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

Using timezone: Central European Time
* arjanb leaves03:14
* djk joins08:48
* djk leaves09:22
* arjanb joins12:49
* bonniot joins13:22
<arjanb>hi
in the logs i see people joining #nice13:26
<bonniot>hello13:43
well, we cannot be there all the time :-)13:44
* GummiEnte joins13:48
Hello all together
<bonniot>hi!13:49
<GummiEnte>HDYD?
<bonniot>fine thanks13:50
and you?
<GummiEnte>well, it could be more comfortable...
<bonniot>what's wrong?13:51
<GummiEnte>my parents are visiting; I'll come back...
<arjanb>i found a hole in typechecking of a do while loop13:55
<bonniot>?13:57
<arjanb>?String s = "xyz";
String t = "abc";
int x = 0;
if ( s != null)
{
do {
t = s;
s = null;
} while(x++ < 10);
println(t);
}
<bonniot>bbs
ok14:00
ok, i see14:01
you should add it as a BUG case
<arjanb>will do14:03
* GummiEnte leaves14:37
* eGummiEnt joins
I'm back...16:22
I've (not really) trouble, but problems with the semantics of the NotNull and InstanceOf "closures"...16:23
I know that the previous implemenation might be wrong in rare cases, but not the constructs don't deliver their full power...16:24
..., but now the constructs...
Let's simple take the following example:
?Socket socket = null;
void connect() {
if (socket != null) {
socket.getPort();
}
}
Today, the nice compiler only recognizes ?Socket as type for socket after the instanceof.16:26
* eGummiEnt leaves16:27
* eGummiEnt joins
<bonniot>is this the whole code?16:28
<eGummiEnt>I know why it does, but to my feeling, this is a natural "error" if the programmer has not synchronized its algorithms...16:29
aeh, yes. for this example.
Now you might speak, that it the compiler should always produce the most possible fail-safe programs, but this is not always comfortable to program.16:30
<bonniot>yes16:31
in this case there is no risk at all, since socket is never assigned16:32
<eGummiEnt>yes, this concrete example...
<bonniot>does it also happen if you declare socket with a let
M
<arjanb>socket is a field in you example?
<bonniot>?
<eGummiEnt>let me try...
<bonniot>no, looks like a local var
the thing is that it's accessed from a closure
<eGummiEnt>Where is the closure?16:33
<bonniot>connect
a local function in this case
<eGummiEnt>Ah, ok, so methods/functions also create closures. I just thought this is only needed for anonymous functions... But Ok16:34
<arjanb>only local function are closures internally
<bonniot>it's needed because you can write
{
void connect () { ... }16:35
return connect;
}
and then connect can be executed from outside the declaring method
<eGummiEnt>??
I don't understand the syntax.
<bonniot>ok, wait16:36
void->void returnAClosure() {
void connect() { println("Connect running..."); }
return connect;
}
void main(...) {
returnAClosure()();
}
see what I mean?16:37
<eGummiEnt>ok, the syntax is clear.
but I don't see the point...16:38
<bonniot>the point is that connect must be compiled as a closure16:40
<eGummiEnt>ah, ok, that was just to explain, why it has to be a closure. I see.16:41
<bonniot>and since closures can be executed at any time, not in the order they appear in the program, it's harder to do nullness analysis with them
<eGummiEnt>same for types I assume (was it called type inference?!)16:42
<bonniot>doesn't mean that no improvements are possible, but it's hard
yes, that's all the same mechanism
dynamic type inference
<eGummiEnt>Ok, I agree. But the current way is a bit of useless for variables in classes... 16:43
Or I would have to create a local pointer and then call instanceof/notNull...
...for each member variable.
...I want to access in such a manner.
<bonniot>you mean field?16:44
<eGummiEnt>Yes, a member variable like socket in the example.
Or do we speak of different things now? :)16:45
<bonniot>socket is a local variable, not a field, right?
<eGummiEnt>Ok, what is a field?
<arjanb>field == member variable
<eGummiEnt>Ok...
<bonniot>a member of an object
<eGummiEnt>Uuups...
class A {16:46
?Socket socket = null;
void connect() {
if (socket != null) {
socket.getPort();
}
}
}
<bonniot>a ok, that's completely different...
<eGummiEnt>That was the example I wanted to point out... :(
<bonniot>then there is no closure
but socket is a field
<eGummiEnt>(I'm a kind of stupid; you extra asked, if this is all code...)16:47
<bonniot>no problem
one way to accept this code is to play on the fact that a thread is allowed to work on a copy of the field16:48
<eGummiEnt>?16:49
<bonniot>so even if socket was modified to null, we still work on the non-null copy
(provided there is no synchronization)
<arjanb>and the field is not volatile
<eGummiEnt>ah, that would be the solution ?
<bonniot>yes, it's a way to accept this code while keeping the guarantee that there is no NullPointerException16:50
<eGummiEnt>"and the field is not volatile" <-- why this?
<bonniot>this behaviour is valid anyway
<arjanb>volatile means that threads may not have a local copy of that field16:52
<eGummiEnt>but to come back to my point: the wrong solution a few weeks ago, was to produce code, that could throw an NPE/CCE. Under normal circumstances a programmer should keep track of that, or not?
ah, that I didn't knwo. Thnx Arjan.16:53
<bonniot>what solution?
the compiler never infered types on fields
the change was only about local variables captured by closures16:54
<eGummiEnt>Wasn't it possible to say something like:
...like the example...
<bonniot>no
<eGummiEnt>Hmmm16:55
it's a pity16:56
<bonniot>the solution is above
it just takes time to implement16:57
<eGummiEnt>If the compiler would not be that complex, I would try it, but it is hard to find an entry.
<bonniot>it should be mostly in bossa/syntax/typecheck.nice16:58
but yes, it might be hard...
<eGummiEnt>;)
<bonniot>(a bit :-)
<eGummiEnt>Typecheck has "only" 1000 loc.17:00
<bonniot>the starting point is typecheck(e@IfExp)17:02
<eGummiEnt>Ok, I can read the code, but...17:08
<arjanb>you get lost following methods used there17:09
<eGummiEnt>:)
Ok, I have to do that in the morning... In the afternoon, I'm not as able to receive energy as in the morning17:20
<bonniot>:-)17:23
<eGummiEnt>Ok, I'll leave for today.17:27
CYA17:28
* eGummiEnt leaves
<bonniot>it seems the JVM does not use SourceDebugExtension yet when printing stack traces18:38
so the line numbers are wrong
<arjanb>which jvm or all?18:40
<bonniot>all i tried
SourceDebugExtension is rather new
jdb supports it when stepping in code
<arjanb>where does the jvm get the line numbers from now?18:42
<bonniot>are you a JDC member?
<arjanb>JDC?
<bonniot>the bytecode attributes
Java Developer Connection
it's a Sun thing
each method has a LineNumberTable attribute18:43
<arjanb>but why are the line number wrong then?
i have registered on the sun site for forums some time ago but i'm not sure that is JDC member too18:46
<bonniot>you can try this url18:47
http://developer.java.sun.com/developer/bugParade/bugs/4972961.html
<arjanb>i see18:48
<bonniot>the line numbers cannot be correct, because the source file name is global for a bytecode class
and we compile several sources into one fun.class
<arjanb>*away for meal*18:49
*back*19:18
<bonniot>can you vote for the RFE?19:27
<arjanb>done19:29
<bonniot>thx19:30
<arjanb>though i don't think they will change it
<bonniot>another useful one is 4726340
why not?
<arjanb>looking at how many things they don't want to change19:31
<bonniot>like what?
<arjanb>equals of Number and many RFE that exist for many and nothing is done with it19:32
<bonniot>they are very careful with things that would modify existing behaviour (like equals)19:38
the source lines extension is something that is not normally present, so it would not hurt previous code
<arjanb>but it could slowdown the stacktrace creation19:39
<bonniot>and by the way, I just asked this on the forums, and it's I think a member of the debuging team would submitted the RFE, so there is hope :-)
only if the info is present
well, you need to test that presence, but I don't think it's very expensive19:40
but true, it's quite likely it will be long...19:42
i'm working on a method that prints the "true" stack trace
to call it from the compiler when there is an unexpected exception
<arjanb>maybe the main method in every nice program could be wrapped in a try catch that converts the stack trace19:44
<bonniot>hum yes, sounds possible19:46
but for instance the compiler API does not let the exception escape, it passes it as a String to the compilation listener19:47
<arjanb>right but correcting a stacktrace could be put it the stdlib19:56
<bonniot>yes
and the wrapper for main would be useful too19:57
would you know of a converter UTF->String?20:48
<arjanb>bytecode UTF?20:49
<bonniot>UTF-8
the encoding of unicode strings20:50
<arjanb>datainputstream has a readUTF method20:53
<bonniot>yes, but it's limited to 64K20:55
<Bluelive>utf8 encodign is pretty simple
<bonniot>it reads the length as a short integer
<Bluelive>the encodign itself isnt aware of unicode :)
<bonniot>yeah, it's a mapping 8bit<->16 (32?)bit20:56
the length of a sourcedebugextension is on 4 words
<arjanb>you could take the one out of the classpath lib20:57
<bonniot>don't they just implement the spec?
or you mean adapt it for longer length?
<Bluelive>32bit
<bonniot>yes, only jvm chars are 16 bit :-/20:58
it's not full unicode
<Bluelive>well 16 bits amkes sense, nothing above is mapped
<arjanb>classpath has a private conversion function
<Bluelive>well you need locale conversion from the enviroment20:59
<arjanb>bottom of the page: http://savannah.gnu.org/cgi-bin/viewcvs/classpath/classpath/java/io/DataInputStream.java?rev=1.23&content-type=text/vnd.viewcvs-markup
<Bluelive>that function should do fine :)21:01
altough stringbuffer might be a bit slow, i would add a native implemetation
<arjanb>there will be an unsynchronized StringBuilder in jdk 1.521:02
<bonniot>hum, maybe I overlooked:21:03
new String(byte[], "UTF-8")
<arjanb>but how do you access the atributes at runtime?21:25
<bonniot>it's a bit hard21:48
i did not find a direct way
i load the class content with ClassLoader.getResourceAsStream("a/b/C.class")
then I parsed the class content to find the attribute21:49
there is an API to access SourceDebugExtension, but it's for debuggers, and it seems the only way is to start another instance of the JVM
<arjanb>:-( lot of work for only to fix the linenumbers21:54
<bonniot>yes, it would be better if that API was available22:11
<arjanb>maybe it will be possible with 1.5
<bonniot>the whole code is ~280 lines
i don't know, because it's not in the jsr22:12
your examples of partial application don't seem OK:22:31
String greet(String salutation, String adjective, String object) = salutation + ", " + adjective + " " + object;
String hello(String adjective, String object) = greet("Hello", ...);
greet("Hello", ...) has type (String,String)->String, agreed?22:32
<arjanb>yes
<bonniot>so that should be:
let (String,String)->String hello = greet("Hello", ...);22:33
<arjanb>right
<bonniot>i like the idea of mixing partial application and named arguments22:34
but i think _ can be useful too22:37
for instance:
let int->int half = _ / 2;
which is the same as:
let int->int half = `/`(_,2);
<arjanb>_ is not too bad22:39
<bonniot>the questions with optional parameters are the same with ... I think22:40
<arjanb>right i responded there too quickly22:41
<bonniot>could you fix your code?22:48
<arjanb>done22:53
<bonniot>hum no, hello should have no arguments: hello() = ...22:56
i think it's more natural to write that code inside a block, not at toplevel22:58
<arjanb>i see now that i meant that as toplevel code
<bonniot>yes, your code is a toplevel, but it was incorrect23:00
not it has dummy parameters
now...23:01
String hello(String adjective, String object) = greet("Hello", ...);23:13
is not correct
<arjanb>well that depends on how you view that proposal23:18
<bonniot>how?23:19
<arjanb>dunno anymore23:23
i changed it now to something that makes more sense
<bonniot>does it start at toplevel?23:29
<arjanb>no23:36
so and can it be both23:40
<bonniot>look good now23:51

Generated by Sualtam