Log of the #nice channel on irc.freenode.net

Using timezone: Greenwich Mean Time
* bonniot joins10:22
* arjanb joins11:21
<bonniot>hello arjan11:35
how are you?
<arjanb>hi
well a bit sleepy11:37
<bonniot>did you work late?
<arjanb>no just got lost in many thoughts11:40
<bonniot>about constructors? ;-)11:41
<arjanb>no about parsing 11:42
<bonniot>what is the idea?11:43
<arjanb>doing a few things differently than than javacc/antlr but i have to try if it makes sense11:47
<bonniot>you want to write a new parser generator?11:58
<arjanb>if the ideas work well then maybe i will11:59
<bonniot>hum, that's a big project...12:00
what would be the main idea?12:06
<arjanb>an additional pass between lexer and parser that creates groups of tokens12:10
and in the parser you can match to a mix of tokens and tokengroups12:11
<bonniot>and what is the motivation?12:20
<arjanb>less lookahead and better error messaging and maybe easier error recovering12:48
*away*12:49
* werwerwer joins13:36
hi
can anyone help me with java
<bonniot>hi
what is your problem?
<werwerwer>right
are you gd with java
its quite long winded to explain
<bonniot>well, first, are you aware this is a chanel for Nice, which is a Java "dialect"?13:37
<werwerwer>no i wasnt
<bonniot>how did you get here? :-)
<werwerwer>searchirc.com
can you point me in the direction of a gd java help channel then13:38
<bonniot>i'm sorry i don't know one
i don't mind if you want to ask here
<werwerwer>ok cool
ill try to explain13:39
<bonniot>in what area is the problem, before entering the details?
<werwerwer>passing an object between classes. and then assigning it to a borderlayout applet
<bonniot>is it a GUI issue?13:40
<werwerwer>yes
<bonniot>hum, then maybe you should find another person to ask, i don't have much GUI experience, sorry
<werwerwer>ok
thanks anyway
bye
<bonniot>no pb
bye
* werwerwer leaves
<arjanb>*back*14:08
i haven't received and new release notification mail yet
<bonniot>i only sent the freshmeat one, you're right14:19
you're not subscribed on fm? :-)
<arjanb>no14:20
<bonniot>sent14:22
<arjanb>i thought that was automatic on sf
<bonniot>no, you can decide when to send the email14:27
which is good, because you might want to do some checking before sending the notification
what is annoying is that there is a lot of manual twiddling to do, like setting the type of each released file14:28
is there something you can commit for constructors?14:40
<arjanb>the parser part but cvs doesn't work at the moment14:49
<bonniot>i can do diffs14:50
cvs is working for me (and i messed up the log message :-(14:52
<arjanb>can reach the cvs server again and committed it14:53
log messages can go wrong easily14:55
<bonniot>well, in this case it was that i selected some files for commit, but then forgot about that, selected another unrelated one and commited all of them with the message for the last one14:58
<arjanb>i'm thinking about implemting the first part of http://nice.sourceforge.net/cgi-bin/twiki/view/Dev/BlockCallSyntax15:09
<bonniot>which one is the first part?15:18
<arjanb>allow foo( ... ) { } as alternativer fo foo (... , () => { })15:20
<bonniot>so without the binding15:24
<arjanb>yes that needs more discussion
<bonniot>i don't like too much the implicit binding15:29
but what about:
using(Stream s = getStream()) { char c = s.read(); }
it would be a general mechanism to declare a local variable inside an expression
similar to:
for (int i = ...; ...)15:30
and assignments return values, like now
<arjanb>i was thinking of: using(s := getStream()) { ... } for the type inferred version15:31
<bonniot>oh, i see you made a similar proposal, only without the type15:32
and allow := everywhere?15:33
<arjanb>maybe
only in expressions is better i think15:35
<bonniot>but an expression can appear everywhere... :-)
<arjanb>yes but that variable would be local to right side of the expression15:36
using(s := getStream()) { } 15:37
dosomething(s);
<bonniot>s not declared15:38
of course
its the same with for(...)
anyway, this is a separate issue
i agree with giving foo(...) { ...} a try
<arjanb>i will try whether the parser agrees too :-)15:40
<bonniot>:-)15:42
<arjanb>would be foo() { } an expression or a statement?15:57
<bonniot>an expression, just lile foo(() => {})15:59
like
<arjanb>the problems is the ; at the end when you use it as statement16:00
<bonniot>yes, there should not be one16:06
that should be possible, by having a production for expressions that don't need ";" to end a statement16:07
<arjanb>yes but that's not a small change16:08
<bonniot>y not? the only such expression is the new one16:10
<arjanb>xxx.yyy().foo() { }16:11
<bonniot>yes?16:12
<arjanb>how do i find out that it's a expression whithout an ;16:13
xxx.yyy() + zzz;16:14
<bonniot>you don't need to know from the start16:15
xxx.yyy() does need a ; by itself
cannot it be:16:19
Statement = ... | Expression ( ";" | Block ) | ...
?
<arjanb>that's an idea16:21
do you have a regression in the testsuite too?17:31
btw just made niceswing compile again17:32
<bonniot>yes, i'm working on the regression17:36
was swing not compiling?
<arjanb>yes17:37
<bonniot>because i made the type of 'object' correct: it does not return a non-null object for every argument!
anyway, good to get rid of it :-)17:38
thanks for the fix
it would have been more helpful to have a comment "removed use of object(...)"
<arjanb>right17:39
have you heard of the groovy language?18:20
<bonniot>yes, a bit18:26
<arjanb>it's interesting how fast that project got started18:28
i'm following it to look for good ideas18:29
<bonniot>when did it start?
<arjanb>september i think and now the first release already18:30
<bonniot>it's a good idea to look around for good ideas :-)
it all depends on the quality of the release :-)18:33
so that's what reminded you of the block syntax! ;-)18:43
<arjanb>i think i have it working now18:44
loop(5) { println("xyz"); }
* Xoltar joins18:46
Hi folks.
<bonniot>hi Bryn!
<arjanb>hi
<bonniot>arjan just got the new block syntax working :-)18:47
<Xoltar>I can't chat for long, busy at work and so on, but I thought I'd drop in and say hello.
Excellent!
I found another good example for block syntax: http://groovy.codehaus.org/markup.html18:48
<bonniot>was there a groovy link somewheere recently? :-)18:49
<arjanb>every where
<Xoltar>A few weeks ago I saw it somewhere, I forget where.18:50
<arjanb>they have a few active bloggers
<bonniot>like?
<arjanb>http://radio.weblogs.com/0112098/18:51
<bonniot>so, we have a different syntax for closures with arguments, but agree on those without arguments :-)
* bkeller joins18:52
Just changing machines...
* Xoltar leaves
<bkeller>So what does our syntax look like with arguments? Like Arjan's examples on the Wiki?18:53
<arjanb>nothing with the arguments yets18:54
<bkeller>Oh, okay.
<arjanb>what about multiple blocks?
<bonniot>we thought about a way to bind local variables inside expressions
so you could do:
using(Stream s = getStream()) { char c = s.readChar(); }18:55
it avoids the problem of implicit binding to an arbitrary name
and it's a general solution, reusing the notion of local variable declaration
<bkeller>Yes, that looks good to me.
<bonniot>similartly to
for (int i = ...; ...)18:56
i prefer general solutions to ad-hoc ones, when possible :-)
<bkeller>Yup. :-)
<arjanb>foo( ... ) { a; } yyy { b; } <-- foo( ... , ()=>{ a; }, yyy: ()=> { b; }18:57
<bonniot>hum, this is getting hairy...
would need a motivating example to see where this is going18:58
one possibility would be to always treat { ... } as a closure with zero arguments (not to be confused with block statements, of course)18:59
<bkeller>Neat! void if(boolean expr, void->void pass, ?(void->void) else = null) { expr ? pass() : (else != null ? else() : null); }19:00
<bonniot>not sure if it is better to make the closure obvious, or to lighten the syntax for small callback arguments
<arjanb>wdym with callback arguments?19:02
<bonniot>pasing a closure as something to be executed when an event happens
("call back")
<arjanb>i see
<bonniot>bryn: true, although we might not want to _implement_ it like that without optimization :-)19:04
<bkeller>;-)
<bonniot>but yes, it's good if we can simplify the language conceptually by providing more powerfull concepts19:05
<bkeller>I think so. If we can say that everything boils down to a few primitive concepts (even if it's not _implemented_ that way), I think it's much nicer.
<arjanb>inlining of calls to higher order function could be possible
<bonniot>it sort of shows the "intuitivity" of the thing, because i did not even think about if, but it indeed supports it like the goold of if from C :-)
yes, the optimization is possible, provided we know the implementation of the method `if` (what about overriding...)19:06
anyway, i would not want us to spend too much time on optimization just yet, because they are a few semantic features to implement first...19:07
<bkeller>Yes indeed. Is it still planned to allow subclasses to inherit from superclasses with fewer type variables?19:08
<bonniot>yes
<bkeller>Cool.19:09
<bonniot>so you were thinking about a macro system?
<bkeller>I've been reading Walid Taha's PhD thesis about multi-stage programming (like in MetaML), and I've been reading about Scheme's hygienic macros. Both seem very interesting.
<bonniot>good that you are gathering information on this. have you looked at template haskell?19:10
<bkeller>Yes, I've even done some small examples. http://www.xoltar.org/2003/aug/13/templateHaskellTupleSample.html is one.19:11
It's interesting stuff, but in some ways MetaML is more ambitious.19:12
<bonniot>the idea is gathered from TH is that a macro system is firstly to provide access to the AST at compile time for manipulation. a syntax to do that from the language is a plus, but it's not the code19:13
...the core
how does MetaML compare to TH?
<bkeller>Right. TH and MetaML are more ambitious than Scheme macros in the sense that they ensure that the generated programs are also type-correct.19:15
<bonniot>yes, that's a must for me :-)19:16
<bkeller>MetaML is more ambitious that TH in that it allows an arbitrary number of 'levels' of computations. Generate programs that generate programs that generate programs that...
All with guaranteed type correctness in the final product.
<bonniot>i see19:17
<bkeller>TH is more about syntactic extension than creating object programs.
<bonniot>that could get fairly dizying, i'm afraid :-)
<bkeller>True, but MetaML's approach is pretty intuitive, it seems. I'll report more as I get a better understanding.
<bonniot>ok, great19:18
<arjanb>Bryn have you found problems with the changed type checking of closure in 0.9.5?19:19
<bkeller>Not that I've noticed so far... but I'm not sure I'm even up to date with what those changes are..?19:20
<arjanb>*phone*
<bonniot>it's about == null and instanceof tests on variables captured by a closure19:21
the compiler used to be unsafe on that, but now it is a bit restrictive
<bkeller>Hmm. Let me check.19:22
My code that I use at work builds fine with the development version.19:24
So I guess I'm happy. :-)
<bonniot>good :-)
<arjanb>*back*19:30
<bkeller>Hmm. I'm looking at the generators code, and it looks like [foo, bar] can't be typed as (()->Object)[] when foo is ()->A and bar is ()->B.19:33
<A,B> ()->(A,B) zip(()->A one, ()->B two) = unsafeZip([one,two]);
<R> ()->R unsafeZip((()->Object)[] generators) =
() => { Object[] res = fill(new Object[generators.size()],
int i => generators[i]());
return res;
};
The error message Arguments (Object[]) do not fit:19:35
<Any R> ()->R unsafeZip(nice.lang.Array<()->Object> generators)
<arjanb>i think it works only for monotypes, daniel?19:36
<bkeller>So I guess it's treating ()->A and ()->B as Object, rather than preserving the common features and treating them both as ()->Object?
<bonniot>it seems to work if you do:
<A,B> ()->(A,B) zip(()->A one, ()->B two)19:37
{
let ()->Object f1 = one;
let ()->Object f2 = two;
return unsafeZip([f1,f2]);
}
i'm not sure why the original does not work19:38
<bkeller>Hmm, okay.
<bonniot>it's not perfect, but it's a workaround...
<bkeller>Sure.
Another odd one:19:40
<bonniot>it has to be ()->?Object, since A might be an option type
<bkeller>Ah, okay.19:41
<R> ()->R unsafeZip((()->Object)[] generators) =
<bonniot>unless you want <!A,!B> ...
<bkeller> () => { Object[] res = fill(new Object[generators.size()],
return res;
};
It can't figure out what type to use for fill:
Ambiguity for symbol fill. Possibilities are :19:42
<Any T> nice.lang.void fill(nice.lang.List<T>, T)
<Any T, Any U | U <: T> U[] fill(nice.lang.Array<T> array, (int)->U value)
<bonniot>why did this never happen before?19:44
<bkeller>I wasn't using 'fill' before. :-)
<bonniot>wait no, the first method should not be applicable
oh yes, because everything is an Object now!19:45
<bkeller>Ah, right!
<bonniot>weird
<bkeller>*away*
<bonniot>that's where it would be handy to write nice.lang.fill(...)
you could do:19:47
<R> ()->R unsafeZip((()->Object)[] generators) 19:52
{
let (?Object[], int->Object)->Object[] f = fill;
return () => { Object[] res = f(new Object[generators.size()],
int i => generators[i]());
return cast(res);
};
}
this solves the ambiguity
arjan, the compiler wrongly reports that f is unsued (probably because the use is in a closure). could you look at that?19:53
<arjanb>yes19:54
<bonniot>thx
<bkeller>*back*
Okay, that'll work I guess. I was going to mention bogus unused variable reports next, but you found that one already!19:55
<bonniot>i've made a testcase for the object function array thing, I will investigate that sometime20:00
<arjanb>that bogus unused variable warning means that the check for being initialized is not done correctly either20:01
()->void f;20:02
f();
this compiles at the moment
D:\Nice>java -jar test.jar
Exception in thread "main" java.lang.VerifyError: (class: testbug/fun, method: main signature: ([Lja
va/lang/String;)V) Accessing value from uninitialized register 2
<bonniot>i can't believe this is not checked!20:04
surprising20:05
so it's that a variable sue in call position is not marked, I suppose?20:06
<arjanb>yes
<bkeller>Cool, generator library compiles and passes tests again.20:09
<bonniot>what changes did you make?20:10
<arjanb>it might be that initialized check is missing in other cases to
<bonniot>i'll be away for some time...20:11
<bkeller>All the zip/zipWith/unzip variants use dynamically typed implementations that work with arbitrary sized tuples. So adding a new version of, say, zip, is as simple as:
<A,B> ()->(A,B) zip(()->A one, ()->B two) = unsafeZip(cast([one,two]));
It's even nicer for the unzip family, which required about 30 lines for each implementation, plus another 10 lines for each additional type variable.20:13
Now it's just:
<A,B> (()->A, ()->B) unzip(()->(A,B) gen) = unsafeUnzip(gen);
<arjanb>:-)
<bkeller>I'm off to lunch, see you folks in a bit.20:17
<arjanb>daniel i'm working on checking of local variables in call positions21:36
* bkeller leaves21:53
<arjanb>that was an easy one to fix :-)21:54
<bonniot>good22:57
* xoltar joins23:06
<arjanb>wb
<bonniot>arjan, shouldn't the code be the same in both cases, and shared?
<xoltar>Hi again.
<bonniot>hey23:07
<arjanb>the code doesn't have to be the same so i didn't share23:10
<bonniot>what do you mean?23:11
<arjanb>assigned is always false in that case
<bonniot>ok, but that does not matter23:12
and there is no guarantee it will always be the case
i think sharing would be much clearer23:17
<arjanb>ok, changed23:18
<bonniot>thx23:22
i just looked at the literal array with Object functions23:25
basically, it's generating the constraint
()->a <: T, ()->b <: T
where a and b are unrelated types23:26
there is no solution, which is expected
if you think about:23:27
<T> boolean `==`(T,T);
where you don't want a == b to be valid when they have incomparable types23:28
that generates a <: T, b <: T, and you don't want Object to be a solution for T23:29
so i'm not sure if and how it would be possible to allow one and not the other
<arjanb>isn't possible when the constraint of an array literal is insolvable then give it type Object[] ?23:30
<bonniot>that's already done23:33
what bryn wanted was (()->Object)[]
which would indeed be afe, since the elements are all functions23:34
<arjanb>i think in this case it's better to use workarounds than to add more hacks to the type system23:37
<bonniot>yes. there are no hack in the type system, btw :-)23:40
<arjanb>the implementation is so complex that i don't see the difference between one big hack and proven correct implementation :-)23:41
<bonniot>;-)23:42
the difference is, there is some theory to back that implementation up23:43
<xoltar>Daniel: As I recall your proofs of the type system were modular in the sense that they didn't care much about the underlying objects, so long as a subtyping order was provided. Am I remembering right? Are the proofs modular in any other ways?00:34
<bonniot>yes, the core system is proved independently of the object system , which is simply a set of primitive operators00:47
another modularity is in the form of constraints, which can be extended by proving a few properties00:48
abstract interfaces are added in that way, for instance
<xoltar>Ah, cool.00:52
Arjan: I almost forgot, Daniel said you have a batch file that will build nicec from CVS on windows? Can I have a copy please?00:53
<arjanb>i can give you that00:54
but it doesn't use relative directories and assumes a few things set in the path/classpath00:55
<xoltar>Okay, whatever you've got is fine, I can adjust it to suit. :-)01:03
<bonniot>maybe it's an occasion to make it more portable01:07
<arjanb>send by mail01:10
the mailscanner ate the attachments :-/01:12
resend01:14
and you need to download javacc manually01:22
<xoltar>Got it, thanks.01:25
<arjanb>good night01:47
<xoltar>Night!
* arjanb leaves01:49
<xoltar>Time for me to go home. Good night!01:50
* xoltar leaves
* bonniot leaves01:55