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

Using timezone: Greenwich Mean Time
<arjanb>.12:47
logger works again
<Bluelive>hmz13:04
how do you resolve this ?
Say C extends B extends A
List<C> is a parameter for a <T> (T <=B) foo(List<T> x)13:05
in which on element of x is used as a parameter to a function wich is overloaded for a,b and c
which variant gets called ?13:06
s/<=/>=/
i would guess the B variant ?13:07
<bonniot>just checking: overloaded or overridden?
<Bluelive>void foo2(A x), void foo2(B x), void foo2(C x), i believe thats called overloaded13:08
<bonniot>the terminology differs
<Bluelive>which one do you use ?13:09
<bonniot>for me: overloaded = static resolution, at compile time
so if you have A x = new B()13:10
if foo2 is overloaded, it calls foo2(A)
if foo2 is a method with three implementations, it calls foo2(B)
<Bluelive>so B would have been used in my example ?13:11
<bonniot>no, i'm just making the terms clear
<Bluelive>because thats the concrete type inside the method for x ?
<bonniot>this is a simpler example
to know what you mean by overloaded13:12
which one?
<Bluelive>void foo2(A x), void foo2(B x), void foo2(C x), exsist as static method inside a class named D for my example13:13
s/method/methods/13:14
<bonniot>in Java?13:15
<Bluelive>yes
<bonniot>ok, so it's overloading13:16
and you say you have T>=B as a constraint?
<Bluelive>yes
<bonniot>then you cannot call foo2 with a T13:17
<Bluelive>?
<bonniot>because T might not be a subclass of A at runtime. it's unsafe
<Bluelive>because of the foo(C) ambiguity ?
<bonniot>no, because of unsafety
for instance, you can call foo(List<Object>)13:18
Object>=B, so it is valid
<Bluelive>no because T would be less then B then
ah
i allways get those the wrong way around
t<=B then ?13:19
<bonniot>so maybe you mean T<=B
:-)
in that case it will call foo2(B)
<Bluelive>but isnt that still wrong because of the foo2(C) ?
<bonniot>not if foo2(C) is a staticly overloaded method13:20
it's the same as
A x = new B()
foo2(x) calls foo2(A)
<Bluelive>:)
<bonniot>you can define foo2 as a method if you wish
then it will call foo2(C)
<Bluelive>so the T is actually typed as the lower constraint while staticly resolving ?13:21
in the case of any T, is it an Object ?13:22
<bonniot>no, it's only equivalent to that if you call a monorphic method like foo2
if you call
<T> T id(T);
then the result will be T, not B
which is more precise
(sorry, I should say <U> U id(U) to avoid the confusion)13:23
<Bluelive>no its clear
Ive been changing my type system to use a similar scheme, but im a bit baffled by the potential problem with nesting13:24
still, im impressed13:25
never thought statictyping could get so fa13:26
r
altough its abit more meta in its nature like this
<bonniot>:-)13:27
what do you mean: it's more meta in it's nature?
<Bluelive>well most strongly typed languages define a type and thats it
here you define parametrics, with more dynamic defined constraints13:28
instead of information about data, its information abotu information about data
so meta :)
<bonniot>yes
how do you like this:15:51
/ JAVA
println("b is " + b + " and a is " + a);
/// PERL: concise but hacky15:52
println("b is $b and a is $a");
/// Proposal:
println("b is "b" and a is "a);
the idea is: a string literal followed by an expression means concatenation15:53
intuitively, it feels like with " you enter the literal mode, then with another " you exit it and go back to the normal evaluation mode15:54
<arjanb>looks good16:09
would println(b " is the value of b"); be allowed?16:11
btw closure are nasty things on the implementation side
i still have the type inference not working correctly with closure16:13
i have no idea how to get it right16:22
void foo(?String x, List<int> list) {16:27
if (x == null) return;
list.foreach(int i => {println(x+i);});
}
wrong example16:29
what i do now is to set the original types back when entering a closure but that breaks reasonable code 16:33
but it's impossible to detect whether a closure escapes the block where it is declared16:37
<bonniot>(b " is ...")16:38
not for the moment
but maybe it could later
<arjanb>a problem with this syntax is reading many concatenations16:40
<bonniot>you should conservatively suppose a closure does escape
what pb?
<arjanb>" a " b " c " d " f " g " h "16:41
<bonniot>it would be more convincing on a real example16:42
but I think if you write it " a "b" c "d" f "g" h " it is readable16:43
also, your editor can use different colors for string literals
<arjanb>true
<bonniot>emacs does, and I think the eclipse plugin too16:44
<arjanb>and what would be the alternative for a += "zyx" and a = b + "abc"
<bonniot>?
<arjanb>or will `+` stay for string concats16:45
<bonniot>yes, it does
<arjanb>if i'm conservative to closure then it will break to much code i think16:48
void foo(?String x, List<int> list) {
if (x == null) return;
list.foreach(int i => {println(x.subString(i));});
}
<bonniot>we should only mark a variable as captured when it is *set* inside a closure16:52
<arjanb>i do that already
but that isn't the problem
<bonniot>so in this code x is not captured
<arjanb>the testcase that now passes at compile time but fails at runtime is:16:54
A a = new B();
if (a instanceof B) {
void->void f = () =>
{
int x = a./* /// FAIL HERE */life;
};
a = new A();
f();
}
<bonniot>ok, so that's a different issue16:55
the capture part is working, then?
<arjanb>yes
<bonniot>ok, good16:56
<arjanb>but the typecheck of the closure body isn't correct
<bonniot>yes
so i think it's best to use the conservative approach now16:59
you can always use a let to keep the more precise typing if that's what you want17:00
and we can later implement more precise analysis
for instance, for the if (...) return;, so can use the precise type
<arjanb>oh wait this is only a problem with non final varibles17:01
<bonniot>yes17:03
<arjanb>i see a good reason to make argument final by default17:04
<bonniot>methods arguments?17:05
<arjanb>yes
<bonniot>yes, that's possible17:06
with 'var' to make them mutable17:07
<arjanb>the exception for final variable in closure isn't always safe but you need to write quite odd code to break it18:38
<Bluelive>somebody will do that :)18:40
<arjanb>i don't think someone will write such code accidentily18:42
<Bluelive>what would it look like ?
<arjanb>let ?String x = somefunction();18:47
?(()->void) f = null;
if (x != null) {
f = ()=> { println(x.trim());};
}
if (f != null)
f(); //maybe NPE within function
<Bluelive>seems logical18:49
why would that be a problem ?
<arjanb>Nice should detect as much NPE's and CCE's at compile as possible18:51
<Bluelive>yeah but x can be null18:52
the state of x at the time of the definition of the anonymous method doesnt matter, but it does at invocation18:53
btw does this mean that anonymous methods cant be returned ?
as a value from a method i mean
<arjanb>it's possible18:54
so you can't find out at compile time where the anonymous function will be called18:55
<Bluelive>with a lot of effort you could try
but yeah, seems pretty impossible18:56
maybe give out a notify about it ?
* daniel__ joins19:59
i think a closure should always use the maximal type for a captured variable, so that we catch all errors20:04
<arjanb>ok20:11
it doesn't break any code in the compiler :)20:26
<daniel__>good20:40
<arjanb>committed20:49
could you look at the code?20:57
<daniel__>i'm busy at the moment, but I will21:37
bye23:10
* daniel__ leaves23:31
* bonniot leaves23:33