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

Using timezone: Greenwich Mean Time
* arjanb leaves00:25
* GummiEnte joins05:02
Good morning...
* GummiEnte leaves08:17
* bonniot joins10:31
* GummiEnte joins10:35
I've jsut released a new Sualtam version...
Please have a look at http://confer09.condor-edv.com/nice@freenode/
<bonniot>nice :-)10:49
some ideas:
it could be good to reverse the order, so that the most recent is at the top (or have an option to do both)
constraints seem to work, altough it gives a few more false negatives then i would like
<bonniot>it would look better if the text for each day was centered (especially for -, and maybe it would make it good to write 1 instead of 01)10:51
<Bluelive>im really impressed by your implementation :)
how did you get all of the idea's ?10:52
<bonniot>can it be made to use other languages than german? :-)
what ideas?10:53
<Bluelive>for the parametric constraints for methods
btw, we speak dutch, not german ;)
<bonniot>arjan and you, yes, but christian is german, aren't you?10:54
<GummiEnte>Yes, I'm...10:55
Which idea's?
Tha language is at the moment determined by the user who actually generates the idnex...10:56
<bonniot>that was to Bluelive
<GummiEnte>...by the users current locale...
<Bluelive>well did you think the constraints up by yourself or did you find a paper about it ?
<bonniot>ok, so the script that starts sualtam could set an english locale
<bonniot>there has been research about constraints for some time, yes10:57
i did not invent everything :-)
<Bluelive>what is unique in nice ?
<GummiEnte>abstract interfaces...?
? types10:58
dynamic type inference
<Bluelive>the var thingy, im really impressed with the compiler logic needed for that one :)10:59
<bonniot>var x = ...; ?
<Bluelive>i guess you collapse the typeing backwards and redefine per branch in which knowledge is gained or lost ?11:00
<bonniot>for dynamic type inference, yes, something like that11:01
but information only flows inwards
the thing is that we also take into account dead branches11:02
if (x == null) return;
then we know that x is not null in the rest of the method
<Bluelive>doesnt that get pretty ugly when combining expressions in an branch ?11:22
and branches that might be dead ?
<bonniot>the implementation?11:24
each variable can be treated separately
<Bluelive>yes ?
<bonniot>what do you mean by combining expressions?11:25
<Bluelive>if (((b instanceof A)&&(b instanceof C))||(c instanceof D))11:26
b instanceof D
<bonniot>since there is a ||, you don't know which branch was true, so you know nothing more about b and c11:30
* arjanb joins
<GummiEnte>hello arjan
for serialVersionUID you should use final long serialVersionUID = ...11:44
at the moment the number for serialVerionUID needs to be positive because of a bug11:45
<bonniot>yes. i'm fixing the number parser so you can use the hex representation of negative numbers11:47
<arjanb>GummiEnte: that with instanceof is a bug11:57
you can work around that using an enhanced for loop instead of an foreach11:58
<arjanb>i have chosen an to simple algorithm for typechecking closures :(12:03
<bonniot>what is wrong?12:04
<arjanb>captured variables should be marked captured and set back to their original type when exiting the closure where they captured12:05
i'm working on that12:06
<bonniot>in christian's case, eveything happens in the closure, no?12:07
so setting back the type should not be the problem
<arjanb>in that case is only marking it as captured too early the problem12:08
<bonniot>arg should not be marked as captured at all, because it is modified in the same closure it is defined12:10
<arjanb>true but bookkeping that is at least so complex and doesn't solve all cases12:20
christian's case seems to work now12:27
<bonniot>what is your change?12:29
<arjanb>i store the the captured variable and do the thing previously in setCaptured at exiting the closure12:30
<bonniot>that's not correct12:45
because when a variable is captured, we should consider it can be modified at any time
even without your change, the current implementation is not strict enough12:46
?int x = 1;
let f = void->void g => {
if (x != null) {
int y = x;
f(() => { x = null; });
x is captured in the second closure, but it should be considered captured in the first too12:47
so capture should be computed before typechecking
in the testcase of christian, i believe it is the fact the the variable is local to the closure that makes the code valid12:48
what cases did you find where this approach is not sufficient?
<arjanb> A a = new B();12:49
void->void f = () => {
if (a instanceof B) {
a = new B();
int x = a.life;
<bonniot>but that involves taking into account the type in assignments, which we don't do yet12:51
<bonniot>currently, since a is assigned a new value, we don't know anymore if it is instanceof B12:52
<arjanb>that value does fit in the conditional type of a so the type stays B12:53
<bonniot>is this implemented?
oh yes12:54
<Bluelive>what does nice do in a <any T> T foo(T a, List<T> b) case when its get called with a C extends B extends A foo(B, List<C>), what type will the return T be ? or is it simply illegal ?
<bonniot>arjanb: ok, so this code could be accepted12:55
the problem is that there could be another closure that does:
if (a instanceof C) { f(); ... }12:56
and a would not have type C after calling f
so it seems quite difficult to implement this
<arjanb>the only thing that my implementation doesn't handle correct is higher order closures and recursive local functions
<bonniot>it could also be other code that modifies the variable in paralell (in another thread)12:57
<arjanb>how do can they access that local variable?12:58
<bonniot>it's not local to the closure13:00
so the thread can be created in the same block that defines the variable and the closure
<arjanb>Bluelive: that call is illegal13:04
<bonniot>which one?13:05
<arjanb>daniel: do you agree that i commit my changes now and try to find out some more correct way to do it later?13:06
<bonniot>i'm not sure, because i don't think it's moving in the right direction13:08
<arjanb>i'm doubting if it's possible to do this correct in a non restrictive way without needing escape analysis of closures13:09
<bonniot>there is a simple and effective thing to do, which is not to mark a variable as captured when it is modified from the same block it is defined13:11
I'm not saying this solves every case, but it is step in the right direction13:12
<arjanb> A a = new A();13:18
void->void f = () => {
a = new B();
if (a instanceof B) {
int x = a.life;
Bluelive: sorry, i was in the other discussion13:21
yes, that call is illegal
on the other hand, foo(C, List<B>) is legal, and will return a B13:22
(because the valud of type C can also be considered as having type B)
<arjanb>this one won't work if the only change is marked captured only if it is not declared local to closure
<bonniot>yes, i know
as I said, this is not the only change that can be made13:23
it's not a reason not to make it13:24
<GummiEnte>Ok, the index is now align in the table fields and descending month order... I'll have to fix some other bugs with the locales, but for now I leave it in german locale... :/13:29
<bonniot>cool :-)13:33
<arjanb>daniel: i have send the patch by mail13:40
now time for breakfast, shower and coffee13:41
i think implementing Serialiable should be required before adding read/writeObject as private methods to the class14:51
<bonniot>why not, but it does not seem urgent to do that14:55
it does not hurt to add them in any case
did you write a testcase for the method call error reporting bug you solved?14:56
<arjanb>committed now15:07
<bonniot>ok, thanks15:08
<arjanb>but i saw that namedparams aren't tested in the testsuite
<bonniot>i think there are two things that should be done now:
i think they are in regtest15:09
one thing is to refine the capture15:10
the other is to allow -123 to be treated as a constant, and not as -(123)
i could work on the capture if you want15:11
<arjanb>i can try the negative numbers15:12
<bonniot>ok, good
i'll be away for ~20m15:13
would nice be able to see that D is atleast a sub type of A and allow the call to X ?
<arjanb>interface A {}16:05
interface B {}
class C implements A,B {}
class Z {
<T | T <: A, T <: B> void foo(T d)
void bar(A d) {}
this compiles in Nice
but if i remove class C than the constraint is not satisfiable16:06
daniel what is the reason of that?16:07
didnt yet get that to work in alpha
<arjanb>the constraint not satisfiable error are ugly now:16:15
The type of method foo is not well formed: <T | T <: testbug.A, T <: testbug.B> (testbug.Z, T)->nice
mlsub.typing.TypingEx: Unsatisfiable 1:[NO MESSAGE]
<bonniot>arjanb: because then there is no class that implements both A and B16:20
is the last part printed in normal mode?16:21
<Bluelive>but thats not true in a dynamic loaded enviroment like java per se ?16:23
a c could be constructed later
that comes with the way constraints are solved at the moment16:25
i'm not sure if it would be easy to allow this kind of situation
at least, it works well when C exists :-)
<Bluelive>well depends upon if constraints still exsist on runtime16:26
<bonniot>no, typing is completely done at compile time16:29
<GummiEnte>I've also encounterd something like follows:17:00
abstract class A {}
class B extends A {}
let Vector<A> ll = new Vector();
A getA() = new B();
A anotherFunction() {17:01
?A rr = null;
ll.foreach(A arg => {
rr = new B();
if (rr == null) {
return getA();
} else return rr;
line 31, column 9:
rr might be null
that is the line "}else return rr;"
* GummiEnte leaves
* GummiEnte joins17:02
Is this related to the other things?
Or is this a new light?
<arjanb>this the typing change of closures17:03
it is
<arjanb>the easiest thing is to replaced such foreach loop with the enhanced for loop17:04
<GummiEnte>I just thought I could live without the "correct" typing, but that is too much to change. Do you think the temporary patch you send daniel does correct this?
So for (arg: list) {...}?!
<GummiEnte>yes for the patch or the syntax?
<arjanb>yes for the syntax17:05
<GummiEnte>Ok, tnx.
<arjanb>my patch won't typecheck your latest example either
<bonniot>i think it would be easier for you just to disable this feature for now
it's a one line change in the compiler
just comment out setCaptured(variable);17:06
<GummiEnte> a one line change??? so you know what's wrong?
<bonniot>we are working on it
but this will just disable a safety feature, it is not a long term solution
but it's surely better to do that than to change your source code17:07
<GummiEnte>So, I should apply the patch you send me with the setCaptured commented out?
<bonniot>no need for the patch
just comment out line 45 in src/bossa/syntax/typecheck.nice17:08
<GummiEnte>No need... So which file, line?
Ok, thnx.
<arjanb>only comment line 44 and 45
<GummiEnte>hopefully anon-cvs is now on the latest stand...17:10
quite a few warnings about "Ignored retyping because no method named ..."17:12
<arjanb>do you use 1.3?17:13
Ok, in cvs the latest serilizable changes are not included :(17:14
<arjanb>then the warnings are ok
<bonniot>they are commited17:23
<GummiEnte>yes, but not traversed to anon...
<bonniot>how much is the delay now?17:24
<GummiEnte>Not sure... Depends on how often teh sync... I assume it is less than 1 day.
<bonniot>the commit was ~ 3.5 hours ago17:25
<GummiEnte>don't know excatly the time they start the sync...
<arjanb>they sync about once a day
<GummiEnte>So, then I have to wait again... :(17:26
<bonniot>we can always work around it
<arjanb>i committed the change to negative int constants
<bonniot>you can see the diffs on nice-commit
<arjanb>daniel can't you build one from cvs and disable closure typing?17:27
*away for dinner*
<GummiEnte>have a nice lunch...17:28
<bonniot>the sync is every 5 hours now
since 11/11, according to SF17:29
<GummiEnte>Daniel, I would be very very pleased if you could have a look at https://sourceforge.net/docman/display_doc.php?docid=772&group_id=1#scriptcvsacls17:30
maybe this is an option?
<bonniot>you'd like to be added to the developer list?17:33
<GummiEnte>Yes, if you and the others don't midn...
<bonniot>no problem. it's done17:36
did'nt you told me, there is already an developer that has started nicedoc?17:38
<bonniot>yes, why?17:44
<GummiEnte>Cause I just saw, that you'r still searching for more volunteers...17:45
<bonniot>that's how that person volunteered17:47
the offer is supposed to disappear after 15 days, but it seems it does not
<GummiEnte>Who's the one?
<bonniot>no big problem, if somebody else is interested, we can find something else to do :-)
<bonniot>he's called Frank17:48
<GummiEnte>also german?
<bonniot>no, australian I think17:49
<GummiEnte>well, I assume that, cause it sounds for so, cause I now quite a lot of Frank's... Even my brothers name is Fran.
Ok, that he is australian doesn't make the 1.0 meeting easier :)
I've had a short look on the irc logs... quite a few people now are using nice... its now really growing17:50
<GummiEnte>I hope, that the 1.0 release is not as far away as the 1.0 kernel release was in the past...
<bonniot>we will need to have a plane company as a sponsor17:52
the Linux kernel?
<GummiEnte>yes, that I meant...
<bonniot>how long was the 0.9 series?
<GummiEnte>Oh, I don't know exactly, but I think it ended with something like 0.9.98... (not that exaactly, but this is the direction)
you've just released 0.9.5... so, if only 1 digit would be allowed, that would be 5 releases...17:54
<bonniot>with all the intermediate versions between 0.9.0 .. 0.9.98?
<GummiEnte>Really a lot of them...17:55
<bonniot>it could be 2 digits
<GummiEnte>Yes, I know :)
<bonniot>if we make releases more often, it will not post-pone 1.0
<arjanb>btw they i haven't heard anything of Frank anymore
<bonniot>anyway, is 1.0 important for you?
<GummiEnte>No, that's just a release...17:56
<bonniot>he's writing emails once in a while. he hopes to have a prototype soon, so we can give comments
<GummiEnte>I'm already stuck to the cvs version...
<GummiEnte>Good to hear that...
<bonniot>there are interesting choices to make, because Nice is not as class based as Java, so there are options about how to organize the info about methods17:59
Well, with the commented out line, there are still cases, that don't work... Should I give a example?18:02
<GummiEnte>?CFUNCTION function = rr.stub.sflist.get(identifier);18:03
if (function != null && function.items.getSize == 3) {
if (function.execution_layer != null) {
[nicec] No possible call for execution_layer.
[nicec] Arguments: (?com.condor_edv.e3m.celleval.CFUNCTION)
[nicec] Possibilities:
[nicec] ?com.condor_edv.e3m.celleval.VariableLayer com.condor_edv.e3m.celleval.CFUNCTION.execution_layer
[nicec] com.condor_edv.e3m.celleval.VariableLayer com.condor_edv.e3m.celleval.Expression.execution_layer
<arjanb>conditional types are still reset when entering a closure18:04
<bonniot>where is the closure?18:05
<GummiEnte>Ahh... Sorry.
Ok,once again:
?CFUNCTION function = rr.stub.sflist.get(identifier);18:0318:06
if (function != null && function.items.getSize == 3) {
ei.items.foreach((EItem i) => {
...if (i instanceof CDECL) {
if (function.execution_layer != null) {
VariableLayer execution_layer = cast(function.execution_layer);18:07
that's it.
<arjanb>the compiler is correct here in principle18:08
<bonniot>yes, this would need the information that foreach does not let the anonfun escape18:09
<arjanb>do you have many of these cases?18:10
<GummiEnte>actually the compiler only throws me two errors ... :)
...for that package...18:11
<arjanb>then replacing with enhanced for loop is an option
<GummiEnte>I'll give it a try.18:13
<arjanb>btw the overhead is much smaller when using the enhanced for loop instead of foreach18:14
<GummiEnte>of what type must be the list?18:15
<bonniot>a collection or an array i think18:16
but you can add others
<bonniot>arjan, did you mesure the performance difference?18:17
Where is it defined?
<arjanb>in nice.lang.ForInIters
<bonniot>arjanb: in your patch of Parser.jj, why do you treat + separately from ! and ~ ?18:20
ah, because +1 is really 1 ?18:21
<arjanb>because something you want to put a + before a constant for clarification18:22
<bonniot>i know, but that was already supported
<arjanb>yes but then it wasn't treated as an constant18:23
here is my current implementation for capture:
<arjanb>GummiEnte: for what kind of lists do you find enhanced for loop not working?18:25
<bonniot>it is done during analyse, so that a closure that appears later will also count
<GummiEnte>For my own implementation...
<bonniot>this means it is safe in presence of threads, higher order functions, ...
on the other hand, it does not mark as captured variables local to the inner anonfun, so there will be no false marks18:26
i think the setCaptured method can simply be removed, because now the capture is always made before enter/exitClosure is called
on the other hand, we keep enter/exitClosure18:27
does that sound OK to you?
will it work for the testcases that i had in my patch?18:28
<bonniot>i'll look at that
it works for the one where the variable is local18:32
but the ones where it is exterior, which is not surprising
(but not for ...)18:33
<GummiEnte>Ok, now I'm using:18:38
for(EItem i : ei.items) {
if (i instanceof CEXPREND) {
i = i.items.getElementOf(0);
and get:
i cannot be assigned a value18:39
<arjanb>that's correct18:40
you make me cracy :-)))
<arjanb>the law of conservation of errors at work here :-)18:43
<GummiEnte>So, I first need to copy the varible to a local defined variable...
<bonniot>iteration variables are final? why?18:44
<arjanb>it can avoid mistakes18:45
<GummiEnte>well, there are quite much foreach loops... now I would need to adjust most of them :-/18:46
<arjanb>i think that change will be permanent to nicec18:49
so we should have fixed this earlier :-/18:50
<GummiEnte>so it won't work again what has been working before?
<arjanb>maybe in long time if Nice get some alias preventing modifier18:52
<GummiEnte>What is now the blocker for that?
<arjanb>i would be quite a lot of work and maybe some changes to typing system18:54
<GummiEnte>cause of what?18:55
<arjanb>and i haven't seen any language with such a thing
<bonniot>i think we could make iteration variables non-final, if that's disturbing19:08
christian, what do you think?
arjan, what change are you speaking about: iteration variables, or closures?19:09
<GummiEnte>yes, that would be good, but the other thing would be even better... I have read again over the logs and have an idea what closures break in the old compiler version...
Is the closure calulation completly computable at compile time?19:10
<bonniot>what closure computation?
<GummiEnte>well, to my mind closure calculation is something that calulates what type a variable has at what stage... Am I wrong?19:11
if so, I did'nt get the term "closure" right19:12
<bonniot>closure is a name for an anonymous function that uses a variable defined outside itself
<GummiEnte>ah, ok.19:13
<bonniot>the computations on the type of local variables is what we call dynamic type inference
<GummiEnte>but is this computable correct at compile time?
<bonniot>it can be correct19:14
it will never be perfect, because you don't know everything at compile time
it is the same with traditional type-checking: the type of an expression is only an approximation of its type at runtime
<GummiEnte>Ok, so mutlithreading should be a problem, should't it?
<bonniot>yes, we have to take into account multi-threading
<arjanb>it will always be either unsafe or too restrictive in certains cases
<bonniot>you can think of this as a problem, but you can also think of it as a way to catch errors at compile time
<bonniot>the question is to make it non-restrictive in the large majority of cases, while being safe
<GummiEnte>so, there will be quite a few new "problem" with dynamic class loading...19:17
...still waiting for your comments about my assumptions... :)19:18
<bonniot>i'm not sure that there are more problems with dynamic class loading, given the way we treat the problem at the moment19:21
i just commited changes. they now handle correctly local variables of anonymous functions19:22
can you tell me how many cases break in your code with this version, and the typical examples?
to disable the feature, you now need to comment lines 439 and 440 in bossa/syntax/analyse.nice19:23
Gummi_log: when disabling the feature, there are only 2 problems, right?19:24
i don't think you should change your code using foreach, we can agree not to make this feature active until it handles most cases correctly19:25
<GummiEnte>Would'nt some of the options be compile time options??? 19:32
ok, first example that break with unmodified cvs version (so no change of code):19:35
?A a;
list.forbreak((B) => {19:36
a = ...;
if (rr==null) {
...} else {
That would fail...
...cause a might be null (a is rr!)19:38
<arjanb>that's because the compiler can't find out whether the closure can escape in forbreak19:40
<GummiEnte>I've also got something else.19:42
A a;
a = ...;
if (a instance of B) { // B subclass of A with a field o19:43
...while_loop {
if (local_var instanceof ...) {19:44
...a.o ...
No possible call for o
nice.lang.int package.B
nice.lang.int package.C //anohter subclass of A19:45
That's a bit strange for me.
<arjanb>where is the closure?
<GummiEnte>after(!) the while loop.19:47
but in the while loop a is not touched.19:48
well, not quite right, it is used as arguemtn for a function
then I've got same as forbreak with foreahc,.
EvalResult name = freeEnvelopes(getEvalResult(e.items.getElementOf(0), el));19:50
if (name instanceof StringResult) {
name.var // field of class StringResult...19:51
throws error:
No possible call for var...
So, there are some informations missing. 19:52
<arjanb>is something assigned to name in a closure?
<GummiEnte>no. only used as arguemtn.19:53
so, it may be defined as final var.
<arjanb>what do you get if you change it to: let EvalResult name = ...19:54
<GummiEnte>still the same.19:55
<GummiEnte>Well, I'm sorry, but I have to leave in a few minutes...20:00
<arjanb>daniel: where is the check that only assigned vars will be marked as captured?20:02
<GummiEnte>Ok, I'll leave you now alone... We'll see us tomorrow... Have a good night...20:03
<arjanb>good night
* GummiEnte leaves
<arjanb> let A a = new B(); 20:31
void->void f = () => {
if (a instanceof B) {
int x = a.x;
this fails
<bonniot>you can call me daniel :-)20:38
sorry, i was away
yes, i forgot to capture only during assignment20:40
it's easy to change I will do it
it seems there was no testcase that exhibited this aspect20:41
i will add yours
the test fails because a.x is not declared20:44
but yes, with a.life it should pass
A a = new A(); 20:46
void->void f = () => {
a = new B();
if (a instanceof B) {
int x = a.life;
<bonniot>yes. testint the change at the moment20:47
<arjanb>i understand why this testcase fails
but isn't the unsafety of this one caused only by the way closure are implemented now?20:48
<bonniot>what do you mean? what different implementation would make a difference?20:50
<arjanb>if captured variable are copied in to local of the stack and only back at the end of the closure then there is no problem with unsafety
local of the closure
<bonniot>that's not only an implementation change, it's a semantic change20:51
<arjanb>i know
<bonniot>i'm not saying it's impossible to specify the semantics like this, but it needs some reflexion20:52
<arjanb>but both semantics look just as good to me
<bonniot>i'm not sure that would make it safe though20:54
your example above is safe in itself, but you can consider adding20:55
void->void g = () => {
a = new C();
if (a instanceof C) {20:56
C c = a;
at least, that one would be currently unsafe, because after a instanceof C that succeeds, another thread can execute a = new B() (from f) and a does not hold a C anymore20:57
but yes, if g is working on its own copy of the reference in a, then it does not matter20:58
so you are right, there would be more flexibility with this semantics
the question is whether this semantic would not be problematic20:59
for instance, you could want a thread that periodically modify a variable, like:
int x = 0;
thread(() => {21:00
<arjanb>i don't know Nice is the first language with closures i really used
<bonniot> while (true) {
<arjanb>you could use threadlocal variables for that21:01
<bonniot>with your semantic, x would never really be modified
<arjanb>hmmz i don't know21:04
maybe i'm wrong21:06
but i find the combination of closures and threads confusing21:07
are you going to build a version without closure typing changes?21:09
<bonniot>you mean the dev version?21:13
<arjanb>yes for christian21:14
<bonniot>he's not using the dev version anyway, because he wants to compile with JDK 1.321:18
but he knows how to disable it
the new CVS versions solves one more case21:20
do you understand the forbreak case? is rr a typo for a?
how do you want to handle read/writeResolve methods for serializable objects?21:50
it needs to be compiled into the class but the modifier doesn't matter
<bonniot>it does matter22:01
there should be the choice, because it will modify the semantics
so in the long term, it should probably have the same visibility as the nice method (private, package or public)22:02
do you want to implement that?22:03
it should simply be extending the test on the method name
and also handle the different arity
* bonniot leaves22:11
* bonniot joins
<arjanb>i can implement that but special casing many methods is not pretty22:14
<bonniot>no, but it's the way to handle serialization at the moment22:22
it's a consequence of not having an interface that declares those methods22:23
in the long term, we can implement dispatch as member methods, so this would work automatically
i'm changing the automatic upgrade of dev versions, so that all failures postpone it, not just the bootstrap and testsuite22:25
that will make the dev version more trustable22:26
<arjanb>where is the read/writeObject set private?22:52
<bonniot>it's the true parameter to addMethod22:54
with named parameters, it would be more clear :-)
how long before rewrite in Nice? :-)23:01
<bonniot>ich wei? es nicht...23:16
<arjanb>readResolve and writeReplace work now23:48
so the urgent problems are solved23:59
<bonniot>for serialization, yes00:19
i will be interesting to have stats from christian about captures
i think i will sleep on this now :-)
btw, the implementation for readSolve and the testcase look fine :-)00:20
good night
<arjanb>good night
* bonniot leaves
* arjanb leaves00:59