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

Using timezone: Central European Time
* lodewijk joins00:10
* bonniot joins00:27
<bonniot>how are you doing?
<Bluelive>actually im aorking at alpha again...
and watching some series
<bonniot>motivated again?
<Bluelive>andromeda, startrek ripoff, but with the gut from hercules for the main role00:32
motivated ? i lowered my standards and expectations, that helped
<lodewijk>ah, bonniot: I've got a nice problem again :)00:46
<bonniot>(call me daniel :-)
<lodewijk>oh damn, this is an xterm and I can't paste from a Terminal.app window. I'll be right back :)
* lodewijk leaves
* lodewijk joins00:48
okay, so this is my test case:
import javax.swing.*;
void main(String[] args) {
int i = javax.swing.JFrame.EXIT_ON_CLOSE;
which gives:
Ambiguity for symbol EXIT_ON_CLOSE. Possibilities are :
nice.lang.int EXIT_ON_CLOSE() = native javax.swing.JFrame.EXIT_ON_CLOSE;
nice.lang.int EXIT_ON_CLOSE() = native javax.swing.WindowConstants.EXIT_ON_CLOSE;
oh, wait a minute. is it saying EXIT_ON_CLOSE has been retyped to a function?00:49
<bonniot>does JFrame implement WindowConstants ?
not necessarily
<lodewijk>yes, JFrame implements WindowConstants00:50
<bonniot>the compiler is not seeing those two declarations are actually the same00:51
<lodewijk>pff, WindowConstants has static int's in it. I didn't even know that was possible.
<bonniot>its a bug in Nice
but you should get by using: javax.swing.WindowConstants.EXIT_ON_CLOSE
<lodewijk>I had another, probably the same bug. let me see if I can get it back.00:52
<bonniot>additionally, I would think it possible not to need that static field, as the wrapper library should offer a higher-level interface to that functionality00:53
<lodewijk>no, this one's even better :)
~/nice/./gui/CubeViewImpl.nice: line 14, column 30:
Ambiguity for symbol remove. Possibilities are :
nice.lang.void remove(java.awt.Container, Component)
nice.lang.void remove(java.awt.Container, Component)
<bonniot>but maybe it's not done yet
<lodewijk>kindof hard to force it one way or there other in that example :)
you did not do any retyping yourself I suppose?00:54
<lodewijk>no, not on that level.
<bonniot>do you have a testcase?
<lodewijk>is there a flag I can switch on that has the compiler giving off gobs of debug info?00:55
<bonniot>yes, but not a single one
there are several properties that can be set, in a file ~/.nice.conf00:56
it's not documented, though :-)
<lodewijk>hmm, strange, my first attempt to reproduce in a smaller example fails. 00:58
<bonniot>like the bug disappears?00:59
<lodewijk>the call is in an anonymous function, I'll check if moving it out of it fixes it.
nope it doesn't fix it.
yes, my attempt at reproducing didn't reproduce. the larger piece of code still does.01:00
<bonniot>so it's in between
that's the typical process
<lodewijk>yes, so binary search it is :)
ouch, forgot to classpath the sleepycat library and got:01:02
An exception has occured in the compiler
Please fill-in a bug report at the following webpage:
<bonniot>with a ClassNotFound error?01:03
<lodewijk>java.lang.RuntimeException: no such class: com.sleepycat.bdb.bind.DataBinding
got a full trace here, but I'll be autokicked if I paste it :)01:04
<bonniot>not surprising, but the error message should be improved, that's true
<lodewijk>Container.remove(component) is retyped twice in swing/src/nice/ui/common/types/awt/java.nice01:08
that's it I think
<bonniot>the same exact method?
<bonniot>then that must be it
<lodewijk>line 751 and 771
<bonniot>easier to fix than a compiler bug :-)
<lodewijk>yes, after a recompile of nice-swing it doesn't complain anymore.01:13
could you commit the change?
what do you think about EXIT_ON_CLOSE?01:16
<lodewijk>well, it works when forcing it to the interface instead of the class
<bonniot>isnt there, or shouldn't there be, a higher level interface?
<lodewijk>oh, like that.
<bonniot>(yes, we'll fix this point)
<lodewijk>well, there is, you can override windowClosing(WindowEvent) and do whatever you want there. EXIT_ON_CLOSE is just a quickie way to bail out.01:17
<bonniot>are there cases where it's more convenient?
<lodewijk>I'll replace it eventually with an are-you-sure dialog, but for now EXIT_ON_CLOSE prevents processes from cluttering up my dock.01:18
<bonniot>i see, it's a flag?
<lodewijk>it's convenient to put in place when you have more important stuff to do than are-you-sure dialogs, but it is a stopgap.01:19
yes, you say setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
<bonniot>i'm not arguing about the feature itself, more about the syntax
<lodewijk>oh, okay. it's an integer.
or rather, an enum written down Java-like.01:20
<bonniot>and there are other values for this call?
<bonniot>we have enums in Nice01:21
so maybe nice-swing could declare such an enum and a method to replace the Java one01:22
<lodewijk>yes, that would be better.
<bonniot>i wonder if we should add the feature to hide an existing method
in that case it would make sense, since one would want only the new method to be used01:23
<lodewijk>yes, or maybe not hide but mark deprecated. if I have the JDK docs in front of me and the compiler claims a method isn't there which should be there, that'd be confusing01:24
there could even be a custom message printed when the old method is used01:25
like: using this other method instead, it's type safe :-)
<lodewijk>right, that'd be very nice.01:26
<bonniot>are you planing to use Swing a lot?
<lodewijk>I already am.
<bonniot>and are you makign use of the nice-swing extension?01:27
<lodewijk>as much as possible, yes.
<bonniot>what do you think about it?
<lodewijk>I like the anonymous methods as callbacks much better than the anonymous inner classes contraption01:28
that's all I've come across so far, I haven't actually tied much of the different components together yet.
<bonniot>if you see possible improvements, you are welcome to try them and commit changes01:29
i know that AWT is pretty much covered, i'm not sure how much of Swing itself is01:30
<lodewijk>I don't know either, I haven't looked at the code that much yet.01:31
anyway, I'm off to write some more code. thanks for the help :)
<bonniot>but you have been using it :-)
<lodewijk>yes, well, using is different than knowing it well enough to figure out possible improvements01:32
<lodewijk>anyway, I'm off. bye :)01:33
* lodewijk leaves
checking for valid code is alot easier then generating helpfull erro messages
took an hour to find a null to not null assignment, it just proclaimed that a method call didnt exsist01:48
<bonniot>in nice or alpha?01:49
<bonniot>so you added the nullness aspect too?01:51
<Bluelive>yup, but removing null ness is abit more of a hassle
<bonniot>you mean the if (x != null) ... ?01:52
<Bluelive>i have no inference, so i have a notnull semi function01:53
<bonniot>so where is the difficulty?
<Bluelive>helpfull error messages01:54
did you try examples in Nice to see what it gives?
normally, it says:
"this value might be null"01:55
not for arguments in method calls with overloading, though
<Bluelive>well i currently just have a matches() function to find a method call, and that doesnt provide enough dat ato give a h3elpfull error message :)01:56
<bonniot>it's sure that error reporting is hard01:57
<Bluelive>i was so pissed today02:02
met a friend, he works for a company that bought my old work (they went broke)
now theyre selling the products we build all over the world02:03
one guy is going to china with some of my code and ill never get a dime or credit
<bonniot>your previous company went broke?02:04
<Bluelive>its seems the same old story, small company has a product, spends years on it, but never gets out of beta, big company buys it, dumps all the old employes and sells the product
<bonniot>isn't it hard for them to work on the code if they dumped everybody?02:05
<Bluelive>i was an employee, but we were only 5 people (of which only me and one other were coders)
<bonniot>code is good, but experience with it is very important...02:06
<Bluelive>the problem is that were both still students, so we cant put in any serious houres, but they didnt ask us anyways02:07
<bonniot>yes, i can imagine this is very frustrating02:08
<Bluelive>well not me anyways, guess they knew i could go on permanent sick leave at any moment i wanted
<bonniot>i guess that's the meaning of explotation:02:10
when you work in a company, what you do does not belong to you but to the company
<Bluelive>not that i intended to, its hard to get a job with that on your record
<bonniot>they are renting you
<Bluelive>doesnt feel like that when your inventing02:11
<bonniot>yes, because it should not be like that
<Bluelive>im still not sure if it is even likely to find another place that pays good and lets a coder be creative02:14
<bonniot>dunno, i have no experience in this02:17
<Bluelive>dont you want something like that for your own job ?02:37
<bonniot>i'd like to be independent :-)02:39
<Bluelive>i would like to have some poeple around me to talk about the job 02:41
independed asin, self funded one man projects ?
kind of highrisk highcost lonely type stuff02:44
<bonniot>it's a trade off, you can't have everything :-/03:32
good night03:55
* bonniot leaves03:56
* lodewijk joins21:21
* lodewijk leaves
* lodewijk joins21:42
* lodewijk leaves21:43
* lodewijk joins21:44
* bonniot joins22:06
<lodewijk>oh, hi there :)22:19
is it intentional that I can say, for example, class Foo<Integer> extends List<Integer> {}, but not class Foo<Map<Integer, Integer>> extends List<Map<Integer, Integer>> {} ?
from looking at the parser source I suspect it is, but I wonder why.22:20
<bonniot>yes, this is not supported by the type system at the moment22:21
even class Foo<Integer> extends List<Integer> is probably not what you think22:22
<lodewijk>no, I would rather be able to say Foo extends List<Integer>, but we've been over that a while ago :)
<bonniot>Foo<T> extends List<T>, the type parameter being just a name
yes, that's a planned extension
<lodewijk>aha, okay, so I'm not actually claiming to have a subclass of a List of Integers there. got it.22:23
<bonniot>you should get by with having a _field_ of type List<int> in your class, no?22:25
(note: Nice supports List<int>, not need to use List<Integer>, althouhg you also can of course)22:26
<lodewijk>not in this instance. the issue here is that I have to implement a Java interface that mandates a method to construct an Object from a byte[] and vice-versa. I tried retyping the interface and those methods, but the Object I need to create is really a Map<>.22:27
another issue I've come across is with testing for nullness. a test for null followed by code using it like it was non-null works only for local variables, not for any levels of indirection. is this intended?22:29
example code:
class Foo { ?Integer i = null; }
void main(String[] args) {
Foo f = new Foo();
if (f.i != null)
has the compiler complaining that f.i might be null.
<bonniot>yes, this is intended22:32
strictly speaking, there is no guarantee that f.i is not null at the point of use22:33
for instance, the constructor of Foo could create a new thread that sets the i field at random moments
<lodewijk>ah, yes.22:34
<bonniot>it's a rather convoluted case, but it's still possible
we know this makes the mechanism somewhat iritating sometimes
at the moment, your best bet is to assigh f.i to a local, then test it
we have been discussing ways to make this more friendly...22:35
(you can also write notNull(f.i).toString() if you prefer)
<lodewijk>yes, but I would've liked to have less notNull()s in the code :)22:36
<bonniot>sure, i understand that :-)
<lodewijk>and how difficult would it be to have the assert statement play along with this?
like assert foo != null: "Oops"; foo.florp();
<bonniot>it seems perfectly feasible. medium amount of work needed22:38
does this look like a common pattern to you?
<lodewijk>okay, maybe I'll take a stab at that. I like using asserts for that stuff, yes.
<bonniot>it's not the simplest part of the compiler, though...22:39
but not the hardest either :-)
<lodewijk>that's okay, I aced my compiler construction course ;)22:40
<bonniot>this was discussed a few days ago on this channel, you could find the advice in the logs
you seem like a valuable user/contributor to keep around ;-)
back to your Map problem, is this a public interface? or could you precise what the problem is?22:42
<lodewijk>oh, sorry, I was browsing the logs22:44
let me look up the docs
now I have a class that implements that interface for one particular data type, and another class for another data type.22:45
but they both still deal in Object, as per the interface specification.
and what's the problem?
<lodewijk>now I would like to retype DataBinding to take a parameter T that I can plug into it instead of Object.
and the idea was to then subclass this and fill in the concrete types in both the implementing classes22:47
<bonniot>i see
you could try:
<T | String <: T> class StringDatabinding<T> implements DataBinding<T> {}22:48
objectToData(String s, data) { ... }22:49
dataToObject(data) = ...;
with not {} at the end of the first line, just {22:50
what this does is to add a constraint on the type parameter, String <: T
that is that T is a supertype of String
<lodewijk>ah, got it. yes, and that constraint can be something like a Map<> instead of a simple type?22:51
<bonniot>so you can only create StringDataBinding<String> in fact
<lodewijk>okay, I'll go and try that then.
<bonniot>generic Map, or with specific types?
<lodewijk>specific types.
<bonniot><T | Map<String,String> <: T> class StringDatabinding<T> implements DataBinding<T> {22:52
<lodewijk>okay, I'll go and play around with that. thanks for the help :)
<bonniot>I'm not completely sure, but it might help to add:
<T | Map<String,String> <: T, T <: Map<String,String>> class StringDatabinding<T> implements DataBinding<T> {22:53
which (in an ugly syntax) says that T is exacltly that type
<lodewijk>and that completely pins it down then
<bonniot>ok, good luck
<lodewijk>okay, bye :)
* lodewijk leaves
<bonniot>i'll be away, but check back in ~1h
* bonniot is away: send me a private message if needed
* lodewijk joins23:18
back again..
it seems the parser will try to parse the Map<> part in objectToData(Map<Dimension, Value> map, TupleOutput output) as a Pattern, which makes it try and treat it as an expression:23:20
Dimension is not a global constant with an integer value.
on account of the '<'
<Bluelive>fun, i got a hello world working again23:24
* bonniot is back (gone 01:12:14)00:06
yes, in method implementations, you can only write patterns, not types
that is, for a generic class, leave out the type parameters00:07
objectToData(Map map, ...)
<lodewijk>the assert patch almost compiles :)
<bonniot>really? wow!
<lodewijk>yes, it compiles! now lets see what it does :)00:29
<lodewijk>it dumps core. time for some printf() debugging.00:33
<bonniot>pardon me?00:34
<lodewijk>yes, printf(), the universal debugging tool. or System.out.println() in the java world :)00:35
<bonniot>dumps core?
<lodewijk>well, no, throws exceptions and such.
<bonniot>ah, i feel better ;-)00:36
is the patch big?
<lodewijk>hmmm.. that's strange. from reading the code, I would expect a CallExp.function to be an IdentExp in the case of an assert statement.
no it's not big. it's actually a nasty hack, rewriting an assert statement into an if() in rewrite.nice00:37
<bonniot>should be IdentExp before resolution, and SymbolExp or OverloadedSymbolExp afterwards00:38
Ident is just a name, Symbol is a link to the definition00:39
<lodewijk>aha.. that's probably it then.
<bonniot>you can use e.isCallTo("assert") to know if a call is to assert
will work in both cases
i see, you rewrite assert x != null ---> if (x != null) assert false00:41
<lodewijk>no, assert x != null: "foo"; /* code */ -> if (x != null) { /* code */ } else throw new AssertionError("foo");00:42
okay, now it's not throwing exceptions anymore, but it doesn't do anything either. oh well, I'll look into it tomorrow.00:43
<bonniot>can you send me the patch? maybe i'll see something obvious
<lodewijk>okay. let's see how cvs diff works these days, sf.net has been very slow.00:44
I wonder when they'll switch to subversion..
<bonniot>yes, it's a pain
yes, it would be good if they provided it as an option00:45
1.0 is almost ready...
<lodewijk>we've used subversion at work for two years now, since 0.14. it has it's annoyances as well, but generally is much better.00:46
yup: cvs.sourceforge.net: Operation timed out
oh wait, I can just send you rewrite.nice, that's the only thing I touched.00:47
<bonniot>yep, i can diff locally or just use it00:48
<lodewijk>okay, on it's way. but the nastiest about this patch is the creating of that throw statement. I just now realized that isn't necessary, you can write it into00:49
assert x != null: "foo"; /* code */ -> assert x != null: "foo"; if (x != null) { /* code */ }00:50
so just leave the assert, only stuff what comes after in an if statement with the assert condition
<bonniot>would be problematic for more complex expressions, possibly with side effects00:51
assert x != null && doSomething();00:52
you don't want to do it twice
but the machinery is already written to extract the list of tested variables
<lodewijk>but asserts with sideeffects is a traditional no-no. is it different in java?
<bonniot>i think it's not advised
i don't think it's formally illegal00:53
could also be performance reasons...
<lodewijk>yes, I saw the function that returns the two lists of variables
<bonniot>assert x != null && fact(10000) > y;
<lodewijk>ouch :)00:54
okay, I'm falling asleep. see you later.00:56
* lodewijk leaves