From forax at univ-mlv.fr Wed Nov 18 13:37:50 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Wed, 18 Nov 2009 22:37:50 +0100 Subject: lambda or reified lambda Message-ID: <4B04692E.8050301@univ-mlv.fr> Hi Neal, I've just read your new proposal for lambda in Java (v0.6a). A small remarks, I think that defined @Shared as an annotation is not necessary. 'shared' as a local keyword should be better. Your proposal doesn't say that function types are not reified: #int(String) fun = #(String text) text.length(); #int(Object) fun2 = fun; // ok, subtyping #int(String) fun3 = (#int(String))fun2; // unsafe warning. What is the reason to not use method handle to implement lambdas ? You will get reification for free. regards, R?mi From Maurizio.Cimadamore at Sun.COM Wed Nov 18 13:32:09 2009 From: Maurizio.Cimadamore at Sun.COM (Maurizio Cimadamore) Date: Wed, 18 Nov 2009 21:32:09 +0000 Subject: lambda or reified lambda In-Reply-To: <4B04692E.8050301@univ-mlv.fr> References: <4B04692E.8050301@univ-mlv.fr> Message-ID: <4B0467D9.1000400@sun.com> R?mi Forax wrote: > Hi Neal, > I've just read your new proposal for lambda in Java (v0.6a). > > A small remarks, I think that defined @Shared as an annotation > is not necessary. 'shared' as a local keyword should be better. > > Your proposal doesn't say that function types are not reified: > #int(String) fun = #(String text) text.length(); > #int(Object) fun2 = fun; // ok, subtyping > > #int(String) fun3 = (#int(String))fun2; // unsafe warning. Hi I think it's the other way around - you can go from #int(Object) to #int(String) but not from #int(String) to #int(Object) [subtyping between parameter types is contravariant]. Maurizio > > What is the reason to not use method handle to implement lambdas ? > You will get reification for free. > > regards, > R?mi > > > From forax at univ-mlv.fr Wed Nov 18 14:01:43 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Wed, 18 Nov 2009 23:01:43 +0100 Subject: lambda or reified lambda In-Reply-To: <4B0467D9.1000400@sun.com> References: <4B04692E.8050301@univ-mlv.fr> <4B0467D9.1000400@sun.com> Message-ID: <4B046EC7.6080202@univ-mlv.fr> Le 18/11/2009 22:32, Maurizio Cimadamore a ?crit : > R?mi Forax wrote: >> Hi Neal, >> I've just read your new proposal for lambda in Java (v0.6a). >> >> A small remarks, I think that defined @Shared as an annotation >> is not necessary. 'shared' as a local keyword should be better. >> >> Your proposal doesn't say that function types are not reified: >> #int(String) fun = #(String text) text.length(); >> #int(Object) fun2 = fun; // ok, subtyping >> >> #int(String) fun3 = (#int(String))fun2; // unsafe warning. > Hi > I think it's the other way around - you can go from #int(Object) to > #int(String) but not from #int(String) to #int(Object) [subtyping > between parameter types is contravariant]. > > Maurizio Oups sorry, I mean: #int(Object) fun = #(Object o) o.toString().length(); #int(String) fun2 = fun; // ok, subtyping #int(Object) fun3 = (#int(Object))fun2; // unsafe warning. >> >> What is the reason to not use method handle to implement lambdas ? >> You will get reification for free. >> >> regards, >> R?mi >> >> >> > R?mi From pbenedict at apache.org Wed Nov 18 20:02:59 2009 From: pbenedict at apache.org (Paul Benedict) Date: Wed, 18 Nov 2009 22:02:59 -0600 Subject: Why a new type parameter for exception transparency? Message-ID: After reading the 0.6 version of the spec, I do not understand why a new type parameter must be created to support exception transparency. My understanding of closures is definitely in the amatuer range; perhaps someone can enlighten me why this code block: public static T withLock(Lock lock, #T() throws E block) throws E { lock.lock(); try { return block.invoke(); } finally { lock.unlock(); } } is not better written (and better understandable) as: public static T withLock(Lock lock, #T() throws E block) throws E { lock.lock(); try { return block.invoke(); } finally { lock.unlock(); } } The keyword "throws" looks sorely out of the place, but truly aside from the aesthetics, I can't find a reason for it's necessity. The "throws E extends Exception" is also nearly duplicated with "#T() throws E" -- we already know it throws something, so it doesn't need two "throws". Can't one be sacrificed? Paul From neal at gafter.com Wed Nov 18 20:05:00 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 18 Nov 2009 20:05:00 -0800 Subject: lambda or reified lambda In-Reply-To: <4B04692E.8050301@univ-mlv.fr> References: <4B04692E.8050301@univ-mlv.fr> Message-ID: <15e8b9d20911182005y3fdb42e9jeea47479d6dea774@mail.gmail.com> On Wed, Nov 18, 2009 at 1:37 PM, R?mi Forax wrote: > Hi Neal, > I've just read your new proposal for lambda in Java (v0.6a). > > A small remarks, I think that defined @Shared as an annotation > is not necessary. 'shared' as a local keyword should be better. > Since it only suppresses a warning, even a context-sensitive keyword seems overkill. > Your proposal doesn't say that function types are not reified: > The proposal defines function types as instances of generic interfaces. If interfaces are not reified, then it follows logically that function types are not reified and therefore need not be specified. > #int(String) fun = #(String text) text.length(); > #int(Object) fun2 = fun; // ok, subtyping > > #int(String) fun3 = (#int(String))fun2; // unsafe warning. > > What is the reason to not use method handle to implement lambdas ? > You will get reification for free. > On the contrary, there are many issues preventing that. Here are two examples: First, method handles do not have VM-verified contravariance of argument types and covariance of return types. Consequently, they cannot support function subtyping. For example, if it requires code to convert an #int(Object) into an #int(String) and the result of the conversion is not reference-equal to the original value, then how would the compiler generate code to convert an Iterable<#int(Object)> into an Iterable<#int(String)>? Second, lambdas inside generic methods cannot in principle be reified if generic methods are not reified: * * * #T() makeClosure(T t)* *{* * return #()t; // what is the reified type of the closure here?* *}* Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091118/67b5d204/attachment.html From neal at gafter.com Wed Nov 18 20:12:28 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 18 Nov 2009 20:12:28 -0800 Subject: Why a new type parameter for exception transparency? In-Reply-To: References: Message-ID: <15e8b9d20911182012t1949caabga9c6941c2050bbff@mail.gmail.com> Paul- The short answer is that a different generic type inference mechanism must be used on these exception parameters than on ordinary type parameters. For example, if you invoke this method on a closure that throws IOException and SQLException, the ordinary generic type inference mechanism will conclude that E is the type Exception. As a consequence, the caller will have to catch Exception rather than just IOException and SQLException. The approach I've taken to address that is to add a modifier on the type parameter that directs the inference mechanism to infer disjunction types rather than lub() types. Perhaps another approach would be to just take the hint from the fact that the type parameter's bound is a checked exception type. That is not strictly backward source-compatible, but it might be compatible enough to allow us to simplify the syntax as you suggest. Cheers, Neal On Wed, Nov 18, 2009 at 8:02 PM, Paul Benedict wrote: > After reading the 0.6 version of the spec, I do not understand why a > new type parameter must be created to support exception transparency. > My understanding of closures is definitely in the amatuer range; > perhaps someone can enlighten me why this code block: > > public static > T withLock(Lock lock, #T() throws E block) throws E { > lock.lock(); > try { > return block.invoke(); > } finally { > lock.unlock(); > } > } > > is not better written (and better understandable) as: > > public static > T withLock(Lock lock, #T() throws E block) throws E { > lock.lock(); > try { > return block.invoke(); > } finally { > lock.unlock(); > } > } > > The keyword "throws" looks sorely out of the place, but truly aside > from the aesthetics, I can't find a reason for it's necessity. The > "throws E extends Exception" is also nearly duplicated with "#T() > throws E" -- we already know it throws something, so it doesn't need > two "throws". Can't one be sacrificed? > > Paul > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091118/dec4fa47/attachment.html From pbenedict at apache.org Wed Nov 18 20:41:47 2009 From: pbenedict at apache.org (Paul Benedict) Date: Wed, 18 Nov 2009 22:41:47 -0600 Subject: Why a new type parameter for exception transparency? In-Reply-To: References: <15e8b9d20911182012t1949caabga9c6941c2050bbff@mail.gmail.com> Message-ID: Neal, > Perhaps another approach would be to just take the hint from the > fact that the type parameter's bound is a checked exception type. That is > not strictly backward source-compatible, but it might be compatible enough > to allow us to simplify the syntax as you suggest. You read my mind! I was hoping you could infer it. Anyway, if we take closures out of the discussion, I imagine the new type is usable outside of closures, correct? For example: public void throwit(E e) throws E { throw e; } But really, the compiler should know what to do just with this: public void throwit(E e) throws E { throw e; } I might be missing something, but is there any important distinction between the two? Paul From neal at gafter.com Wed Nov 18 21:02:42 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 18 Nov 2009 21:02:42 -0800 Subject: Why a new type parameter for exception transparency? In-Reply-To: References: <15e8b9d20911182012t1949caabga9c6941c2050bbff@mail.gmail.com> Message-ID: <15e8b9d20911182102s17da6779w9e96ad89a321c80e@mail.gmail.com> On Wed, Nov 18, 2009 at 8:41 PM, Paul Benedict wrote: > But really, the compiler should know what to do just with this: > > public void throwit(E e) throws E { > throw e; > } > > I might be missing something, but is there any important distinction > between the two? > Not in this case. The important cases are where the compiler has to combine exceptions that may be thrown from multiple places. You want type inference to form a disjunction type then, not find the common supertype. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091118/e11a52b5/attachment-0001.html From forax at univ-mlv.fr Thu Nov 19 06:20:53 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 19 Nov 2009 15:20:53 +0100 Subject: lambda or reified lambda In-Reply-To: <15e8b9d20911182005y3fdb42e9jeea47479d6dea774@mail.gmail.com> References: <4B04692E.8050301@univ-mlv.fr> <15e8b9d20911182005y3fdb42e9jeea47479d6dea774@mail.gmail.com> Message-ID: <4B055445.1010506@univ-mlv.fr> Neal Gafter a ?crit : > On Wed, Nov 18, 2009 at 1:37 PM, R?mi Forax > wrote: > > Hi Neal, > I've just read your new proposal for lambda in Java (v0.6a). > > A small remarks, I think that defined @Shared as an annotation > is not necessary. 'shared' as a local keyword should be better. > > > Since it only suppresses a warning, even a context-sensitive keyword > seems overkill. > > > Your proposal doesn't say that function types are not reified: > > > The proposal defines function types as instances of generic > interfaces. If interfaces are not reified, then it follows logically > that function types are not reified and therefore need not be specified. > > > #int(String) fun = #(String text) text.length(); > #int(Object) fun2 = fun; // ok, subtyping > > #int(String) fun3 = (#int(String))fun2; // unsafe warning. > > What is the reason to not use method handle to implement lambdas ? > You will get reification for free. > > > On the contrary, there are many issues preventing that. Here are two > examples: > > First, method handles do not have VM-verified contravariance of > argument types and covariance of return types. Consequently, they > cannot support function subtyping. For example, if it requires code > to convert an #int(Object) into an #int(String) and the result of the > conversion is not reference-equal to the original value, then how > would the compiler generate code to convert an Iterable<#int(Object)> > into an Iterable<#int(String)>? That's true that there is not currently support for function subtyping but it can be added, The EG of JSR292 let a place holder for that saying something like when Java will suppport closure, this need to be re-visited. Also you can use invokedynamic and generate an inlining cache with an entry for each runtime method type. In both case, there is no conversion. > > Second, lambdas inside generic methods cannot in principle be reified > if generic methods are not reified: > * > * > * #T() makeClosure(T t)* > *{* > * return #()t; // what is the reified type of the closure here?* > *}* First, we aren't in the same configuration than with the introduction of generics, there is no existing code that already use lambdas. In my opinion the best way to deal with that code is to consider that the instantation of a generic lambda is a conversion : #String() fun = makeClosure("hello"); will be translated to something like: #String() fun = makeClosure("hello").genericInstantiation(String.class); Now to answer to your question, the reified type of a function type with generics will be a function type with erasure of generics at place where there is a generic: erasure of a type in a function type: - if it's the return type and it is generic, use the type of null. - if it's a parameter type and it is generic, use its bounds - if it's not a generics, use it directly. In you example, the reified function type will be #null() I think it will be ok if cast between a generic function type and a reified function type (and vice-versa) are not allowed. > > Cheers, > Neal Cheers, R?mi From forax at univ-mlv.fr Thu Nov 19 06:30:56 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 19 Nov 2009 15:30:56 +0100 Subject: lambda or reified lambda In-Reply-To: <15e8b9d20911182005y3fdb42e9jeea47479d6dea774@mail.gmail.com> References: <4B04692E.8050301@univ-mlv.fr> <15e8b9d20911182005y3fdb42e9jeea47479d6dea774@mail.gmail.com> Message-ID: <4B0556A0.3010109@univ-mlv.fr> Neal Gafter a ?crit : > On Wed, Nov 18, 2009 at 1:37 PM, R?mi Forax > wrote: > > Hi Neal, > I've just read your new proposal for lambda in Java (v0.6a). > > A small remarks, I think that defined @Shared as an annotation > is not necessary. 'shared' as a local keyword should be better. > > > Since it only suppresses a warning, even a context-sensitive keyword > seems overkill. Neal, during my Java course, I don't want to have to answer to the question why "final" is not '@Final'. R?mi From pbenedict at apache.org Thu Nov 19 08:20:57 2009 From: pbenedict at apache.org (Paul Benedict) Date: Thu, 19 Nov 2009 10:20:57 -0600 Subject: Expression syntax Message-ID: Neal/Remi, perhaps you could give your opinion on this one. To me, having well-formatted code to make easy readability is important to me. It's very important. I don't find it very readable without the use of braces to enclose the lambda function. Example: #int(String) fun = #(String text) text.length(); If braces aren't mandatory, are they validly optional? I would rather write: #int(String) fun = #(String text) { text.length(); } And that could allow my IDE formatters to run their rules based on how to handle braces. If someone likes breaking, this can remain possible: #int(String) fun = #(String text) { text.length(); } If someone likes to inline everything, this could be possible too: object.call(a, b, c, #(String text) { text.length(); }); Just to be clear, my focus here is on flexibility to take advantage of existing IDE formatting options surrounding braces. Paul From tronicek at fel.cvut.cz Thu Nov 19 08:57:28 2009 From: tronicek at fel.cvut.cz (Zdenek Tronicek) Date: Thu, 19 Nov 2009 17:57:28 +0100 Subject: Expression syntax In-Reply-To: References: Message-ID: <20091119175728.979846zhletcs1yw@wimap.feld.cvut.cz> Hi Paul, I am not Neal nor Remi but I will try to answer anyway :). Braces are not optional here because they distinguish between expression and statement lambda: #int(T) p = #(T t) t.m(); // expression lambda #int(T) p = #(T t) { return t.m(); } // expression statement I think this is a good choice because previous syntax (when the closure returns the value of the last expression) was confusing. Zdenek -- Zdenek Tronicek FIT CTU in Prague Cituji Paul Benedict : > Neal/Remi, perhaps you could give your opinion on this one. To me, > having well-formatted code to make easy readability is important to > me. It's very important. I don't find it very readable without the use > of braces to enclose the lambda function. > > Example: > #int(String) fun = #(String text) text.length(); > > If braces aren't mandatory, are they validly optional? I would rather write: > #int(String) fun = #(String text) { text.length(); } > > And that could allow my IDE formatters to run their rules based on how > to handle braces. If someone likes breaking, this can remain possible: > #int(String) fun = #(String text) { > text.length(); > } > > If someone likes to inline everything, this could be possible too: > object.call(a, b, c, #(String text) { text.length(); }); > > Just to be clear, my focus here is on flexibility to take advantage of > existing IDE formatting options surrounding braces. > > Paul > From tronicek at fel.cvut.cz Thu Nov 19 09:00:04 2009 From: tronicek at fel.cvut.cz (Zdenek Tronicek) Date: Thu, 19 Nov 2009 18:00:04 +0100 Subject: Expression syntax In-Reply-To: <20091119175728.979846zhletcs1yw@wimap.feld.cvut.cz> References: <20091119175728.979846zhletcs1yw@wimap.feld.cvut.cz> Message-ID: <20091119180004.813250cszd7dipas@wimap.feld.cvut.cz> Sorry, of course should be: > #int(T) p = #(T t) t.m(); // expression lambda > #int(T) p = #(T t) { return t.m(); } // statement lambda Z. -- Zdenek Tronicek FIT CTU in Prague Cituji Zdenek Tronicek : > Hi Paul, > > I am not Neal nor Remi but I will try to answer anyway :). > > Braces are not optional here because they distinguish between > expression and statement lambda: > > #int(T) p = #(T t) t.m(); // expression lambda > #int(T) p = #(T t) { return t.m(); } // expression statement > > I think this is a good choice because previous syntax (when the > closure returns the value of the last expression) was confusing. > > Zdenek > -- > Zdenek Tronicek > FIT CTU in Prague > > > Cituji Paul Benedict : > >> Neal/Remi, perhaps you could give your opinion on this one. To me, >> having well-formatted code to make easy readability is important to >> me. It's very important. I don't find it very readable without the use >> of braces to enclose the lambda function. >> >> Example: >> #int(String) fun = #(String text) text.length(); >> >> If braces aren't mandatory, are they validly optional? I would rather write: >> #int(String) fun = #(String text) { text.length(); } >> >> And that could allow my IDE formatters to run their rules based on how >> to handle braces. If someone likes breaking, this can remain possible: >> #int(String) fun = #(String text) { >> text.length(); >> } >> >> If someone likes to inline everything, this could be possible too: >> object.call(a, b, c, #(String text) { text.length(); }); >> >> Just to be clear, my focus here is on flexibility to take advantage of >> existing IDE formatting options surrounding braces. >> >> Paul >> > > > > From pbenedict at apache.org Thu Nov 19 09:02:11 2009 From: pbenedict at apache.org (Paul Benedict) Date: Thu, 19 Nov 2009 11:02:11 -0600 Subject: Expression syntax In-Reply-To: <20091119175728.979846zhletcs1yw@wimap.feld.cvut.cz> References: <20091119175728.979846zhletcs1yw@wimap.feld.cvut.cz> Message-ID: On Thu, Nov 19, 2009 at 10:57 AM, Zdenek Tronicek wrote: > Braces are not optional here because they distinguish between expression and > statement lambda: > > #int(T) p = #(T t) t.m(); // expression lambda > #int(T) p = #(T t) { return t.m(); } // statement lambda > > I think this is a good choice because previous syntax (when the closure > returns the value of the last expression) was confusing. > Okay, so let's take this example. How is it substantially different than: #int(T) p = #(T t) { t.m(); } // expression lambda #int(T) p = #(T t) { return t.m(); } // statement lambda Couldn't the lack of "return" indicate such? Paul From tronicek at fel.cvut.cz Thu Nov 19 09:17:40 2009 From: tronicek at fel.cvut.cz (Zdenek Tronicek) Date: Thu, 19 Nov 2009 18:17:40 +0100 Subject: Expression syntax In-Reply-To: References: <20091119175728.979846zhletcs1yw@wimap.feld.cvut.cz> Message-ID: <20091119181740.3793511dxaapqeno@wimap.feld.cvut.cz> This is exactly the previous version of the closures proposal. There, the closure returned the value of the last expression. But there were two "problems" with this approach: 1) it was a concept which were not used anywhere else, 2) you could not return a value before the end of closure. Z. -- Zdenek Tronicek FIT CTU in Prague Cituji Paul Benedict : > On Thu, Nov 19, 2009 at 10:57 AM, Zdenek Tronicek > wrote: >> Braces are not optional here because they distinguish between expression and >> statement lambda: >> >> #int(T) p = #(T t) t.m(); // expression lambda >> #int(T) p = #(T t) { return t.m(); } // statement lambda >> >> I think this is a good choice because previous syntax (when the closure >> returns the value of the last expression) was confusing. >> > > Okay, so let's take this example. How is it substantially different than: > #int(T) p = #(T t) { t.m(); } // expression lambda > #int(T) p = #(T t) { return t.m(); } // statement lambda > > Couldn't the lack of "return" indicate such? > > Paul > From pbenedict at apache.org Thu Nov 19 09:21:51 2009 From: pbenedict at apache.org (Paul Benedict) Date: Thu, 19 Nov 2009 11:21:51 -0600 Subject: Expression syntax In-Reply-To: <20091119181740.3793511dxaapqeno@wimap.feld.cvut.cz> References: <20091119175728.979846zhletcs1yw@wimap.feld.cvut.cz> <20091119181740.3793511dxaapqeno@wimap.feld.cvut.cz> Message-ID: Thanks for reminding me of the previous version ;-) Okay. I think the braces are an obvious delimiter that's helpful for reading, but I give the benefit-of-the-doubt to Neal that he's gone through the thought process and made the right trade-off. If Neal/Remi know of any other possible way, maybe they could share it. Paul On Thu, Nov 19, 2009 at 11:17 AM, Zdenek Tronicek wrote: > This is exactly the previous version of the closures proposal. There, the > closure returned the value of the last expression. But there were two > "problems" with this approach: 1) it was a concept which were not used > anywhere else, 2) you could not return a value before the end of closure. > > Z. > -- > Zdenek Tronicek > FIT CTU in Prague > > > Cituji Paul Benedict : > >> On Thu, Nov 19, 2009 at 10:57 AM, Zdenek Tronicek >> wrote: >>> >>> Braces are not optional here because they distinguish between expression >>> and >>> statement lambda: >>> >>> #int(T) p = #(T t) t.m(); ?// expression lambda >>> #int(T) p = #(T t) { return t.m(); } ?// statement lambda >>> >>> I think this is a good choice because previous syntax (when the closure >>> returns the value of the last expression) was confusing. >>> >> >> Okay, so let's take this example. How is it substantially different than: >> #int(T) p = #(T t) { t.m(); } ?// expression lambda >> #int(T) p = #(T t) { return t.m(); } ?// statement lambda >> >> Couldn't the lack of "return" indicate such? >> >> Paul >> > > > > From tronicek at fel.cvut.cz Thu Nov 19 09:34:44 2009 From: tronicek at fel.cvut.cz (Zdenek Tronicek) Date: Thu, 19 Nov 2009 18:34:44 +0100 Subject: lambda or reified lambda In-Reply-To: <4B0556A0.3010109@univ-mlv.fr> References: <4B04692E.8050301@univ-mlv.fr> <15e8b9d20911182005y3fdb42e9jeea47479d6dea774@mail.gmail.com> <4B0556A0.3010109@univ-mlv.fr> Message-ID: <20091119183444.82466rkl0ql9eies@wimap.feld.cvut.cz> Hi Remi and others, my view of annotations is that annotations add some "additional information" to the source code. It is "additional information" and so the annotations should not change the semantics. So, should the final keyword be replaced by the @Final annotation? Certainly no, because the semantics of the final variables is different to non-final in multithreaded environment. The keyword is right here in my opinion. Zdenek -- Zdenek Tronicek FIT CTU in Prague Cituji R?mi Forax : > Neal Gafter a ?crit : >> On Wed, Nov 18, 2009 at 1:37 PM, R?mi Forax > > wrote: >> >> Hi Neal, >> I've just read your new proposal for lambda in Java (v0.6a). >> >> A small remarks, I think that defined @Shared as an annotation >> is not necessary. 'shared' as a local keyword should be better. >> >> >> Since it only suppresses a warning, even a context-sensitive >> keyword seems overkill. > > Neal, > during my Java course, I don't want to have to answer to the question > why "final" is not '@Final'. > > R?mi > From neal at gafter.com Thu Nov 19 15:53:47 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 19 Nov 2009 15:53:47 -0800 Subject: Expression syntax In-Reply-To: References: <20091119175728.979846zhletcs1yw@wimap.feld.cvut.cz> <20091119181740.3793511dxaapqeno@wimap.feld.cvut.cz> Message-ID: <15e8b9d20911191553h1c526a42jbf0b54d255359471@mail.gmail.com> Paul- For expression lambdas, you can certainly use parens if you find it more clear: *#int(T) p = #(T t) ( t.m() ) * Since expression lambdas are at the topmost level of the precedence hierarchy, I think there are few problems reading code even without the parens. Cheers, Neal On Thu, Nov 19, 2009 at 9:21 AM, Paul Benedict wrote: > Thanks for reminding me of the previous version ;-) Okay. I think the > braces are an obvious delimiter that's helpful for reading, but I give > the benefit-of-the-doubt to Neal that he's gone through the thought > process and made the right trade-off. If Neal/Remi know of any other > possible way, maybe they could share it. > > Paul > > On Thu, Nov 19, 2009 at 11:17 AM, Zdenek Tronicek > wrote: > > This is exactly the previous version of the closures proposal. There, the > > closure returned the value of the last expression. But there were two > > "problems" with this approach: 1) it was a concept which were not used > > anywhere else, 2) you could not return a value before the end of closure. > > > > Z. > > -- > > Zdenek Tronicek > > FIT CTU in Prague > > > > > > Cituji Paul Benedict : > > > >> On Thu, Nov 19, 2009 at 10:57 AM, Zdenek Tronicek > > >> wrote: > >>> > >>> Braces are not optional here because they distinguish between > expression > >>> and > >>> statement lambda: > >>> > >>> #int(T) p = #(T t) t.m(); // expression lambda > >>> #int(T) p = #(T t) { return t.m(); } // statement lambda > >>> > >>> I think this is a good choice because previous syntax (when the closure > >>> returns the value of the last expression) was confusing. > >>> > >> > >> Okay, so let's take this example. How is it substantially different > than: > >> #int(T) p = #(T t) { t.m(); } // expression lambda > >> #int(T) p = #(T t) { return t.m(); } // statement lambda > >> > >> Couldn't the lack of "return" indicate such? > >> > >> Paul > >> > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091119/10431296/attachment.html From opinali at gmail.com Fri Nov 20 06:32:40 2009 From: opinali at gmail.com (Osvaldo Doederlein) Date: Fri, 20 Nov 2009 12:32:40 -0200 Subject: Currying and the warning Message-ID: Hi Neal, I've just read the new proposal, seems to hit a quite good balance so I hope this will finally succeed. Some initial comments: The proposal doesn't mention support for any kind of transformation. You've already explained that MethodHandle doesn't serve as a good basis for closures, but I'd like both features to be as... close as possible; and for closures, it makes a lot of sense to support currying because this feature is highly useful and it wouldn't add any significant complexity (that I can see) to the language. The Method Reference facility would also allow to curry a common method, this is a simple combination of two steps (creating a closure that wraps the method and then currying that closure), but would be more efficient if defined/implemented as a single operation (so we can just create a single closure that performs the currying, i.e. passing some fixed parameters, when delegating to the method). The _mandatory_ warning for closures that capture non-final/shared vars seems too conservative. The motivation should be not freaking people who worry about hidden costs, but there's now plenty precedent for that, e.g. the silent allocations performed by enhanced-for or autoboxing, or much before, inner classes with their synthetic accessors to outer fields/methods including private ones. The language spec doesn't require mandatory warnings for those. I'm fully favorable to an _optional_ warning, that developers can activate when reviewing performance-critical code, such as the many extra warnings in the Eclipse compiler or tools like Checkstyle/FindBugs/PMD that include many detections of potential performance issues. But IMHO, making this warning of captures enabled by default will "taint" closures as something expensive, and make it more complex than necessary by requiring the @Shared or @SuppressWarnings("shared") annotations. (If the warning is optional, I guess we can omit at least @Shared from the spec.) In a secondary note, item 2 of that warning could be "The variable is not the target of any assignment after the closure is defined", which will avoid the warning for simple cases like "{ int x; if (a) x = 10 else x = 20; #() println(x) }" (not all developers would prefer using ?: here to enforce the initialization-in-declaration). Of course, the "after" in "after the closure is defined" is not that simple because if the closure is defined inside a loop, we can't have assignmaets to the variable before the closure definition but inside the loop; but I guess javac can already do the necessary flow analysis, should need it for definite assignment. A+ Osvaldo -- ----------------------------------------------------------------------- Osvaldo Pinali Doederlein Visionnaire Virtus S/A osvaldo at visionnaire.com.br http://www.visionnaire.com.br Arquiteto de Tecnologia +55 (41) 3337-1000 #226 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091120/d49dc13d/attachment.html From tronicek at fel.cvut.cz Fri Nov 20 08:39:43 2009 From: tronicek at fel.cvut.cz (Zdenek Tronicek) Date: Fri, 20 Nov 2009 17:39:43 +0100 Subject: Currying and the warning In-Reply-To: References: Message-ID: <20091120173943.92473mzzdm1ls2tr@wimap.feld.cvut.cz> Hi Osvaldo, the @Shared annotation says "I am aware that the variable may be accessed from many threads". It warns you that you may need a synchronization. It is not about hidden costs. Zdenek -- Zdenek Tronicek FIT CTU in Prague Cituji Osvaldo Doederlein : > Hi Neal, > > I've just read the new proposal, seems to hit a quite good balance so I hope > this will finally succeed. Some initial comments: > > The proposal doesn't mention support for any kind of transformation. You've > already explained that MethodHandle doesn't serve as a good basis for > closures, but I'd like both features to be as... close as possible; and for > closures, it makes a lot of sense to support currying because this feature > is highly useful and it wouldn't add any significant complexity (that I can > see) to the language. The Method Reference facility would also allow to > curry a common method, this is a simple combination of two steps (creating a > closure that wraps the method and then currying that closure), but would be > more efficient if defined/implemented as a single operation (so we can just > create a single closure that performs the currying, i.e. passing some fixed > parameters, when delegating to the method). > > The _mandatory_ warning for closures that capture non-final/shared vars > seems too conservative. The motivation should be not freaking people who > worry about hidden costs, but there's now plenty precedent for that, e.g. > the silent allocations performed by enhanced-for or autoboxing, or much > before, inner classes with their synthetic accessors to outer fields/methods > including private ones. The language spec doesn't require mandatory warnings > for those. I'm fully favorable to an _optional_ warning, that developers can > activate when reviewing performance-critical code, such as the many extra > warnings in the Eclipse compiler or tools like Checkstyle/FindBugs/PMD that > include many detections of potential performance issues. But IMHO, making > this warning of captures enabled by default will "taint" closures as > something expensive, and make it more complex than necessary by requiring > the @Shared or @SuppressWarnings("shared") annotations. (If the warning is > optional, I guess we can omit at least @Shared from the spec.) > > In a secondary note, item 2 of that warning could be "The variable is not > the target of any assignment after the closure is defined", which will avoid > the warning for simple cases like "{ int x; if (a) x = 10 else x = 20; #() > println(x) }" (not all developers would prefer using ?: here to enforce the > initialization-in-declaration). Of course, the "after" in "after the closure > is defined" is not that simple because if the closure is defined inside a > loop, we can't have assignmaets to the variable before the closure > definition but inside the loop; but I guess javac can already do the > necessary flow analysis, should need it for definite assignment. > > > A+ > Osvaldo > > -- > ----------------------------------------------------------------------- > Osvaldo Pinali Doederlein Visionnaire Virtus S/A > osvaldo at visionnaire.com.br http://www.visionnaire.com.br > Arquiteto de Tecnologia +55 (41) 3337-1000 #226 > From neal at gafter.com Fri Nov 20 08:43:54 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 08:43:54 -0800 Subject: Currying and the warning In-Reply-To: References: Message-ID: <15e8b9d20911200843h4e1cb975o574af94db08df27e@mail.gmail.com> On Fri, Nov 20, 2009 at 6:32 AM, Osvaldo Doederlein wrote: > I've just read the new proposal, seems to hit a quite good balance so I > hope this will finally succeed. Some initial comments: > Thanks! The proposal doesn't mention support for any kind of transformation. You've > already explained that MethodHandle doesn't serve as a good basis for > closures, but I'd like both features to be as... close as possible; and for > closures, it makes a lot of sense to support currying because this feature > is highly useful and it wouldn't add any significant complexity (that I can > see) to the language. The Method Reference facility would also allow to > curry a common method, this is a simple combination of two steps (creating a > closure that wraps the method and then currying that closure), but would be > more efficient if defined/implemented as a single operation (so we can just > create a single closure that performs the currying, i.e. passing some fixed > parameters, when delegating to the method). > Can you please suggest a syntax for currying? (Especially one that adds no complexity ;-) The _mandatory_ warning for closures that capture non-final/shared vars > seems too conservative. The motivation should be not freaking people who > worry about hidden costs, but there's now plenty precedent for that, e.g. > the silent allocations performed by enhanced-for or autoboxing, or much > before, inner classes with their synthetic accessors to outer fields/methods > including private ones. The language spec doesn't require mandatory warnings > for those. I'm fully favorable to an _optional_ warning, that developers can > activate when reviewing performance-critical code, such as the many extra > warnings in the Eclipse compiler or tools like Checkstyle/FindBugs/PMD that > include many detections of potential performance issues. But IMHO, making > this warning of captures enabled by default will "taint" closures as > something expensive, and make it more complex than necessary by requiring > the @Shared or @SuppressWarnings("shared") annotations. (If the warning is > optional, I guess we can omit at least @Shared from the spec.) > This warning is not a concession to concerns about the cost model (performance), but based on concerns about semantics in concurrent settings. In a secondary note, item 2 of that warning could be "The variable is not > the target of any assignment after the closure is defined", which will avoid > the warning for simple cases like "{ int x; if (a) x = 10 else x = 20; #() > println(x) }" (not all developers would prefer using ?: here to enforce the > initialization-in-declaration). Of course, the "after" in "after the closure > is defined" is not that simple because if the closure is defined inside a > loop, we can't have assignmaets to the variable before the closure > definition but inside the loop; but I guess javac can already do the > necessary flow analysis, should need it for definite assignment. > I'd love to see your proposed alternative specification. As you say "after the closure is defined" refers to the dynamic semantics of the program, but compile-time diagnostics must be defined in terms of the static semantics. I suspect a specification along the lines you suggest would be very difficult. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091120/68ac787a/attachment.html From opinali at gmail.com Fri Nov 20 09:09:42 2009 From: opinali at gmail.com (Osvaldo Doederlein) Date: Fri, 20 Nov 2009 15:09:42 -0200 Subject: Currying and the warning In-Reply-To: <20091120173943.92473mzzdm1ls2tr@wimap.feld.cvut.cz> References: <20091120173943.92473mzzdm1ls2tr@wimap.feld.cvut.cz> Message-ID: Thanks for the clarification, where is this @Shared annotation specified? It's not in the closures proposal and I admit to have just guessed its meaning, I'm not tracking all of JDK7 developments. A+ Osvaldo 2009/11/20 Zdenek Tronicek > Hi Osvaldo, > > the @Shared annotation says "I am aware that the variable may be accessed > from many threads". It warns you that you may need a synchronization. It is > not about hidden costs. > > Zdenek > -- > Zdenek Tronicek > FIT CTU in Prague > > > Cituji Osvaldo Doederlein : > > > Hi Neal, >> >> I've just read the new proposal, seems to hit a quite good balance so I >> hope >> this will finally succeed. Some initial comments: >> >> The proposal doesn't mention support for any kind of transformation. >> You've >> already explained that MethodHandle doesn't serve as a good basis for >> closures, but I'd like both features to be as... close as possible; and >> for >> closures, it makes a lot of sense to support currying because this feature >> is highly useful and it wouldn't add any significant complexity (that I >> can >> see) to the language. The Method Reference facility would also allow to >> curry a common method, this is a simple combination of two steps (creating >> a >> closure that wraps the method and then currying that closure), but would >> be >> more efficient if defined/implemented as a single operation (so we can >> just >> create a single closure that performs the currying, i.e. passing some >> fixed >> parameters, when delegating to the method). >> >> The _mandatory_ warning for closures that capture non-final/shared vars >> seems too conservative. The motivation should be not freaking people who >> worry about hidden costs, but there's now plenty precedent for that, e.g. >> the silent allocations performed by enhanced-for or autoboxing, or much >> before, inner classes with their synthetic accessors to outer >> fields/methods >> including private ones. The language spec doesn't require mandatory >> warnings >> for those. I'm fully favorable to an _optional_ warning, that developers >> can >> activate when reviewing performance-critical code, such as the many extra >> warnings in the Eclipse compiler or tools like Checkstyle/FindBugs/PMD >> that >> include many detections of potential performance issues. But IMHO, making >> this warning of captures enabled by default will "taint" closures as >> something expensive, and make it more complex than necessary by requiring >> the @Shared or @SuppressWarnings("shared") annotations. (If the warning is >> optional, I guess we can omit at least @Shared from the spec.) >> >> In a secondary note, item 2 of that warning could be "The variable is not >> the target of any assignment after the closure is defined", which will >> avoid >> the warning for simple cases like "{ int x; if (a) x = 10 else x = 20; #() >> println(x) }" (not all developers would prefer using ?: here to enforce >> the >> initialization-in-declaration). Of course, the "after" in "after the >> closure >> is defined" is not that simple because if the closure is defined inside a >> loop, we can't have assignmaets to the variable before the closure >> definition but inside the loop; but I guess javac can already do the >> necessary flow analysis, should need it for definite assignment. >> >> >> A+ >> Osvaldo >> >> -- >> ----------------------------------------------------------------------- >> Osvaldo Pinali Doederlein Visionnaire Virtus S/A >> osvaldo at visionnaire.com.br http://www.visionnaire.com.br >> Arquiteto de Tecnologia +55 (41) 3337-1000 #226 >> >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091120/ee3828a6/attachment-0001.html From neal at gafter.com Fri Nov 20 09:17:29 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 09:17:29 -0800 Subject: Currying and the warning In-Reply-To: References: <20091120173943.92473mzzdm1ls2tr@wimap.feld.cvut.cz> Message-ID: <15e8b9d20911200917t759a7693vf70c6d51f4033f9e@mail.gmail.com> Its specification is just that one mention in the spec. The API spec isn't in the language spec part (perhaps it should be), but it will be something like this: *package java.lang /** See JLS section n.m for the meaning of this annotation. */ @Target(LOCAL_VARIABLE) @Retention(SOURCE) @interface Shared {} * Cheers, Neal On Fri, Nov 20, 2009 at 9:09 AM, Osvaldo Doederlein wrote: > Thanks for the clarification, where is this @Shared annotation specified? > It's not in the closures proposal and I admit to have just guessed its > meaning, I'm not tracking all of JDK7 developments. > > A+ > Osvaldo > > 2009/11/20 Zdenek Tronicek > > Hi Osvaldo, >> >> the @Shared annotation says "I am aware that the variable may be accessed >> from many threads". It warns you that you may need a synchronization. It is >> not about hidden costs. >> >> Zdenek >> -- >> Zdenek Tronicek >> FIT CTU in Prague >> >> >> Cituji Osvaldo Doederlein : >> >> >> Hi Neal, >>> >>> I've just read the new proposal, seems to hit a quite good balance so I >>> hope >>> this will finally succeed. Some initial comments: >>> >>> The proposal doesn't mention support for any kind of transformation. >>> You've >>> already explained that MethodHandle doesn't serve as a good basis for >>> closures, but I'd like both features to be as... close as possible; and >>> for >>> closures, it makes a lot of sense to support currying because this >>> feature >>> is highly useful and it wouldn't add any significant complexity (that I >>> can >>> see) to the language. The Method Reference facility would also allow to >>> curry a common method, this is a simple combination of two steps >>> (creating a >>> closure that wraps the method and then currying that closure), but would >>> be >>> more efficient if defined/implemented as a single operation (so we can >>> just >>> create a single closure that performs the currying, i.e. passing some >>> fixed >>> parameters, when delegating to the method). >>> >>> The _mandatory_ warning for closures that capture non-final/shared vars >>> seems too conservative. The motivation should be not freaking people who >>> worry about hidden costs, but there's now plenty precedent for that, e.g. >>> the silent allocations performed by enhanced-for or autoboxing, or much >>> before, inner classes with their synthetic accessors to outer >>> fields/methods >>> including private ones. The language spec doesn't require mandatory >>> warnings >>> for those. I'm fully favorable to an _optional_ warning, that developers >>> can >>> activate when reviewing performance-critical code, such as the many extra >>> warnings in the Eclipse compiler or tools like Checkstyle/FindBugs/PMD >>> that >>> include many detections of potential performance issues. But IMHO, making >>> this warning of captures enabled by default will "taint" closures as >>> something expensive, and make it more complex than necessary by requiring >>> the @Shared or @SuppressWarnings("shared") annotations. (If the warning >>> is >>> optional, I guess we can omit at least @Shared from the spec.) >>> >>> In a secondary note, item 2 of that warning could be "The variable is not >>> the target of any assignment after the closure is defined", which will >>> avoid >>> the warning for simple cases like "{ int x; if (a) x = 10 else x = 20; >>> #() >>> println(x) }" (not all developers would prefer using ?: here to enforce >>> the >>> initialization-in-declaration). Of course, the "after" in "after the >>> closure >>> is defined" is not that simple because if the closure is defined inside a >>> loop, we can't have assignmaets to the variable before the closure >>> definition but inside the loop; but I guess javac can already do the >>> necessary flow analysis, should need it for definite assignment. >>> >>> >>> A+ >>> Osvaldo >>> >>> -- >>> ----------------------------------------------------------------------- >>> Osvaldo Pinali Doederlein Visionnaire Virtus S/A >>> osvaldo at visionnaire.com.br http://www.visionnaire.com.br >>> Arquiteto de Tecnologia +55 (41) 3337-1000 #226 >>> >>> >> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091120/aa808c68/attachment.html From tronicek at fel.cvut.cz Fri Nov 20 09:18:41 2009 From: tronicek at fel.cvut.cz (Zdenek Tronicek) Date: Fri, 20 Nov 2009 18:18:41 +0100 Subject: Currying and the warning In-Reply-To: References: <20091120173943.92473mzzdm1ls2tr@wimap.feld.cvut.cz> Message-ID: <20091120181841.158567n0zlri714h@wimap.feld.cvut.cz> I think it is not specified anywhere now. But the same annotation was already in the previous proposal. Z. -- Zdenek Tronicek FIT CTU in Prague Cituji Osvaldo Doederlein : > Thanks for the clarification, where is this @Shared annotation specified? > It's not in the closures proposal and I admit to have just guessed its > meaning, I'm not tracking all of JDK7 developments. > > A+ > Osvaldo > > 2009/11/20 Zdenek Tronicek > >> Hi Osvaldo, >> >> the @Shared annotation says "I am aware that the variable may be accessed >> from many threads". It warns you that you may need a synchronization. It is >> not about hidden costs. >> >> Zdenek >> -- >> Zdenek Tronicek >> FIT CTU in Prague >> >> >> Cituji Osvaldo Doederlein : >> >> >> Hi Neal, >>> >>> I've just read the new proposal, seems to hit a quite good balance so I >>> hope >>> this will finally succeed. Some initial comments: >>> >>> The proposal doesn't mention support for any kind of transformation. >>> You've >>> already explained that MethodHandle doesn't serve as a good basis for >>> closures, but I'd like both features to be as... close as possible; and >>> for >>> closures, it makes a lot of sense to support currying because this feature >>> is highly useful and it wouldn't add any significant complexity (that I >>> can >>> see) to the language. The Method Reference facility would also allow to >>> curry a common method, this is a simple combination of two steps (creating >>> a >>> closure that wraps the method and then currying that closure), but would >>> be >>> more efficient if defined/implemented as a single operation (so we can >>> just >>> create a single closure that performs the currying, i.e. passing some >>> fixed >>> parameters, when delegating to the method). >>> >>> The _mandatory_ warning for closures that capture non-final/shared vars >>> seems too conservative. The motivation should be not freaking people who >>> worry about hidden costs, but there's now plenty precedent for that, e.g. >>> the silent allocations performed by enhanced-for or autoboxing, or much >>> before, inner classes with their synthetic accessors to outer >>> fields/methods >>> including private ones. The language spec doesn't require mandatory >>> warnings >>> for those. I'm fully favorable to an _optional_ warning, that developers >>> can >>> activate when reviewing performance-critical code, such as the many extra >>> warnings in the Eclipse compiler or tools like Checkstyle/FindBugs/PMD >>> that >>> include many detections of potential performance issues. But IMHO, making >>> this warning of captures enabled by default will "taint" closures as >>> something expensive, and make it more complex than necessary by requiring >>> the @Shared or @SuppressWarnings("shared") annotations. (If the warning is >>> optional, I guess we can omit at least @Shared from the spec.) >>> >>> In a secondary note, item 2 of that warning could be "The variable is not >>> the target of any assignment after the closure is defined", which will >>> avoid >>> the warning for simple cases like "{ int x; if (a) x = 10 else x = 20; #() >>> println(x) }" (not all developers would prefer using ?: here to enforce >>> the >>> initialization-in-declaration). Of course, the "after" in "after the >>> closure >>> is defined" is not that simple because if the closure is defined inside a >>> loop, we can't have assignmaets to the variable before the closure >>> definition but inside the loop; but I guess javac can already do the >>> necessary flow analysis, should need it for definite assignment. >>> >>> >>> A+ >>> Osvaldo >>> >>> -- >>> ----------------------------------------------------------------------- >>> Osvaldo Pinali Doederlein Visionnaire Virtus S/A >>> osvaldo at visionnaire.com.br http://www.visionnaire.com.br >>> Arquiteto de Tecnologia +55 (41) 3337-1000 #226 >>> >>> >> >> >> > From neal at gafter.com Fri Nov 20 09:24:02 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 09:24:02 -0800 Subject: Currying and the warning In-Reply-To: <20091120181841.158567n0zlri714h@wimap.feld.cvut.cz> References: <20091120173943.92473mzzdm1ls2tr@wimap.feld.cvut.cz> <20091120181841.158567n0zlri714h@wimap.feld.cvut.cz> Message-ID: <15e8b9d20911200924k6fb97f28gdd8b6267557595d4@mail.gmail.com> No, it was not in the previous proposal. It was in the prototype. On Fri, Nov 20, 2009 at 9:18 AM, Zdenek Tronicek wrote: > I think it is not specified anywhere now. But the same annotation was > already in the previous proposal. > > Z. > > -- > Zdenek Tronicek > FIT CTU in Prague > > > Cituji Osvaldo Doederlein : > > Thanks for the clarification, where is this @Shared annotation specified? >> It's not in the closures proposal and I admit to have just guessed its >> meaning, I'm not tracking all of JDK7 developments. >> >> A+ >> Osvaldo >> >> 2009/11/20 Zdenek Tronicek >> >> Hi Osvaldo, >>> >>> the @Shared annotation says "I am aware that the variable may be accessed >>> from many threads". It warns you that you may need a synchronization. It >>> is >>> not about hidden costs. >>> >>> Zdenek >>> -- >>> Zdenek Tronicek >>> FIT CTU in Prague >>> >>> >>> Cituji Osvaldo Doederlein : >>> >>> >>> Hi Neal, >>> >>>> >>>> I've just read the new proposal, seems to hit a quite good balance so I >>>> hope >>>> this will finally succeed. Some initial comments: >>>> >>>> The proposal doesn't mention support for any kind of transformation. >>>> You've >>>> already explained that MethodHandle doesn't serve as a good basis for >>>> closures, but I'd like both features to be as... close as possible; and >>>> for >>>> closures, it makes a lot of sense to support currying because this >>>> feature >>>> is highly useful and it wouldn't add any significant complexity (that I >>>> can >>>> see) to the language. The Method Reference facility would also allow to >>>> curry a common method, this is a simple combination of two steps >>>> (creating >>>> a >>>> closure that wraps the method and then currying that closure), but would >>>> be >>>> more efficient if defined/implemented as a single operation (so we can >>>> just >>>> create a single closure that performs the currying, i.e. passing some >>>> fixed >>>> parameters, when delegating to the method). >>>> >>>> The _mandatory_ warning for closures that capture non-final/shared vars >>>> seems too conservative. The motivation should be not freaking people who >>>> worry about hidden costs, but there's now plenty precedent for that, >>>> e.g. >>>> the silent allocations performed by enhanced-for or autoboxing, or much >>>> before, inner classes with their synthetic accessors to outer >>>> fields/methods >>>> including private ones. The language spec doesn't require mandatory >>>> warnings >>>> for those. I'm fully favorable to an _optional_ warning, that developers >>>> can >>>> activate when reviewing performance-critical code, such as the many >>>> extra >>>> warnings in the Eclipse compiler or tools like Checkstyle/FindBugs/PMD >>>> that >>>> include many detections of potential performance issues. But IMHO, >>>> making >>>> this warning of captures enabled by default will "taint" closures as >>>> something expensive, and make it more complex than necessary by >>>> requiring >>>> the @Shared or @SuppressWarnings("shared") annotations. (If the warning >>>> is >>>> optional, I guess we can omit at least @Shared from the spec.) >>>> >>>> In a secondary note, item 2 of that warning could be "The variable is >>>> not >>>> the target of any assignment after the closure is defined", which will >>>> avoid >>>> the warning for simple cases like "{ int x; if (a) x = 10 else x = 20; >>>> #() >>>> println(x) }" (not all developers would prefer using ?: here to enforce >>>> the >>>> initialization-in-declaration). Of course, the "after" in "after the >>>> closure >>>> is defined" is not that simple because if the closure is defined inside >>>> a >>>> loop, we can't have assignmaets to the variable before the closure >>>> definition but inside the loop; but I guess javac can already do the >>>> necessary flow analysis, should need it for definite assignment. >>>> >>>> >>>> A+ >>>> Osvaldo >>>> >>>> -- >>>> ----------------------------------------------------------------------- >>>> Osvaldo Pinali Doederlein Visionnaire Virtus S/A >>>> osvaldo at visionnaire.com.br http://www.visionnaire.com.br >>>> Arquiteto de Tecnologia +55 (41) 3337-1000 #226 >>>> >>>> >>>> >>> >>> >>> >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091120/ccb0e5bb/attachment.html From neal at gafter.com Fri Nov 20 11:33:22 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 11:33:22 -0800 Subject: [The Java Posse] Re: Closures, too much or too little? In-Reply-To: <4B06E9DA.7020507@ptc.com> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <4B05011D.8030503@tidalwave.it> <4B0535E9.9020309@ptc.com> <4B06E769.9060108@tidalwave.it> <4B06E9DA.7020507@ptc.com> Message-ID: <15e8b9d20911201133j321b0f99n60c3caf4044438c2@mail.gmail.com> On Fri, Nov 20, 2009 at 11:11 AM, Jess Holle wrote: > I am heartened to hear that the spec referenced is not *too* official > yet. I don't have any *big *issues with it -- but on a syntactic level I > just really don't like the use of #. It seems oddly out of place when > compared to closures in other languages -- or in BGGA. > This version is based on CLang, but with # instead of ^. # is used for method references because that is the syntax in javadoc. I would prefer ^ rather than # for function types and lambdas, but the current spec uses # for consistency with method references. Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091120/19463651/attachment-0001.html From neal at gafter.com Fri Nov 20 11:44:25 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 11:44:25 -0800 Subject: Syntax... Message-ID: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> Folks- The 0.6a syntax is based on CLang, but with # instead of ^. I kind of like ^ better, but that's slightly inconsistent with method references, which must use # because (a) that's the javadoc syntax, and (b) it would be ambiguous to use ^. How would you feel about using ^ instead of # for function types and lambdas: *Expression:**ExpressionLambda**Primary:**StatementLambda* *ExpressionLambda *:*^* ( *FormalParametersopt* ) *Expression**StatementLambda*: *^* ( * FormalParametersopt* ) *BlockStatement* *Type:**FunctionType**FunctionType*: *^ **Type* ( *TypeListopt** )* *FunctionThrowsopt* *TypeList:**Type Type* , *TypeList**FunctionThrows*:throws *FunctionExceptionTypeList* * FunctionExceptionTypeList:* *ExceptionType FunctionExceptionTypeList | ExceptionType * *Primary:**MethodReference** MethodReference:**Primary *# *TypeArgumentsopt Identifier* ( *TypeListopt* ) Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091120/0ebc6257/attachment.html From pbenedict at apache.org Fri Nov 20 12:21:28 2009 From: pbenedict at apache.org (Paul Benedict) Date: Fri, 20 Nov 2009 14:21:28 -0600 Subject: Syntax... In-Reply-To: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> Message-ID: Neal, If anything, I would tell the JSR-292 folks to use ^ over # for their exotic identifiers ;-) But in terms of the closures, I think # is kind of the universal identifier of a method .. especially since I saw that method literals (using #) are also in JDK 7. Paul On Fri, Nov 20, 2009 at 1:44 PM, Neal Gafter wrote: > Folks- > > The 0.6a syntax is based on CLang, but with # instead of ^.? I kind of like > ^ better, but that's slightly inconsistent with method references, which > must use # because (a) that's the javadoc syntax, and (b) it would be > ambiguous to use ^. > > How would you feel about using ^ instead of # for function types and > lambdas: From neal at gafter.com Fri Nov 20 12:55:17 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 12:55:17 -0800 Subject: Syntax... In-Reply-To: References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> Message-ID: <15e8b9d20911201255k6bcc2492u1898dfd167c029d6@mail.gmail.com> On Fri, Nov 20, 2009 at 12:21 PM, Paul Benedict wrote: > If anything, I would tell the JSR-292 folks to use ^ over # for their > exotic identifiers ;-) But in terms of the closures, I think # is kind > of the universal identifier of a method .. especially since I saw that > method literals (using #) are also in JDK 7. > Exotic identifiers are now in the hands of project Coin, not 292. I hadn't heard that method literals are to be in JDK7. I've had no feedback from Sun on the 0.6a spec. I see your point about thinking of "#" as an anonymous name, but I'd suggest we avoid calling them methods. Lambdas are functions, not methods. Specifically, names are interpreted from their lexical scope, not in the scope of "their class" (for example, "this"). Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091120/5e3723d4/attachment.html From neal at gafter.com Fri Nov 20 12:59:09 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 12:59:09 -0800 Subject: Syntax... In-Reply-To: <15e8b9d20911201255k6bcc2492u1898dfd167c029d6@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <15e8b9d20911201255k6bcc2492u1898dfd167c029d6@mail.gmail.com> Message-ID: <15e8b9d20911201259j2f0565fftad819e5c17103fa7@mail.gmail.com> On Fri, Nov 20, 2009 at 12:55 PM, Neal Gafter wrote: > On Fri, Nov 20, 2009 at 12:21 PM, Paul Benedict wrote: > >> If anything, I would tell the JSR-292 folks to use ^ over # for their >> exotic identifiers ;-) But in terms of the closures, I think # is kind >> of the universal identifier of a method .. especially since I saw that >> method literals (using #) are also in JDK 7. >> > > I've had no feedback from Sun on the 0.6a spec. > Correction: no feedback other than Gosling. His comment (October 22) was that "I'm not bothered by the restrictions in your compromise proposal, but I'd also like to think it isn't necessary to go there." Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091120/a7985bb4/attachment.html From forax at univ-mlv.fr Fri Nov 20 15:00:35 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 21 Nov 2009 00:00:35 +0100 Subject: Syntax... In-Reply-To: References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> Message-ID: <4B071F93.9010906@univ-mlv.fr> Le 20/11/2009 21:21, Paul Benedict a ?crit : > Neal, > > If anything, I would tell the JSR-292 folks to use ^ over # for their > exotic identifiers ;-) But in terms of the closures, I think # is kind > of the universal identifier of a method .. especially since I saw that > method literals (using #) are also in JDK 7. > > Paul > Hi Paul, Exotic identifiers start with #" and not only #, so there is no problem, the lexer is able to handle that. R?mi > On Fri, Nov 20, 2009 at 1:44 PM, Neal Gafter wrote: > >> Folks- >> >> The 0.6a syntax is based on CLang, but with # instead of ^. I kind of like >> ^ better, but that's slightly inconsistent with method references, which >> must use # because (a) that's the javadoc syntax, and (b) it would be >> ambiguous to use ^. >> >> How would you feel about using ^ instead of # for function types and >> lambdas: >> From forax at univ-mlv.fr Fri Nov 20 15:05:02 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 21 Nov 2009 00:05:02 +0100 Subject: Syntax... In-Reply-To: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> Message-ID: <4B07209E.50508@univ-mlv.fr> Le 20/11/2009 20:44, Neal Gafter a ?crit : > Folks- > > The 0.6a syntax is based on CLang > , > but with # instead of ^. I kind of like ^ better, but that's slightly > inconsistent with method references, which must use # because (a) > that's the javadoc syntax, and (b) it would be ambiguous to use ^. I vote for any syntax that clearly differentiate between lambda and function type. R?mi > > How would you feel about using ^ instead of # for function types and > lambdas: > > /Expression:/ > /ExpressionLambda/ > /Primary:/ > /StatementLambda/ > /ExpressionLambda/: > *^* ( /FormalParameters_opt / ) /Expression/ > /StatementLambda/: > *^* ( /FormalParameters_opt / ) /BlockStatement/ > > /Type:/ > /FunctionType/ > /FunctionType/: > *^ */Type/ ( /TypeList_opt /* )* /FunctionThrows_opt / > /TypeList:/ > /Type > Type/ , /TypeList/ > /FunctionThrows/: > throws /FunctionExceptionTypeList/ > /FunctionExceptionTypeList:/ > /ExceptionType > FunctionExceptionTypeList | ExceptionType / > > /Primary:/ > /MethodReference/ > /MethodReference:/ > /Primary /# /TypeArguments_opt Identifier/ ( /TypeList_opt / ) > > Cheers, > Neal > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/6949be66/attachment.html From neal at gafter.com Fri Nov 20 14:51:06 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 14:51:06 -0800 Subject: Syntax... In-Reply-To: <4B07209E.50508@univ-mlv.fr> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B07209E.50508@univ-mlv.fr> Message-ID: <15e8b9d20911201451g1af9f0b6v9c15cfcc28b68cd6@mail.gmail.com> On Fri, Nov 20, 2009 at 3:05 PM, R?mi Forax wrote: > Le 20/11/2009 20:44, Neal Gafter a ?crit : > > The 0.6a syntax is based on CLang, > but with # instead of ^. I kind of like ^ better, but that's slightly > inconsistent with method references, which must use # because (a) that's the > javadoc syntax, and (b) it would be ambiguous to use ^. > > > I vote for any syntax that clearly differentiate between lambda and > function type. > Remi- All of these syntax forms do. Either there's a type between the # (or ^) and the open paren (for a function type) or there isn't (for a lambda). Is that clear enough for your taste? -Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091120/39623ac3/attachment.html From forax at univ-mlv.fr Fri Nov 20 15:21:22 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 21 Nov 2009 00:21:22 +0100 Subject: Syntax... In-Reply-To: <15e8b9d20911201451g1af9f0b6v9c15cfcc28b68cd6@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B07209E.50508@univ-mlv.fr> <15e8b9d20911201451g1af9f0b6v9c15cfcc28b68cd6@mail.gmail.com> Message-ID: <4B072472.50503@univ-mlv.fr> Le 20/11/2009 23:51, Neal Gafter a ?crit : > On Fri, Nov 20, 2009 at 3:05 PM, R?mi Forax > wrote: > > Le 20/11/2009 20:44, Neal Gafter a ?crit : >> The 0.6a syntax is based on CLang >> , >> but with # instead of ^. I kind of like ^ better, but that's >> slightly inconsistent with method references, which must use # >> because (a) that's the javadoc syntax, and (b) it would be >> ambiguous to use ^. > > I vote for any syntax that clearly differentiate between lambda > and function type. > > > Remi- > > All of these syntax forms do. Either there's a type between the # (or > ^) and the open paren (for a function type) or there isn't (for a > lambda). Is that clear enough for your taste? > > -Neal Sorry, I was not clear. I am able to parse the current syntax and any parser will be able too, but I am not sure everyone will be able to do the same. One thing I have observed when teaching C is that the first problem when explaining pointer was the C syntax. This syntax use * when you declare a pointer type and * when you want to dereference a pointer variable. This syntax create unnecessary confusion. If the syntax of closure use a symbol for lambda and another for function type, I will be happy. R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/b87f4820/attachment.html From neal at gafter.com Fri Nov 20 15:18:30 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 15:18:30 -0800 Subject: Syntax... In-Reply-To: <4B072472.50503@univ-mlv.fr> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B07209E.50508@univ-mlv.fr> <15e8b9d20911201451g1af9f0b6v9c15cfcc28b68cd6@mail.gmail.com> <4B072472.50503@univ-mlv.fr> Message-ID: <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> On Fri, Nov 20, 2009 at 3:21 PM, R?mi Forax wrote: > Sorry, I was not clear. > I am able to parse the current syntax and any parser will be able too, > but I am not sure everyone will be able to do the same. > > One thing I have observed when teaching C is that the first problem when > explaining pointer was the C syntax. > This syntax use * when you declare a pointer type and * when you want to > dereference > a pointer variable. This syntax create unnecessary confusion. > > If the syntax of closure use a symbol for lambda and another for function > type, > I will be happy. > So you would prefer, for example, to use # for one of them and ^ for the other? If so, I think it must be # for the lambda (because method references make closures, too) and ^ for the function type. *^int(int) plusOne = #(int x)x+1; * I wonder if a context-sensitive keyword would work? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091120/6116a178/attachment-0001.html From pbenedict at apache.org Fri Nov 20 16:32:31 2009 From: pbenedict at apache.org (Paul Benedict) Date: Fri, 20 Nov 2009 18:32:31 -0600 Subject: Syntax... In-Reply-To: <4B071F93.9010906@univ-mlv.fr> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B071F93.9010906@univ-mlv.fr> Message-ID: Yes, I know it's #", but that doesn't matter much to me. I see the pound sign and think it's the ugliest string escape syntax in existence. There, I said it :-) On Fri, Nov 20, 2009 at 5:00 PM, R?mi Forax wrote: > Le 20/11/2009 21:21, Paul Benedict a ?crit : >> >> Neal, >> >> If anything, I would tell the JSR-292 folks to use ^ over # for their >> exotic identifiers ;-) But in terms of the closures, I think # is kind >> of the universal identifier of a method .. especially since I saw that >> method literals (using #) are also in JDK 7. >> >> Paul >> > > Hi Paul, > Exotic identifiers start with #" and not only #, so there is no problem, > the lexer is able to handle that. > > R?mi > >> On Fri, Nov 20, 2009 at 1:44 PM, Neal Gafter ?wrote: >> >>> >>> Folks- >>> >>> The 0.6a syntax is based on CLang, but with # instead of ^. ?I kind of >>> like >>> ^ better, but that's slightly inconsistent with method references, which >>> must use # because (a) that's the javadoc syntax, and (b) it would be >>> ambiguous to use ^. >>> >>> How would you feel about using ^ instead of # for function types and >>> lambdas: >>> > > From pbenedict at apache.org Fri Nov 20 16:33:21 2009 From: pbenedict at apache.org (Paul Benedict) Date: Fri, 20 Nov 2009 18:33:21 -0600 Subject: Syntax... In-Reply-To: <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B07209E.50508@univ-mlv.fr> <15e8b9d20911201451g1af9f0b6v9c15cfcc28b68cd6@mail.gmail.com> <4B072472.50503@univ-mlv.fr> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> Message-ID: You could use # and ## . Is that palatable? On Fri, Nov 20, 2009 at 5:18 PM, Neal Gafter wrote: > On Fri, Nov 20, 2009 at 3:21 PM, R?mi Forax wrote: >> >> Sorry, I was not clear. >> I am able to parse the current syntax and any parser will be able too, >> but I am not sure everyone will be able to do the same. >> >> One thing I have observed when teaching C is that the first problem when >> explaining pointer was the C syntax. >> This syntax use * when you declare a pointer type and * when you want to >> dereference >> a pointer variable. This syntax create unnecessary confusion. >> >> If the syntax of closure use a symbol for lambda and another for function >> type, >> I will be happy. > > So you would prefer, for example, to use # for one of them and ^ for the > other?? If so, I think it must be # for the lambda (because method > references make closures, too) and ^ for the function type. > > ^int(int) plusOne = #(int x)x+1; > > I wonder if a context-sensitive keyword would work? > From forax at univ-mlv.fr Fri Nov 20 17:54:33 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 21 Nov 2009 02:54:33 +0100 Subject: Syntax... In-Reply-To: <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B07209E.50508@univ-mlv.fr> <15e8b9d20911201451g1af9f0b6v9c15cfcc28b68cd6@mail.gmail.com> <4B072472.50503@univ-mlv.fr> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> Message-ID: <4B074859.2050107@univ-mlv.fr> Le 21/11/2009 00:18, Neal Gafter a ?crit : > On Fri, Nov 20, 2009 at 3:21 PM, R?mi Forax > wrote: > > Sorry, I was not clear. > I am able to parse the current syntax and any parser will be able too, > but I am not sure everyone will be able to do the same. > > One thing I have observed when teaching C is that the first > problem when explaining pointer was the C syntax. > This syntax use * when you declare a pointer type and * when you > want to dereference > a pointer variable. This syntax create unnecessary confusion. > > If the syntax of closure use a symbol for lambda and another for > function type, > I will be happy. > > > So you would prefer, for example, to use # for one of them and ^ for > the other? If so, I think it must be # for the lambda (because method > references make closures, too) and ^ for the function type. > > *^int(int) plusOne = #(int x)x+1; > * > > I wonder if a context-sensitive keyword would work? A context sensitive keyword for function type seems easy, something like *fun int(int) plusOne = #(int x)x+1; *Because lambda are expression having a keyword for lambda, it seems less possible, it can generate conflicts with method call.* **^int() one = lambda () 1;* R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/86d9b9b0/attachment.html From vladimir.kirichenko at gmail.com Fri Nov 20 17:44:36 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Sat, 21 Nov 2009 03:44:36 +0200 Subject: Syntax... In-Reply-To: <4B074859.2050107@univ-mlv.fr> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B07209E.50508@univ-mlv.fr> <15e8b9d20911201451g1af9f0b6v9c15cfcc28b68cd6@mail.gmail.com> <4B072472.50503@univ-mlv.fr> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> <4B074859.2050107@univ-mlv.fr> Message-ID: <4B074604.7090601@gmail.com> R?mi Forax wrote: > A context sensitive keyword for function type seems easy, something like > fun int(int) plusOne = #(int x)x+1; It has gone so far that this: fun int plusOne(int x) = x + 1; does not seem an insane idea. It also doesn't contain double type declaration. -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/e33c3501/attachment.bin From vladimir.kirichenko at gmail.com Fri Nov 20 18:05:39 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Sat, 21 Nov 2009 04:05:39 +0200 Subject: Syntax... In-Reply-To: <4B074604.7090601@gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B07209E.50508@univ-mlv.fr> <15e8b9d20911201451g1af9f0b6v9c15cfcc28b68cd6@mail.gmail.com> <4B072472.50503@univ-mlv.fr> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> <4B074859.2050107@univ-mlv.fr> <4B074604.7090601@gmail.com> Message-ID: <4B074AF3.9090504@gmail.com> Vladimir Kirichenko wrote: > It has gone so far that this: > > fun int plusOne(int x) = x + 1; > > does not seem an insane idea. It also doesn't contain double type > declaration. Or lets go more wild: named function/closure/lambda: fun int plusOne(int x) => x + 1; anonymous: x.aMethod(fun int(int x) => x + 1); type decl: void aMethod( fun int f(int x) ) {....f(1)... } -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/9552c98f/attachment.bin From vladimir.kirichenko at gmail.com Fri Nov 20 18:14:44 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Sat, 21 Nov 2009 04:14:44 +0200 Subject: Syntax... In-Reply-To: <4B074AF3.9090504@gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B07209E.50508@univ-mlv.fr> <15e8b9d20911201451g1af9f0b6v9c15cfcc28b68cd6@mail.gmail.com> <4B072472.50503@univ-mlv.fr> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> <4B074859.2050107@univ-mlv.fr> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> Message-ID: <4B074D14.6050005@gmail.com> Vladimir Kirichenko wrote: > Or lets go more wild: > > named function/closure/lambda: > > fun int plusOne(int x) => x + 1; > > anonymous: > > x.aMethod(fun int(int x) => x + 1); > > type decl: > > void aMethod( fun int f(int x) ) {....f(1)... } Assignment: fun int plusOne(int x) => x + 1; fun int inc(int x) = plusOne; -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/5e95a38b/attachment.bin From neal at gafter.com Fri Nov 20 21:52:10 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 21:52:10 -0800 Subject: Syntax... In-Reply-To: <4B074D14.6050005@gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B07209E.50508@univ-mlv.fr> <15e8b9d20911201451g1af9f0b6v9c15cfcc28b68cd6@mail.gmail.com> <4B072472.50503@univ-mlv.fr> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> <4B074859.2050107@univ-mlv.fr> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> Message-ID: <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> I can't quite infer the structure of the language from your examples. Can you please show the syntax grammar (BNF) for this suggestion? On Fri, Nov 20, 2009 at 6:14 PM, Vladimir Kirichenko < vladimir.kirichenko at gmail.com> wrote: > Vladimir Kirichenko wrote: > > Or lets go more wild: > > > > named function/closure/lambda: > > > > fun int plusOne(int x) => x + 1; > > > > anonymous: > > > > x.aMethod(fun int(int x) => x + 1); > > > > type decl: > > > > void aMethod( fun int f(int x) ) {....f(1)... } > > Assignment: > > fun int plusOne(int x) => x + 1; > > fun int inc(int x) = plusOne; > > -- > Best Regards, > Vladimir Kirichenko > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091120/17fdf3c1/attachment.html From jp at hapra.at Sat Nov 21 01:48:22 2009 From: jp at hapra.at (Jakob Praher) Date: Sat, 21 Nov 2009 10:48:22 +0100 Subject: Informal: Syntax from an outside position Message-ID: <4B07B766.40303@hapra.at> Hi all, disclaimer: I did not provide complete EBNF, I just want to get this ideas out and hope for feedback. For me the biggest motivations for designing syntacic changes is to make it _orthogonal_ to other java language constructs. Therefore IMHO one should differentiate between: * function handles as first class type * creating closures For function handles I would just use all the argument types that make up the funciton interface: void bar( int (String,byte[]) f ) { f("test", new byte[] {...}) } IMHO I would not differntiate the type of a closure from the type of a function handle. I think in languages like C++, C the alternative syntax is mainly because of memory management issues? Is there any other reason. E.g. if some static method (e.g. function) does already implement some functionality I would not have to use some kind of closure construction facilty, just pass this static method? For creating closures I would use the new keyword for introducing them with "new" "(" FormalParameters_opt ")" BlockStatement . "new" "(" FormalParameters_opt ")" Expression . for example: void foo() { int (String, byte[] f) closure = new (String name, byte[] data) { System.out.println(name); return date.length; } } when doing this with the lock example, it would look like: withLock(lock, new() { System.out.println("Hello"); }); Thanks for your feedback Jakob From tronicek at fit.cvut.cz Sat Nov 21 02:09:46 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Sat, 21 Nov 2009 11:09:46 +0100 Subject: Why a new type parameter for exception transparency? Message-ID: Hi, [Neal, the reference to closures-v07a.html on javac.info does not work.] Using the declaration from the proposal public static T withLock(Lock lock, #T() throws E block) throws E { lock.lock(); try { return block.invoke(); } finally { lock.unlock(); } } I understand we can use withLock as follows: withLock(lock, #() { Thread.sleep(1000); // throws InterruptedException new FileInputStream("x").close(); // throws FileNotFoundException and IOException }); and the compiler infers that E is InterruptedException or IOException and will force us to catch both of them. This is why we need the throws keyword. In accordance with the proposal I use "or" (InterruptedException or IOException) but more logical seems to be "and", as this is the compile time checking. The compiler must infer that the method may throw InterruptedException AND IOException. [The NumberFormatException used in the proposal is not a good choice because it is a runtime exception.] So far, so good. Now, let's use the throws keyword in a method declaration: public void throwit(boolean b, E e1, E e2) throws E { if (b) throw e1; else throw e2; } and call it: throwit(b, new InterruptedException(), new IOException()); If E is inferred the same way, does it mean that e1 and e2 are of different types? Does it make sense to use E as a type (except that it can be thrown from the method)? Zdenek -- Zdenek Tronicek FIT CTU in Prague Cituji Paul Benedict : > Neal, > >> Perhaps another approach would be to just take the hint from the >> fact that the type parameter's bound is a checked exception type. That is >> not strictly backward source-compatible, but it might be compatible enough >> to allow us to simplify the syntax as you suggest. > > You read my mind! I was hoping you could infer it. > > Anyway, if we take closures out of the discussion, I imagine the new > type is usable outside of closures, correct? For example: > > public void throwit(E e) throws E { > throw e; > } > > But really, the compiler should know what to do just with this: > > public void throwit(E e) throws E { > throw e; > } > > I might be missing something, but is there any important distinction > between the two? > > Paul > From tronicek at fit.cvut.cz Sat Nov 21 04:23:06 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Sat, 21 Nov 2009 13:23:06 +0100 Subject: Syntax... In-Reply-To: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> Message-ID: <1af45fa312bda7b03856555e3848efed.squirrel@imap.fit.cvut.cz> Hi, I do not have any strong argument neither for # nor for ^ but I, personally, prefer # (for both, function types and lambdas). Why? ^ is an operator and thus # seems to be more readable. In C, the situation is different: # is a preprocessor thing and so ^ is probably better there. Zdenek -- Zdenek Tronicek FIT CTU in Prague Neal Gafter napsal(a): > Folks- > > The 0.6a syntax is based on > CLang, > but with # instead of ^. I kind of like ^ better, but that's slightly > inconsistent with method references, which must use # because (a) that's > the > javadoc syntax, and (b) it would be ambiguous to use ^. > > How would you feel about using ^ instead of # for function types and > lambdas: > *Expression:**ExpressionLambda**Primary:**StatementLambda* > *ExpressionLambda > *:*^* ( *FormalParametersopt* ) *Expression**StatementLambda*: *^* ( * > FormalParametersopt* ) *BlockStatement* > *Type:**FunctionType**FunctionType*: > *^ **Type* ( *TypeListopt** )* *FunctionThrowsopt* *TypeList:**Type > Type* , *TypeList**FunctionThrows*:throws *FunctionExceptionTypeList* * > FunctionExceptionTypeList:* *ExceptionType > FunctionExceptionTypeList | ExceptionType * *Primary:**MethodReference** > MethodReference:**Primary *# *TypeArgumentsopt Identifier* ( *TypeListopt* > ) > Cheers, > Neal > From jp at hapra.at Sat Nov 21 05:21:41 2009 From: jp at hapra.at (Jakob Praher) Date: Sat, 21 Nov 2009 14:21:41 +0100 Subject: Syntax... In-Reply-To: <1af45fa312bda7b03856555e3848efed.squirrel@imap.fit.cvut.cz> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <1af45fa312bda7b03856555e3848efed.squirrel@imap.fit.cvut.cz> Message-ID: <4B07E965.1070907@hapra.at> Hi all, why do we need something like #, ^ for defining the function type at all? IMHO in Java the identifier space has no function type already, since this is a novelity, compared with C/C++ block/lambda concepts build on top of existing function pointers. This implies the opportunity to introduce a clean function/lambda type identifier, which would also leverage a common representation. I would not introduce new operators like => or # if it is not absolutely necessary. Java style would be to use something more readable IMHO. Introducing closures with new would have the charme of beeing similar to anonymous inner class instantiation. e.g. File f = new File("."); File[] textfiles = f.listFiles( new FileFilter() { public boolean accept(File pathname) { return pathname.endswith(".txt"); }); which would be translated to: File f = new FIle("."); File[] textfiles = f.listFiles( new (File pathname) { pathname.endswith("txt") } ); "new" is surely debatable and one could think about omitting it.... Then one could also think about more scala like: f.listFiles (File pathanme) { return pathname.endswith("txt") ; } If the only argument to a method is a closure, one could leave out the parenthesis and it looks much more readable IMHO. Surely this would be a bigger burdon to the compiler, but even with the parenthesis around it would be readable, no? f.listFiles( (File pathanme) { return pathname.endswith("txt") ; }); Just my 2 cents. -- Jakob tronicek at fit.cvut.cz schrieb: > Hi, > > I do not have any strong argument neither for # nor for ^ but I, > personally, prefer # (for both, function types and lambdas). Why? > ^ is an operator and thus # seems to be more readable. > In C, the situation is different: # is a preprocessor thing and so ^ is > probably better there. > > Zdenek > From jp at hapra.at Sat Nov 21 07:11:33 2009 From: jp at hapra.at (Jakob Praher) Date: Sat, 21 Nov 2009 16:11:33 +0100 Subject: Syntax... In-Reply-To: <4B07E965.1070907@hapra.at> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <1af45fa312bda7b03856555e3848efed.squirrel@imap.fit.cvut.cz> <4B07E965.1070907@hapra.at> Message-ID: <4B080325.2050903@hapra.at> Sorry for the noise again, another important point is that I would not separate expressions form statements. This something which should be adressed by the Java language on a larger scale. Too many different ways are not consistent and introduce headaches for people experienced with Java w/o closures. E.g. Why can I write f.listFiles( #(File pathname) pathname.getName().endswith(".txt") ) while not public static bool accept(File pathname) pathname.getName().endswith(".txt") IMHO it is much more important to beeing able to write something like: f.listFiles(File patname) { return pathname.getName().endswith("txt"); } I would stick with return for the current change and address the statement/expression dichotomy on a larger picture. Also what one sees with "pathname.getName().endswith(...)" above is that extreme consiceness is not the main goal of Java while consistency I think is(One way to do things). So my point: In the end a closure/lambda/method should be consistent representation of executable code. -- Jakob Jakob Praher schrieb: > Hi all, > > why do we need something like #, ^ for defining the function type at all? > > IMHO in Java the identifier space has no function type already, since > this is a novelity, compared with C/C++ block/lambda concepts build on > top of existing function pointers. This implies the opportunity to > introduce a clean function/lambda type identifier, which would also > leverage a common representation. > > I would not introduce new operators like => or # if it is not > absolutely necessary. Java style would be to use something more > readable IMHO. > Introducing closures with new would have the charme of beeing similar > to anonymous inner class instantiation. > > e.g. > > File f = new File("."); > File[] textfiles = f.listFiles( new FileFilter() { > public boolean accept(File pathname) { > return pathname.endswith(".txt"); > }); > > which would be translated to: > > File f = new FIle("."); > File[] textfiles = f.listFiles( new (File pathname) { > pathname.endswith("txt") } ); > > "new" is surely debatable and one could think about omitting it.... > Then one could also think about more scala like: > > f.listFiles (File pathanme) { > return pathname.endswith("txt") ; > } > > If the only argument to a method is a closure, one could leave out the > parenthesis and it looks much more readable IMHO. > Surely this would be a bigger burdon to the compiler, but even with > the parenthesis around it would be readable, no? > > f.listFiles( (File pathanme) { > return pathname.endswith("txt") ; > }); > > Just my 2 cents. > -- Jakob > > tronicek at fit.cvut.cz schrieb: >> Hi, >> >> I do not have any strong argument neither for # nor for ^ but I, >> personally, prefer # (for both, function types and lambdas). Why? >> ^ is an operator and thus # seems to be more readable. >> In C, the situation is different: # is a preprocessor thing and so ^ is >> probably better there. >> >> Zdenek >> > > From neal at gafter.com Sat Nov 21 08:04:52 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 21 Nov 2009 08:04:52 -0800 Subject: Why a new type parameter for exception transparency? In-Reply-To: References: Message-ID: <15e8b9d20911210804s62cafa9cq92b288a74c93de@mail.gmail.com> Zdenek- In this case E is a disjunction type, and the variables e1 and e2 are of the disjunction type, which means either of them can be either of the two types at runtime. Cheers, Neal On Sat, Nov 21, 2009 at 2:09 AM, wrote: > Hi, > > [Neal, the reference to closures-v07a.html on javac.info does not work.] > > Using the declaration from the proposal > > public static > T withLock(Lock lock, #T() throws E block) throws E { > lock.lock(); > try { > return block.invoke(); > } finally { > lock.unlock(); > } > } > > I understand we can use withLock as follows: > > withLock(lock, #() { > Thread.sleep(1000); // throws InterruptedException > new FileInputStream("x").close(); // throws FileNotFoundException and > IOException > }); > > and the compiler infers that E is InterruptedException or IOException and > will force us to catch both of them. This is why we need the throws > keyword. > In accordance with the proposal I use "or" (InterruptedException or > IOException) but more logical seems to be "and", as this is the compile > time checking. The compiler must infer that the method may throw > InterruptedException AND IOException. > [The NumberFormatException used in the proposal is not a good choice > because it is a runtime exception.] > > So far, so good. Now, let's use the throws keyword in a method declaration: > > public void throwit(boolean b, E e1, E e2) > throws E { > if (b) throw e1; > else throw e2; > } > > and call it: > > throwit(b, new InterruptedException(), new IOException()); > > If E is inferred the same way, does it mean that e1 and e2 are of > different types? > Does it make sense to use E as a type (except that it can be thrown from > the method)? > > Zdenek > -- > Zdenek Tronicek > FIT CTU in Prague > > > Cituji Paul Benedict : > > > Neal, > > > >> Perhaps another approach would be to just take the hint from the > >> fact that the type parameter's bound is a checked exception type. That > is > >> not strictly backward source-compatible, but it might be compatible > enough > >> to allow us to simplify the syntax as you suggest. > > > > You read my mind! I was hoping you could infer it. > > > > Anyway, if we take closures out of the discussion, I imagine the new > > type is usable outside of closures, correct? For example: > > > > public void throwit(E e) throws E { > > throw e; > > } > > > > But really, the compiler should know what to do just with this: > > > > public void throwit(E e) throws E { > > throw e; > > } > > > > I might be missing something, but is there any important distinction > > between the two? > > > > Paul > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/f11b2ffd/attachment.html From neal at gafter.com Sat Nov 21 08:10:56 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 21 Nov 2009 08:10:56 -0800 Subject: Syntax... In-Reply-To: <4B07E965.1070907@hapra.at> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <1af45fa312bda7b03856555e3848efed.squirrel@imap.fit.cvut.cz> <4B07E965.1070907@hapra.at> Message-ID: <15e8b9d20911210810l7f83687duc21800e320acd844@mail.gmail.com> On Sat, Nov 21, 2009 at 5:21 AM, Jakob Praher wrote: > File f = new FIle("."); > File[] textfiles = f.listFiles( new (File pathname) { > pathname.endswith("txt") } ); > The problem with "new" is that a lambda expression should not require the creation of a new object at each evaluation. If the lambda captures no state from the enclosing context, the compiler should be free to allocate it statically. > "new" is surely debatable and one could think about omitting it.... Then > one could also think about more scala like: > > f.listFiles (File pathanme) { > return pathname.endswith("txt") ; > } > I don't believe that can be retrofitted onto the Java language without syntactic ambiguity. > If the only argument to a method is a closure, one could leave out the > parenthesis and it looks much more readable IMHO. > Surely this would be a bigger burdon to the compiler, but even with the > parenthesis around it would be readable, no? > > f.listFiles( (File pathanme) { > return pathname.endswith("txt") ; > }); > Yes, this was what we had back in BGGA version 1. We'd really like to eliminate the "return" boilerplate. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/3ec95a71/attachment.html From jp at hapra.at Sat Nov 21 09:18:15 2009 From: jp at hapra.at (Jakob Praher) Date: Sat, 21 Nov 2009 18:18:15 +0100 Subject: Syntax... In-Reply-To: <15e8b9d20911210810l7f83687duc21800e320acd844@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <1af45fa312bda7b03856555e3848efed.squirrel@imap.fit.cvut.cz> <4B07E965.1070907@hapra.at> <15e8b9d20911210810l7f83687duc21800e320acd844@mail.gmail.com> Message-ID: <4B0820D7.1040809@hapra.at> Hi, thanks for your reply. Neal Gafter schrieb: > On Sat, Nov 21, 2009 at 5:21 AM, Jakob Praher > wrote: > > File f = new FIle("."); > File[] textfiles = f.listFiles( new (File pathname) { > pathname.endswith("txt") } ); > > > The problem with "new" is that a lambda expression should not require > the creation of a new object at each evaluation. If the lambda > captures no state from the enclosing context, the compiler should be > free to allocate it statically. Ok. From this point of view it makes sense. On the other hand there is not always a 1:1 correspondance in Java regarding optimizability and syntax. E.g. virtual inlining at runtime. From a conceptional point of view it is a late bound method, actually it is inlined at runtime. My point here was that new is a common concept for creating almost everything in Java, so people are famliar to use it. > > > "new" is surely debatable and one could think about omitting > it.... Then one could also think about more scala like: > > f.listFiles (File pathanme) { > return pathname.endswith("txt") ; > } > > > I don't believe that can be retrofitted onto the Java language without > syntactic ambiguity. Hmm. Personally after thinking over it I see some problems regarding expressiveness, especially if the existing method names are not changed. Here listFiles should then be called filterFilesBy or something similar. Syntaxwise I have played with the MethodInvocation production/nonterminals. Since the MethodInvocation expression has to be followed by a semicolon it could even be differentiated from nested blocks following a method call. But one would maybe have to add a semicolon after the RPAR. Yet I have not had time to think about every corner case. f.listFiles(File p); {int x; ... } vs . f.listFiles(File p) { int x; ... }; > If the only argument to a method is a closure, one could leave out > the parenthesis and it looks much more readable IMHO. > Surely this would be a bigger burdon to the compiler, but even > with the parenthesis around it would be readable, no? > > f.listFiles( (File pathanme) { > return pathname.endswith("txt") ; > }); > > > Yes, this was what we had back in BGGA version 1. We'd really like to > eliminate the "return" boilerplate. My point is here that this is something for the Java language to capture generally (for all statements/expressions), don't you think? Why did you change to # for introducing function types and creating closures? For instnace if one translates Ruby code (for selecting over collections[1]) to Java: int[] result = x.select( (int c) { return c % 2} ); I am not sure if it is really necessary to omit the outer parenthesis: int[] result = x.select (int c) {return c % 2 == 0; } But I think having to write: int[] result = x.select( #(int c) c % 2 == 0) is harder to read. Don't you think? If one looks at other languages built for closures/blocks/anonymous functions, there is also a mixed way of representing it and almost always a dichotomy. AFAIK in Scala: afunc {...} is only allowed if it the parameter of afunc has no formal arguments. Otherwise one uses: afunc (a :T1, b: T2) => { ... } which is also a kind of strange, yet less since => is here the offiical way to represent functions as types. On the other hand it breaks with def. Since def is used like: def myfunc (a: T1, b: T2) { ... } not def myfunc = (a: T1, b: T2 ) => { ... } or similar. Here IMHO scheme/lisp's consistency is desirable: (define x (lambda (a b) ...)) is written identically to: (afunc (lambda (a b ) ...) ) I propably would stick with POLS (principle of least surprise) for Java. IF closures are really used heavily I think having to ways of writing code rises the burden on the reader of the language. Thanks Jakob [1] http://ruby-doc.org/core/classes/Enumerable.html#M003125 From neal at gafter.com Sat Nov 21 09:28:00 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 21 Nov 2009 09:28:00 -0800 Subject: Syntax... In-Reply-To: <4B0820D7.1040809@hapra.at> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <1af45fa312bda7b03856555e3848efed.squirrel@imap.fit.cvut.cz> <4B07E965.1070907@hapra.at> <15e8b9d20911210810l7f83687duc21800e320acd844@mail.gmail.com> <4B0820D7.1040809@hapra.at> Message-ID: <15e8b9d20911210928t47aecc24v9b031fe1d7f2b381@mail.gmail.com> On Sat, Nov 21, 2009 at 9:18 AM, Jakob Praher wrote: > Why did you change to # for introducing function types and creating > closures? > Because the # syntax for references to methods is already part of the Java mindset from its use in javadoc. That naturally generalizes to a corresponding syntax for lambdas and therefore function types. > But I think having to write: > > int[] result = x.select( #(int c) c % 2 == 0) > > is harder to read. Don't you think? > Not especially. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/e1ffedb4/attachment.html From vladimir.kirichenko at gmail.com Sat Nov 21 10:19:25 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Sat, 21 Nov 2009 20:19:25 +0200 Subject: Syntax... In-Reply-To: <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B07209E.50508@univ-mlv.fr> <15e8b9d20911201451g1af9f0b6v9c15cfcc28b68cd6@mail.gmail.com> <4B072472.50503@univ-mlv.fr> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> <4B074859.2050107@univ-mlv.fr> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> Message-ID: <4B082F2D.8020008@gmail.com> Neal Gafter wrote: > I can't quite infer the structure of the language from your examples. > Can you please show the syntax grammar (BNF) for this suggestion? Ok. But I'd like to explain some grounds of this syntax first. This proposal is actually based on experience with other languages with lambda. ocaml: fun x -> x + 1 haskell: \x -> x + 1 scala: (x:Int) => x + 1 C#: (int x) => x + 1 .... So we can see some (as for me it's very successful) pattern here. As I can see there are 2 possible difficulties with possible lambda syntax: inconvenient c-like prefixed type manifestation and necessity of checked exceptions declaration. Most of these languages have "pascal-like" type manifestation - using colon. In Java we have similar situation as in C#, it could be good to consider experience of good enough implementation there. There are two issues: actual lambda definition and definition of "function variable" with it's type. There are delegates in C# those were used to declare type of function: delegate int increment(int i); We have no delegates in java so we have to invent something new for it. Let's take it from OCaml: "fun". So possible proposed syntax by example: a) Anonymous lambda: EBNF: /AnonymousLambda/: fun /TypeSpec/ => /Body/ /TypeSpec/: /Type/? /ParamsSpec/? /ThrowsSpec/? /ParamsSpec/: ( /Param/+ ) /Param/: /Type/ ID /ThrowsSpec/: throws /ExceptionType/+ /Body/: /Expression/ | { /StatementList/ } The return type, params and throws declared optional to reduce unnecessary "empty" constructs. See examples: Examples: 1. fully typed: fun int (int x) throws Exception => x + 1 2. no exceptions: fun int (int x) => x + 1 3. void lambda: fun (int x) => System.out.println(x) 4. no params: fun => System.out.println("hello") 5. nonvoid with statements fun int => { return 10 } 6. exceptional only fun throws IOException => { if (!(new File("/a")).exists()) throw new IOException("oops") } b) Named function declaration: It's very similar to the anonymous lambda except it has identifier, uses assignment operator instead of implication ( => ), and has no param identifiers: EBNF: /Function/: fun /TypeSpec/ /Assignment/? /Assignment/: = /AnonymousLambda/ /TypeSpec/: /Type/? ID /ParamsSpec/? /ThrowsSpec/? /ParamsSpec/: ( /Type/+ ) /ThrowsSpec/: throws /ExceptionType/+ Examples: 1. fully typed w/o assignment: fun int increment(int) throws Exception; .... increment = fun int (int x) => x + 1 2. void w/o params and w/o assignment: fun hello; .... hello = System.out.println("hello"); 3. different usages as argument: int method1( fun int f(int), fun int g(int) ) { return f(g(10)); } void method2( fun code ) { code(); } 4. passing as argument (to previous declarations) and in-place assignment: fun int inc(int) = fun int (int x) => x + 1; method1( inc, fun int (int x) => x * 2 ); method2( fun => System.out.println("hello") ); As we can see in example a.4. there is some type duplication in in-place assignment. So: c) Named function declaration aka short form. Difference between c) and b) are IDs in param spec and implication (=>) instead of assignment. So basically it's Anonymous lambda with name: EBNF: /Function/: fun /TypeSpec/ => /Body/ /TypeSpec/: /Type/? ID /ParamsSpec/? /ThrowsSpec/? /ParamsSpec/: ( /Param/+ ) /Param/: /Type/ ID /ThrowsSpec/: throws /ExceptionType/+ /Body/: /Expression/ | { /StatementList/ } Examples: 1. fully typed w/o assignment: fun int increment(int) throws Exception => x + 1; 2. void w/o params and w/o assignment: fun hello => System.out.println("hello"); An the end: Optionality of empty argument list or/and return type could be sacrificed for the purposes of parsing. Benefits of this syntax: 1. It has usual syntax (follows the pattern of different languages with lambda). 2. Contains no Perl'ish hieroglyphs. Let's not start please! 3. It proposes short form syntax of named function definition w/o necessity of type duplications. -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/db7c12f6/attachment.bin From vladimir.kirichenko at gmail.com Sat Nov 21 10:58:26 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Sat, 21 Nov 2009 20:58:26 +0200 Subject: Syntax... (errata) In-Reply-To: <4B082F2D.8020008@gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B07209E.50508@univ-mlv.fr> <15e8b9d20911201451g1af9f0b6v9c15cfcc28b68cd6@mail.gmail.com> <4B072472.50503@univ-mlv.fr> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> <4B074859.2050107@univ-mlv.fr> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> Message-ID: <4B083852.8090906@gmail.com> Neal Gafter wrote: > > I can't quite infer the structure of the language from your examples. > > Can you please show the syntax grammar (BNF) for this suggestion? Ok. But I'd like to explain some grounds of this syntax first. This proposal is actually based on experience with other languages with lambda. ocaml: fun x -> x + 1 haskell: \x -> x + 1 scala: (x:Int) => x + 1 C#: (int x) => x + 1 .... So we can see some (as for me it's very successful) pattern here. As I can see there are 2 possible difficulties with possible lambda syntax: inconvenient c-like prefixed type manifestation and necessity of checked exceptions declaration. Most of these languages have "pascal-like" type manifestation - using colon. In Java we have similar situation as in C#, it could be good to consider experience of good enough implementation there. There are two issues: actual lambda definition and definition of "function variable" with it's type. There are delegates in C# those were used to declare type of function: delegate int increment(int i); We have no delegates in java so we have to invent something new for it. Let's take it from OCaml: "fun". So possible proposed syntax by example: a) Anonymous lambda: EBNF: /AnonymousLambda/: fun /TypeSpec/ => /Body/ /TypeSpec/: /Type/? /ParamsSpec/? /ThrowsSpec/? /ParamsSpec/: ( /Param/+ ) /Param/: /Type/ ID /ThrowsSpec/: throws /ExceptionType/+ /Body/: /Expression/ | { /StatementList/ } The return type, params and throws declared optional to reduce unnecessary "empty" constructs. See examples: Examples: 1. fully typed: fun int (int x) throws Exception => x + 1 2. no exceptions: fun int (int x) => x + 1 3. void lambda: fun (int x) => System.out.println(x) 4. no params: fun => System.out.println("hello") 5. nonvoid with statements fun int => { return 10 } 6. exceptional only fun throws IOException => { if (!(new File("/a")).exists()) throw new IOException("oops") } b) Named function declaration: It's very similar to the anonymous lambda except it has identifier, uses assignment operator instead of implication ( => ), and has no param identifiers: EBNF: /Function/: fun /TypeSpec/ /Assignment/? /Assignment/: = /AnonymousLambda/ /TypeSpec/: /Type/? ID /ParamsSpec/? /ThrowsSpec/? /ParamsSpec/: ( /Type/+ ) /ThrowsSpec/: throws /ExceptionType/+ Examples: 1. fully typed w/o assignment: fun int increment(int) throws Exception; .... increment = fun int (int x) => x + 1 2. void w/o params and w/o assignment: fun hello; .... hello = fun => System.out.println("hello"); 3. different usages as argument: int method1( fun int f(int), fun int g(int) ) { return f(g(10)); } void method2( fun code ) { code(); } 4. passing as argument (to previous declarations) and in-place assignment: fun int inc(int) = fun int (int x) => x + 1; method1( inc, fun int (int x) => x * 2 ); method2( fun => System.out.println("hello") ); As we can see in example a.4. there is some type duplication in in-place assignment. So: c) Named function declaration aka short form. Difference between c) and b) are IDs in param spec and implication (=>) instead of assignment. So basically it's Anonymous lambda with name: EBNF: /Function/: fun /TypeSpec/ => /Body/ /TypeSpec/: /Type/? ID /ParamsSpec/? /ThrowsSpec/? /ParamsSpec/: ( /Param/+ ) /Param/: /Type/ ID /ThrowsSpec/: throws /ExceptionType/+ /Body/: /Expression/ | { /StatementList/ } Examples: 1. fully typed: fun int increment(int) throws Exception => x + 1; 2. void w/o params: fun hello => System.out.println("hello"); At the end: Optionality of empty argument list or/and return type could be sacrificed for the purposes of parsing. Benefits of this syntax: 1. It is usual (follows the pattern of different languages with lambda). 2. Contains no Perl'ish hieroglyphs. Let's not start please! 3. It proposes short form syntax of named function definition w/o necessity of type duplications. -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/70b82660/attachment.bin From neal at gafter.com Sat Nov 21 11:03:00 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 21 Nov 2009 11:03:00 -0800 Subject: Syntax... In-Reply-To: <4B082F2D.8020008@gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <15e8b9d20911201451g1af9f0b6v9c15cfcc28b68cd6@mail.gmail.com> <4B072472.50503@univ-mlv.fr> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> <4B074859.2050107@univ-mlv.fr> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> Message-ID: <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> On Sat, Nov 21, 2009 at 10:19 AM, Vladimir Kirichenko < vladimir.kirichenko at gmail.com> wrote: > /AnonymousLambda/: > fun /TypeSpec/ => /Body/ > /TypeSpec/: > /Type/? /ParamsSpec/? /ThrowsSpec/? > /ParamsSpec/: > ( /Param/+ ) > /Param/: > /Type/ ID > /ThrowsSpec/: > throws /ExceptionType/+ > /Body/: > /Expression/ | { /StatementList/ } > > The return type, params and throws declared optional to reduce > unnecessary "empty" constructs. ... > EBNF: > > /Function/: > fun /TypeSpec/ /Assignment/? > /Assignment/: > = /AnonymousLambda/ > /TypeSpec/: > /Type/? ID /ParamsSpec/? /ThrowsSpec/? > /ParamsSpec/: > ( /Type/+ ) > /ThrowsSpec/: > throws /ExceptionType/+ > ... > EBNF: > > /Function/: > fun /TypeSpec/ => /Body/ > /TypeSpec/: > /Type/? ID /ParamsSpec/? /ThrowsSpec/? > /ParamsSpec/: > ( /Param/+ ) > /Param/: > /Type/ ID > /ThrowsSpec/: > throws /ExceptionType/+ > /Body/: > /Expression/ | { /StatementList/ } > This is all very confusing. From /Function/ I derive using /Function/: fun /TypeSpec/ /Assignment/? we get fun /TypeSpec/ /Assignment/ using /TypeSpec/: /Type/? /ParamsSpec/? /ThrowsSpec/? and taking all the optional parts to be empty, we get fun /Assignment/ Then using /Assignment/: = /AnonymousLambda/ this results in fun = /AnonymousLambda/ Then using /AnonymousLambda/: fun /TypeSpec/ => /Body/ this becomes fun = fun /TypeSpec/ => /Body/ Again, taking /TypeSpec/ to be empty, as before, and using /Body/: /Expression/ | { /StatementList/ } we finally get fun = fun => 3 I just have no idea what it is all supposed to mean. Is this a declaration? A statement? An expression? Is it supposed to define something? Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/4fabdf7a/attachment.html From vladimir.kirichenko at gmail.com Sat Nov 21 11:11:14 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Sat, 21 Nov 2009 21:11:14 +0200 Subject: Syntax... In-Reply-To: <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <15e8b9d20911201451g1af9f0b6v9c15cfcc28b68cd6@mail.gmail.com> <4B072472.50503@univ-mlv.fr> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> <4B074859.2050107@univ-mlv.fr> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> Message-ID: <4B083B52.5050000@gmail.com> Neal Gafter wrote: > On Sat, Nov 21, 2009 at 10:19 AM, Vladimir Kirichenko > > > wrote: > > /AnonymousLambda/: > fun /TypeSpec/ => /Body/ > /TypeSpec/: > /Type/? /ParamsSpec/? /ThrowsSpec/? > /ParamsSpec/: > ( /Param/+ ) > /Param/: > /Type/ ID > /ThrowsSpec/: > throws /ExceptionType/+ > /Body/: > /Expression/ | { /StatementList/ } > > The return type, params and throws declared optional to reduce > unnecessary "empty" constructs. > > ... > > EBNF: > > /Function/: > fun /TypeSpec/ /Assignment/? > /Assignment/: > = /AnonymousLambda/ > /TypeSpec/: > /Type/? ID /ParamsSpec/? /ThrowsSpec/? > /ParamsSpec/: > ( /Type/+ ) > /ThrowsSpec/: > throws /ExceptionType/+ > > ... > > EBNF: > > /Function/: > fun /TypeSpec/ => /Body/ > /TypeSpec/: > /Type/? ID /ParamsSpec/? /ThrowsSpec/? > /ParamsSpec/: > ( /Param/+ ) > /Param/: > /Type/ ID > /ThrowsSpec/: > throws /ExceptionType/+ > /Body/: > /Expression/ | { /StatementList/ } > Sorry for confusion - it's 3 differened EBNFs - haven't synced them. > This is all very confusing. From /Function/ I derive > > using > /Function/: > fun /TypeSpec/ /Assignment/? > > we get > > fun /TypeSpec/ /Assignment/ > > using > /TypeSpec/: > /Type/? /ParamsSpec/? /ThrowsSpec/? It's wrong TypeSpec. In /Function/ it's slightly different: /TypeSpec/: /Type/? ID /ParamsSpec/? /ThrowsSpec/? > and taking all the optional parts to be empty, we get > > fun /Assignment/ fun ID /Assignment/ > Then using > /Assignment/: > = /AnonymousLambda/ > > this results in > > fun = /AnonymousLambda/ fun ID = /AnonymousLambda/ > Then using > /AnonymousLambda/: > fun /TypeSpec/ => /Body/ > > this becomes > fun = fun /TypeSpec/ => /Body/ fun ID = fun /TypeSpec/ => /Body/ > Again, taking /TypeSpec/ to be empty, as before, and using > /Body/: > /Expression/ | { /StatementList/ } > > we finally get > > fun = fun => 3 fun ID = fun => 3 > I just have no idea what it is all supposed to mean. Is this a > declaration? A statement? An expression? Is it supposed to define > something? so it's a declaration of identifier ID of declared type "fun void ()" and type mismatch compiler error "expected: void but found: int". -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/06d96313/attachment-0001.bin From neal at gafter.com Sat Nov 21 11:17:41 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 21 Nov 2009 11:17:41 -0800 Subject: Syntax... In-Reply-To: <4B083B52.5050000@gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> <4B074859.2050107@univ-mlv.fr> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> <4B083B52.5050000@gmail.com> Message-ID: <15e8b9d20911211117i1d2ba197pafafdf3d9557eaa0@mail.gmail.com> Are you proposing "fun" be a new keyword? On Sat, Nov 21, 2009 at 11:11 AM, Vladimir Kirichenko < vladimir.kirichenko at gmail.com> wrote: > Neal Gafter wrote: > > On Sat, Nov 21, 2009 at 10:19 AM, Vladimir Kirichenko > > > > > wrote: > > > > /AnonymousLambda/: > > fun /TypeSpec/ => /Body/ > > /TypeSpec/: > > /Type/? /ParamsSpec/? /ThrowsSpec/? > > /ParamsSpec/: > > ( /Param/+ ) > > /Param/: > > /Type/ ID > > /ThrowsSpec/: > > throws /ExceptionType/+ > > /Body/: > > /Expression/ | { /StatementList/ } > > > > The return type, params and throws declared optional to reduce > > unnecessary "empty" constructs. > > > > ... > > > > EBNF: > > > > /Function/: > > fun /TypeSpec/ /Assignment/? > > /Assignment/: > > = /AnonymousLambda/ > > /TypeSpec/: > > /Type/? ID /ParamsSpec/? /ThrowsSpec/? > > /ParamsSpec/: > > ( /Type/+ ) > > /ThrowsSpec/: > > throws /ExceptionType/+ > > > > ... > > > > EBNF: > > > > /Function/: > > fun /TypeSpec/ => /Body/ > > /TypeSpec/: > > /Type/? ID /ParamsSpec/? /ThrowsSpec/? > > /ParamsSpec/: > > ( /Param/+ ) > > /Param/: > > /Type/ ID > > /ThrowsSpec/: > > throws /ExceptionType/+ > > /Body/: > > /Expression/ | { /StatementList/ } > > > > Sorry for confusion - it's 3 differened EBNFs - haven't synced them. > > > This is all very confusing. From /Function/ I derive > > > > using > > /Function/: > > fun /TypeSpec/ /Assignment/? > > > > we get > > > > fun /TypeSpec/ /Assignment/ > > > > using > > /TypeSpec/: > > /Type/? /ParamsSpec/? /ThrowsSpec/? > > It's wrong TypeSpec. In /Function/ it's slightly different: > > /TypeSpec/: > /Type/? ID /ParamsSpec/? /ThrowsSpec/? > > > and taking all the optional parts to be empty, we get > > > > fun /Assignment/ > > fun ID /Assignment/ > > > > Then using > > /Assignment/: > > = /AnonymousLambda/ > > > > this results in > > > > fun = /AnonymousLambda/ > > fun ID = /AnonymousLambda/ > > > Then using > > /AnonymousLambda/: > > fun /TypeSpec/ => /Body/ > > > > this becomes > > fun = fun /TypeSpec/ => /Body/ > > fun ID = fun /TypeSpec/ => /Body/ > > > Again, taking /TypeSpec/ to be empty, as before, and using > > /Body/: > > /Expression/ | { /StatementList/ } > > > > we finally get > > > > fun = fun => 3 > > fun ID = fun => 3 > > > I just have no idea what it is all supposed to mean. Is this a > > declaration? A statement? An expression? Is it supposed to define > > something? > > so it's a declaration of identifier ID of declared type "fun void ()" > and type mismatch compiler error "expected: void but found: int". > > > > -- > Best Regards, > Vladimir Kirichenko > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/77c6bf0a/attachment.html From vladimir.kirichenko at gmail.com Sat Nov 21 11:22:39 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Sat, 21 Nov 2009 21:22:39 +0200 Subject: Syntax... In-Reply-To: <15e8b9d20911211117i1d2ba197pafafdf3d9557eaa0@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> <4B074859.2050107@univ-mlv.fr> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> <4B083B52.5050000@gmail.com> <15e8b9d20911211117i1d2ba197pafafdf3d9557eaa0@mail.gmail.com> Message-ID: <4B083DFF.4070505@gmail.com> Neal Gafter wrote: > Are you proposing "fun" be a new keyword? Yes. Anyway we need something for disambiguation (in current proposal it's # or ^). "fun" looks nice for this. (shorter than function - too much letters for limbda construct, and good looking next to class, interface and especially enum). Other languages with pascal-like type manifestation have their let, var, val, set. -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/b0fddcb2/attachment.bin From neal at gafter.com Sat Nov 21 12:04:36 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 21 Nov 2009 12:04:36 -0800 Subject: Syntax... In-Reply-To: <4B083DFF.4070505@gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> <4B083B52.5050000@gmail.com> <15e8b9d20911211117i1d2ba197pafafdf3d9557eaa0@mail.gmail.com> <4B083DFF.4070505@gmail.com> Message-ID: <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> Vladimir- We've been carefully avoiding keywords up to now, but I agree using keywords could result in more natural-reading programs. The problem is the risk of breaking existing programs. However, that is somewhat less severe now that there is a syntax for "exotic" identifiers. In JDK7 a keyword can still be used as an identifier by using the exotic identifier escape syntax. So the breakage is not as bad as it would have been earlier. It might be possible to use context-sensitive keywords, too. I would probably want to use something like 'fun' in place of '#' for function types, and 'lambda' or 'fun' in place of '#' for lambda expressions. fun int(int) plus1 = lambda (int x) x+1; I also prefer the result type on the right-hand-side of a function types, but somepeople seem to have trouble with that: fun (int)->int plus1 = lambda (int x) x+1; This latter formulation is neater-looking when there are exceptions in the function type. For example, this fun int(int) throws Exception plus1 = lambda (int x) x+1; reads less well to me than this fun (int) throws Exception ->int plus1 = lambda (int x) x+1; Cheers, Neal On Sat, Nov 21, 2009 at 11:22 AM, Vladimir Kirichenko < vladimir.kirichenko at gmail.com> wrote: > Neal Gafter wrote: > > Are you proposing "fun" be a new keyword? > > Yes. Anyway we need something for disambiguation (in current proposal > it's # or ^). "fun" looks nice for this. (shorter than function - too > much letters for limbda construct, and good looking next to class, > interface and especially enum). > > Other languages with pascal-like type manifestation have their let, var, > val, set. > > -- > Best Regards, > Vladimir Kirichenko > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/c9200a13/attachment.html From vladimir.kirichenko at gmail.com Sat Nov 21 12:24:02 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Sat, 21 Nov 2009 22:24:02 +0200 Subject: Syntax... In-Reply-To: <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> <4B083B52.5050000@gmail.com> <15e8b9d20911211117i1d2ba197pafafdf3d9557eaa0@mail.gmail.com> <4B083DFF.4070505@gmail.com> <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> Message-ID: <4B084C62.7030901@gmail.com> Neal Gafter wrote: > Vladimir- > > We've been carefully avoiding keywords up to now, but I agree using > keywords could result in more natural-reading programs. The problem is > the risk of breaking existing programs. However, that is somewhat less We survived "enum" I'm pretty sure "fun" is survivable too. Mostly because of the same reasons - enum were used to implement ad-hoc enums and "fun" most likely used with ad-hoc lambdas. > severe now that there is a syntax for "exotic" identifiers. In JDK7 a > keyword can still be used as an identifier by using the exotic > identifier escape syntax. So the breakage is not as bad as it would > have been earlier. It might be possible to use context-sensitive > keywords, too. > > I would probably want to use something like 'fun' in place of '#' for > function types, and 'lambda' or 'fun' in place of '#' for lambda > expressions. > > fun int(int) plus1 = lambda (int x) x+1; > > I also prefer the result type on the right-hand-side of a function > types, but somepeople seem to have trouble with that: > > fun (int)->int plus1 = lambda (int x) x+1; I also like currying-like syntax, but made my proposal looking back to those somepeople :) But it's understandable (int)->int looks alien in Java. > This latter formulation is neater-looking when there are exceptions in > the function type. For example, this > > fun int(int) throws Exception plus1 = lambda (int x) x+1; > > reads less well to me than this > > fun (int) throws Exception ->int plus1 = lambda (int x) x+1; Putting identifier in the type declaration (like regular method) was chasing two rabbits: 1. As a preparation for short form (EBNF.3) to remove duplicate type declaration. fun int increment(int x) => x + 1; instead of fun int (int) increment = fun int (int x) => x + 1; notice double type declaration here. 2. Thinking about somepeople who used to see: int increment(int x) { return x + 1 }; compare to: fun int increment(int x) => x + 1; -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/466c0bd8/attachment.bin From forax at univ-mlv.fr Sat Nov 21 12:53:11 2009 From: forax at univ-mlv.fr (=?UTF-8?B?UsOpbWkgRm9yYXg=?=) Date: Sat, 21 Nov 2009 21:53:11 +0100 Subject: Syntax... In-Reply-To: <4B084C62.7030901@gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> <4B083B52.5050000@gmail.com> <15e8b9d20911211117i1d2ba197pafafdf3d9557eaa0@mail.gmail.com> <4B083DFF.4070505@gmail.com> <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> <4B084C62.7030901@gmail.com> Message-ID: <4B085337.1070105@univ-mlv.fr> Le 21/11/2009 21:24, Vladimir Kirichenko a ?crit : > Neal Gafter wrote: > >> Vladimir- >> >> We've been carefully avoiding keywords up to now, but I agree using >> keywords could result in more natural-reading programs. The problem is >> the risk of breaking existing programs. However, that is somewhat less >> > We survived "enum" I'm pretty sure "fun" is survivable too. Mostly > because of the same reasons - enum were used to implement ad-hoc enums > and "fun" most likely used with ad-hoc lambdas. > I haven't survive to enum :) Since 1.0, JDK embeds a class named java.util.Enumeration, you can easily guess the name of the variable commonly used for that type. R?mi From forax at univ-mlv.fr Sat Nov 21 13:00:09 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 21 Nov 2009 22:00:09 +0100 Subject: Syntax... In-Reply-To: <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> <4B083B52.5050000@gmail.com> <15e8b9d20911211117i1d2ba197pafafdf3d9557eaa0@mail.gmail.com> <4B083DFF.4070505@gmail.com> <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> Message-ID: <4B0854D9.4080600@univ-mlv.fr> Le 21/11/2009 21:04, Neal Gafter a ?crit : > Vladimir- > > We've been carefully avoiding keywords up to now, but I agree using > keywords could result in more natural-reading programs. The problem > is the risk of breaking existing programs. However, that is somewhat > less severe now that there is a syntax for "exotic" identifiers. In > JDK7 a keyword can still be used as an identifier by using the exotic > identifier escape syntax. So the breakage is not as bad as it would > have been earlier. It might be possible to use context-sensitive > keywords, too. > > I would probably want to use something like 'fun' in place of '#' for > function types, and 'lambda' or 'fun' in place of '#' for lambda > expressions. > > fun int(int) plus1 = lambda (int x) x+1; > > I also prefer the result type on the right-hand-side of a function > types, but somepeople seem to have trouble with that: > > fun (int)->int plus1 = lambda (int x) x+1; [...] I vote for fun and lambda too. Neal do you have planned to try to patch the parser to see if their introduction is possible or not ? BTW, I am one of the mob that doesn't like arrow, it's too warlike for me :) cheers, R?mi From vladimir.kirichenko at gmail.com Sat Nov 21 12:48:23 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Sat, 21 Nov 2009 22:48:23 +0200 Subject: Syntax... In-Reply-To: <4B085337.1070105@univ-mlv.fr> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> <4B083B52.5050000@gmail.com> <15e8b9d20911211117i1d2ba197pafafdf3d9557eaa0@mail.gmail.com> <4B083DFF.4070505@gmail.com> <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> <4B084C62.7030901@gmail.com> <4B085337.1070105@univ-mlv.fr> Message-ID: <4B085217.5020507@gmail.com> R?mi Forax wrote: > I haven't survive to enum :) > Since 1.0, JDK embeds a class named java.util.Enumeration, > you can easily guess the name of the variable commonly used for that type. AFAIU the biggest problems with new keyword is a package name or class name. Big problem was with org.apache.commons.enum AFAIR. If your moving your sources to next java version with all the language improvements - changing the couple of local variables is not a big deal. Remember migration to generics - that was a big peace of work. Anyway with appearance of closures most people are going to be so happy that this problems are going to be like a byte of small mosquito. And anyway it's better than avoiding keywords with replacing them with cryptic hieroglyphs. It's a change not for one day - it is how language will going to look like within 5 years an later. Another good example is C#. MS does not hesitate to add keywords to the language and it does not seem that anyone get hurt much because of this. -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/77f7ed9c/attachment.bin From vladimir.kirichenko at gmail.com Sat Nov 21 12:59:09 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Sat, 21 Nov 2009 22:59:09 +0200 Subject: Syntax... In-Reply-To: <4B0854D9.4080600@univ-mlv.fr> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> <4B083B52.5050000@gmail.com> <15e8b9d20911211117i1d2ba197pafafdf3d9557eaa0@mail.gmail.com> <4B083DFF.4070505@gmail.com> <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> <4B0854D9.4080600@univ-mlv.fr> Message-ID: <4B08549D.6070908@gmail.com> R?mi Forax wrote: > I vote for fun and lambda too. Two keywords:) With a short form (EBNF.3) use of fun int f = fun int => 3; will be marginal, in favor of fun int f => 3; So it's not necessary to use 2 keywords which almost never will be together in real life. Actually short form of function could be seen as named (not anonymous) lambda. It's a "codefolding" similar to: x += 1; x = x + 1; -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/7940b46b/attachment.bin From mark at twistedbanana.demon.co.uk Sat Nov 21 17:30:48 2009 From: mark at twistedbanana.demon.co.uk (Mark Mahieu) Date: Sun, 22 Nov 2009 01:30:48 +0000 Subject: Syntax... In-Reply-To: <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> <4B083B52.5050000@gmail.com> <15e8b9d20911211117i1d2ba197pafafdf3d9557eaa0@mail.gmail.com> <4B083DFF.4070505@gmail.com> <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> Message-ID: It's also worth considering carefully how readable any proposed syntax will be when a lambda expression is used as a method argument, or a function type used in a method signature. When I last looked into various options, I noted that some forms worked well in the context of a variable declaration or assignment, but were rather less easy to parse (for me, not the compiler) when they appeared as the type of a method parameter, especially when there were two or more parameters. On another note, the link to the v0.6a Open Issues page is pointing to v0.5 at javac.info (although the correct URL isn't hard to guess :-) Mark On 21 Nov 2009, at 20:04, Neal Gafter wrote: > Vladimir- > > We've been carefully avoiding keywords up to now, but I agree using keywords could result in more natural-reading programs. The problem is the risk of breaking existing programs. However, that is somewhat less severe now that there is a syntax for "exotic" identifiers. In JDK7 a keyword can still be used as an identifier by using the exotic identifier escape syntax. So the breakage is not as bad as it would have been earlier. It might be possible to use context-sensitive keywords, too. > > I would probably want to use something like 'fun' in place of '#' for function types, and 'lambda' or 'fun' in place of '#' for lambda expressions. > > fun int(int) plus1 = lambda (int x) x+1; > > I also prefer the result type on the right-hand-side of a function types, but somepeople seem to have trouble with that: > > fun (int)->int plus1 = lambda (int x) x+1; > > This latter formulation is neater-looking when there are exceptions in the function type. For example, this > > fun int(int) throws Exception plus1 = lambda (int x) x+1; > > reads less well to me than this > > fun (int) throws Exception ->int plus1 = lambda (int x) x+1; > > Cheers, > Neal > > On Sat, Nov 21, 2009 at 11:22 AM, Vladimir Kirichenko wrote: > Neal Gafter wrote: > > Are you proposing "fun" be a new keyword? > > Yes. Anyway we need something for disambiguation (in current proposal > it's # or ^). "fun" looks nice for this. (shorter than function - too > much letters for limbda construct, and good looking next to class, > interface and especially enum). > > Other languages with pascal-like type manifestation have their let, var, > val, set. > > -- > Best Regards, > Vladimir Kirichenko > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091122/2f2a4c44/attachment-0001.html From pbenedict at apache.org Sat Nov 21 17:55:06 2009 From: pbenedict at apache.org (Paul Benedict) Date: Sat, 21 Nov 2009 19:55:06 -0600 Subject: Syntax... In-Reply-To: References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> <4B083B52.5050000@gmail.com> <15e8b9d20911211117i1d2ba197pafafdf3d9557eaa0@mail.gmail.com> <4B083DFF.4070505@gmail.com> <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> Message-ID: I would favor -> (dash greater-than) since it does not overload an existing operator. I suppose that is more readable than # for closures. Paul On Sat, Nov 21, 2009 at 7:30 PM, Mark Mahieu wrote: > It's also worth considering carefully how readable any proposed syntax will > be when a lambda expression is used as a method argument, or a function type > used in a method signature. ?When I last looked into various options, I > noted that some forms worked well in the context of a variable declaration > or assignment, but were rather less easy to parse (for me, not the compiler) > when they appeared as the type of a method parameter, especially when there > were two or more parameters. > On another note, the link to the v0.6a Open Issues page is pointing to v0.5 > at javac.info (although the correct URL isn't hard to guess :-) > Mark > > On 21 Nov 2009, at 20:04, Neal Gafter wrote: > > Vladimir- > > We've been carefully avoiding keywords up to now, but I agree using keywords > could result in more natural-reading programs.? The problem is the risk of > breaking existing programs.? However, that is somewhat less severe now that > there is a syntax for "exotic" identifiers.? In JDK7 a keyword can still be > used as an identifier by using the exotic identifier escape syntax.? So the > breakage is not as bad as it would have been earlier.? It might be possible > to use context-sensitive keywords, too. > > I would probably want to use something like 'fun' in place of '#' for > function types, and 'lambda' or 'fun' in place of '#' for lambda > expressions. > > fun int(int) plus1 = lambda (int x) x+1; > > I also prefer the result type on the right-hand-side of a function types, > but somepeople seem to have trouble with that: > > fun (int)->int plus1 = lambda (int x) x+1; > > This latter formulation is neater-looking when there are exceptions in the > function type.? For example, this > > fun int(int) throws Exception plus1 = lambda (int x) x+1; > > reads less well to me than this > > fun (int) throws Exception ->int plus1 = lambda (int x) x+1; > > Cheers, > Neal > > On Sat, Nov 21, 2009 at 11:22 AM, Vladimir Kirichenko > wrote: >> >> Neal Gafter wrote: >> > Are you proposing "fun" be a new keyword? >> >> Yes. Anyway we need something for disambiguation (in current proposal >> it's # or ^). "fun" looks nice for this. (shorter than function - too >> much letters for limbda construct, and good looking next to class, >> interface and especially enum). >> >> Other languages with pascal-like type manifestation have their let, var, >> val, set. >> >> -- >> Best Regards, >> Vladimir Kirichenko >> > > > From neal at gafter.com Sat Nov 21 18:18:43 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 21 Nov 2009 18:18:43 -0800 Subject: Closures discussion list... Message-ID: <15e8b9d20911211818q295b9d55j48e2f76e1110e2b@mail.gmail.com> Folks- I suggest we consolidate discussion of about closures to the openjdk closures project mailing list: http://mail.openjdk.java.net/mailman/listinfo/closures-dev. Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091121/ff9c6c75/attachment.html From pbenedict at apache.org Sat Nov 21 18:34:31 2009 From: pbenedict at apache.org (Paul Benedict) Date: Sat, 21 Nov 2009 20:34:31 -0600 Subject: Syntax... In-Reply-To: <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> <4B083B52.5050000@gmail.com> <15e8b9d20911211117i1d2ba197pafafdf3d9557eaa0@mail.gmail.com> <4B083DFF.4070505@gmail.com> <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> Message-ID: Neal et. al., > I would probably want to use something like 'fun' in place of '#' for > function types, and 'lambda' or 'fun' in place of '#' for lambda > expressions. > > fun int(int) plus1 = lambda (int x) x+1; > > I also prefer the result type on the right-hand-side of a function types, > but some people seem to have trouble with that: > > fun (int)->int plus1 = lambda (int x) x+1; I think the idea of context-sensitive keywords is very astute. It would certainly be very readable as it indicates a "closure type" quite easily. As for "fun", it does seem .. well, kind of funny. I hope another context-sensitive keyword can be found. Otherwise, I still think this is clearly readable though: int(int) plus1 = lambda (int x) x+1; Some already said "lambda" or "fun" might not be 100% backwards compatible. I know that's a lofty goal, but is it absolutely necessary? I imagine people who write "lambda" in their source are doing esoteric things like writing math libraries. Otherwise, I can't froresee a great impact to the developer population. Paul From mark at twistedbanana.demon.co.uk Sat Nov 21 18:46:33 2009 From: mark at twistedbanana.demon.co.uk (Mark Mahieu) Date: Sun, 22 Nov 2009 02:46:33 +0000 Subject: Syntax... In-Reply-To: References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> <4B083B52.5050000@gmail.com> <15e8b9d20911211117i1d2ba197pafafdf3d9557eaa0@mail.gmail.com> <4B083DFF.4070505@gmail.com> <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> Message-ID: <73E2265C-AD1F-47F3-850A-185FF1DE268C@twistedbanana.demon.co.uk> On 22 Nov 2009, at 02:34, Paul Benedict wrote: > > As for "fun", it does seem .. well, kind of funny. Many moons ago I used a language which used just "fn" as its reserved word for functions. Seemed quite pithy at the time. Mark -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091122/66f14161/attachment.html From mark at twistedbanana.demon.co.uk Sat Nov 21 20:27:34 2009 From: mark at twistedbanana.demon.co.uk (Mark Mahieu) Date: Sun, 22 Nov 2009 04:27:34 +0000 Subject: Lambda expressions vs Diamond Message-ID: <6A6C1B2E-28C3-4984-9223-2AC08BC14999@twistedbanana.demon.co.uk> I'm wondering whether Diamond could/should be useable with lambda expressions, for example: #int(Collection) foo = #(Collection<> c) c.size(); I can imagine people intuitively expecting that to work, depending on whether they think of lambda expressions as objects with a type first and foremost, or as functions with a signature. One downside though - if 'foo' above had been declared as a normal interface type, it would become more difficult to understand the type of 'c' (not that it's relevant in this example). Mark From neal at gafter.com Sat Nov 21 21:36:59 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 21 Nov 2009 21:36:59 -0800 Subject: Lambda expressions vs Diamond Message-ID: <4b08cdf2.9513f30a.1f7f.3445@mx.google.com> You need the types of the lambda parameters to determine the result type in a lambda, which you need to do overload resolution. So you can't delay determining the types of the parameters until after overload resolution. Unless, of course, you're willing to have type a completely different kind of type inference. I believe C# and Scala can both infer lambda parameter types completely, enabling you to omit their types altogether. I think that would be a good thing to consider. It can be done as a further extension later, too. Cheers, Neal -----Original Message----- From: Mark Mahieu Sent: Saturday, November 21, 2009 8:27 PM To: closures-dev at openjdk.java.net Subject: Lambda expressions vs Diamond I'm wondering whether Diamond could/should be useable with lambda expressions, for example: #int(Collection) foo = #(Collection<> c) c.size(); I can imagine people intuitively expecting that to work, depending on whether they think of lambda expressions as objects with a type first and foremost, or as functions with a signature. One downside though - if 'foo' above had been declared as a normal interface type, it would become more difficult to understand the type of 'c' (not that it's relevant in this example). Mark From ipris at inbox.ru Sat Nov 21 22:49:25 2009 From: ipris at inbox.ru (Kochurov Alexander) Date: Sun, 22 Nov 2009 09:49:25 +0300 Subject: Boxing function types Message-ID: Gentlemens, what about introducing boxing/unboxing for functional types? As Java generics don't allow us to use primitive types as type parameters, all java implementations of collection algorithms (such as map, fold, filter, etc.) would possibly use wrapper types such as Integer, Float and function types with wrapper arguments. So it would be great if every function type with argument types A[1], A[2],.. A[n] and result type Ra may be implicitly boxed into any other function type with argument types B[1], B[2], .. B[n] and result type Rb if either A[i] = B[i] or A[i] can be converted into B[i] using implicit convertion for any i = 1..n and if it's result type Ra either matches Rb or may be converted implicitly. (So I mean not only boxing/unboxing but also widening convertions for primitive types, e.g. function with result of short may be converted implicitly into function which returns int, long, float, double, Short, Integer, Long, Float, Double but not byte, Byte, etc.) Alex From tronicek at fit.cvut.cz Sun Nov 22 01:25:27 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Sun, 22 Nov 2009 10:25:27 +0100 Subject: Syntax... (errata) In-Reply-To: <4B083852.8090906@gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B07209E.50508@univ-mlv.fr> <15e8b9d20911201451g1af9f0b6v9c15cfcc28b68cd6@mail.gmail.com> <4B072472.50503@univ-mlv.fr> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> <4B074859.2050107@univ-mlv.fr> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <4B083852.8090906@gmail.com> Message-ID: <398c4a165428ad5f8adf9f3097177b84.squirrel@imap.fit.cvut.cz> Hi, this is very readable for me. In grammar, commas between params are missing and there is ambiguity: fun X => { throw new NullPointerException(); } because X can be a name of closure or a return type. But probably this is not crucial, because anonymous lambda and named functions will not appear on the same place. Z. -- Zdenek Tronicek FIT CTU in Prague Vladimir Kirichenko napsal(a): > a) Anonymous lambda: > > EBNF: > > /AnonymousLambda/: > fun /TypeSpec/ => /Body/ > /TypeSpec/: > /Type/? /ParamsSpec/? /ThrowsSpec/? > /ParamsSpec/: > ( /Param/+ ) > /Param/: > /Type/ ID > /ThrowsSpec/: > throws /ExceptionType/+ > /Body/: > /Expression/ | { /StatementList/ } > ... > b) Named function declaration: > > It's very similar to the anonymous lambda except it has identifier, uses > assignment operator instead of implication ( => ), and has no param > identifiers: > > EBNF: > > /Function/: > fun /TypeSpec/ /Assignment/? > /Assignment/: > = /AnonymousLambda/ > /TypeSpec/: > /Type/? ID /ParamsSpec/? /ThrowsSpec/? > /ParamsSpec/: > ( /Type/+ ) > /ThrowsSpec/: > throws /ExceptionType/+ > ... > c) Named function declaration aka short form. Difference between c) and > b) are IDs in param spec and implication (=>) instead of assignment. So > basically it's Anonymous lambda with name: > > EBNF: > > /Function/: > fun /TypeSpec/ => /Body/ > /TypeSpec/: > /Type/? ID /ParamsSpec/? /ThrowsSpec/? > /ParamsSpec/: > ( /Param/+ ) > /Param/: > /Type/ ID > /ThrowsSpec/: > throws /ExceptionType/+ > /Body/: > /Expression/ | { /StatementList/ } > From reinier at zwitserloot.com Sun Nov 22 02:17:49 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 22 Nov 2009 11:17:49 +0100 Subject: Syntax... (errata) In-Reply-To: <398c4a165428ad5f8adf9f3097177b84.squirrel@imap.fit.cvut.cz> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> <4B074859.2050107@univ-mlv.fr> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <4B083852.8090906@gmail.com> <398c4a165428ad5f8adf9f3097177b84.squirrel@imap.fit.cvut.cz> Message-ID: <560fb5ed0911220217o23b98c80wc4bcf9f86fd5f5f9@mail.gmail.com> fun? + a few million to the idea of using 'fn' or # instead. Zdenek, I'm guessing that you find: fun X => {codeblock} readable primarily because you have experience with plenty of other languages. Java users that don't take an interest to closures-dev usually don't have that experience, so any statements about whether something looks 'natural' or 'feels java-like' by any of us is probably not worth all that much. We've been tainted by too much knowledge :) --Reinier Zwitserloot On Sun, Nov 22, 2009 at 10:25 AM, wrote: > Hi, > > this is very readable for me. In grammar, commas between params are > missing and there is ambiguity: > > fun X => { throw new NullPointerException(); } > > because X can be a name of closure or a return type. But probably this is > not crucial, because anonymous lambda and named functions will not appear > on the same place. > > Z. > -- > Zdenek Tronicek > FIT CTU in Prague > > > Vladimir Kirichenko napsal(a): > > > a) Anonymous lambda: > > > > EBNF: > > > > /AnonymousLambda/: > > fun /TypeSpec/ => /Body/ > > /TypeSpec/: > > /Type/? /ParamsSpec/? /ThrowsSpec/? > > /ParamsSpec/: > > ( /Param/+ ) > > /Param/: > > /Type/ ID > > /ThrowsSpec/: > > throws /ExceptionType/+ > > /Body/: > > /Expression/ | { /StatementList/ } > > > ... > > b) Named function declaration: > > > > It's very similar to the anonymous lambda except it has identifier, uses > > assignment operator instead of implication ( => ), and has no param > > identifiers: > > > > EBNF: > > > > /Function/: > > fun /TypeSpec/ /Assignment/? > > /Assignment/: > > = /AnonymousLambda/ > > /TypeSpec/: > > /Type/? ID /ParamsSpec/? /ThrowsSpec/? > > /ParamsSpec/: > > ( /Type/+ ) > > /ThrowsSpec/: > > throws /ExceptionType/+ > > > ... > > c) Named function declaration aka short form. Difference between c) and > > b) are IDs in param spec and implication (=>) instead of assignment. So > > basically it's Anonymous lambda with name: > > > > EBNF: > > > > /Function/: > > fun /TypeSpec/ => /Body/ > > /TypeSpec/: > > /Type/? ID /ParamsSpec/? /ThrowsSpec/? > > /ParamsSpec/: > > ( /Param/+ ) > > /Param/: > > /Type/ ID > > /ThrowsSpec/: > > throws /ExceptionType/+ > > /Body/: > > /Expression/ | { /StatementList/ } > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091122/fa4724f9/attachment-0001.html From reinier at zwitserloot.com Sun Nov 22 02:33:36 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 22 Nov 2009 11:33:36 +0100 Subject: Boxing function types In-Reply-To: References: Message-ID: <560fb5ed0911220233x44a01ec5w3aa416e8ff4189c0@mail.gmail.com> That seems like a good idea, Kochurov. Speaking of autoboxing and closures, Mark Reinhold showed a slide containing all the types in Parallel Array, basically using the explosion of these as one of the main reasons why we need structural types with our closures. Presumably boxing and autoboxing don't need to access memory, and, thus, probably have an insignificant (not to mention probably entirely removable via JIT) performance cost associated with them. Has anyone checked what happens when you cut down jsr166z's types by only have the generic variant? So, Instead of: Ops.LongMaxReducer, just stick with: Ops.MaxReducer, and instead of: ParallelDoubleArray just go with: ParallelArray Another point I'm noticing when looking through PA's classes is that a lot of suggested duplication is unfair reasoning. For example, PA has separate interfaces for MinReducer and MaxReducer. They are both SAMs with the same signature on the one method. Clearly the design of PA fundamentally disagrees with the notion that, for situations where closures work better, giving the types of the closures a name and a place for javadoc is not useful. This argument is espoused by many BGGA fans, for example here: http://weblogs.java.net/blog/brucechapman/archive/2008/02/bgga_fud_bustin.html Between PA's design aesthetic, and (hopefully) the ability to cut down PA's typeset to less than half of what it has now by getting rid of the primitive versions and relying on generics parameters instead, it seems target-typing closures to a named type instead of introducing structural types should be considered. --Reinier Zwitserloot 2009/11/22 Kochurov Alexander > Gentlemens, > > what about introducing boxing/unboxing for functional types? > > As Java generics don't allow us to use primitive types as type parameters, > all java implementations of collection algorithms (such as map, fold, > filter, etc.) would possibly use wrapper types such as Integer, Float and > function types with wrapper arguments. > > So it would be great if every function type with argument types A[1], > A[2],.. A[n] and result type Ra may be implicitly boxed into any other > function type with argument types B[1], B[2], .. B[n] and result type Rb if > either A[i] = B[i] or A[i] can be converted into B[i] using implicit > convertion for any i = 1..n and if it's result type Ra either matches Rb or > may be converted implicitly. > (So I mean not only boxing/unboxing but also widening convertions for > primitive types, e.g. function with result of short may be converted > implicitly into function which returns int, long, float, double, Short, > Integer, Long, Float, Double but not byte, Byte, etc.) > > Alex > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091122/b9701eae/attachment.html From tronicek at fit.cvut.cz Sun Nov 22 03:46:01 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Sun, 22 Nov 2009 12:46:01 +0100 Subject: Syntax... (errata) In-Reply-To: <560fb5ed0911220217o23b98c80wc4bcf9f86fd5f5f9@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> <4B074859.2050107@univ-mlv.fr> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <4B083852.8090906@gmail.com> <398c4a165428ad5f8adf9f3097177b84.squirrel@imap.fit.cvut.cz> <560fb5ed0911220217o23b98c80wc4bcf9f86fd5f5f9@mail.gmail.com> Message-ID: <5b64245b60020cff4d5e613c2efc5c93.squirrel@imap.fit.cvut.cz> It is not only 'fun' vs. '#'. Compare: #String(int, double) throws IOException | InterruptedException p; vs. fun String p(int, double) throws IOException, InterruptedException; or #String p(int, double) throws IOException, InterruptedException; And p.invoke(42, 3.14); vs. p(42, 3.14); Z. -- Zdenek Tronicek FIT CTU in Prague Reinier Zwitserloot napsal(a): > fun? + a few million to the idea of using 'fn' or # instead. > > Zdenek, I'm guessing that you find: > > fun X => {codeblock} > > readable primarily because you have experience with plenty of other > languages. Java users that don't take an interest to closures-dev usually > don't have that experience, so any statements about whether something > looks > 'natural' or 'feels java-like' by any of us is probably not worth all that > much. We've been tainted by too much knowledge :) > > --Reinier Zwitserloot > > On Sun, Nov 22, 2009 at 10:25 AM, wrote: > >> Hi, >> >> this is very readable for me. In grammar, commas between params are >> missing and there is ambiguity: >> >> fun X => { throw new NullPointerException(); } >> >> because X can be a name of closure or a return type. But probably this >> is >> not crucial, because anonymous lambda and named functions will not >> appear >> on the same place. >> >> Z. >> -- >> Zdenek Tronicek >> FIT CTU in Prague >> >> >> Vladimir Kirichenko napsal(a): >> >> > a) Anonymous lambda: >> > >> > EBNF: >> > >> > /AnonymousLambda/: >> > fun /TypeSpec/ => /Body/ >> > /TypeSpec/: >> > /Type/? /ParamsSpec/? /ThrowsSpec/? >> > /ParamsSpec/: >> > ( /Param/+ ) >> > /Param/: >> > /Type/ ID >> > /ThrowsSpec/: >> > throws /ExceptionType/+ >> > /Body/: >> > /Expression/ | { /StatementList/ } >> > >> ... >> > b) Named function declaration: >> > >> > It's very similar to the anonymous lambda except it has identifier, >> uses >> > assignment operator instead of implication ( => ), and has no param >> > identifiers: >> > >> > EBNF: >> > >> > /Function/: >> > fun /TypeSpec/ /Assignment/? >> > /Assignment/: >> > = /AnonymousLambda/ >> > /TypeSpec/: >> > /Type/? ID /ParamsSpec/? /ThrowsSpec/? >> > /ParamsSpec/: >> > ( /Type/+ ) >> > /ThrowsSpec/: >> > throws /ExceptionType/+ >> > >> ... >> > c) Named function declaration aka short form. Difference between c) >> and >> > b) are IDs in param spec and implication (=>) instead of assignment. >> So >> > basically it's Anonymous lambda with name: >> > >> > EBNF: >> > >> > /Function/: >> > fun /TypeSpec/ => /Body/ >> > /TypeSpec/: >> > /Type/? ID /ParamsSpec/? /ThrowsSpec/? >> > /ParamsSpec/: >> > ( /Param/+ ) >> > /Param/: >> > /Type/ ID >> > /ThrowsSpec/: >> > throws /ExceptionType/+ >> > /Body/: >> > /Expression/ | { /StatementList/ } >> > >> >> > From vladimir.kirichenko at gmail.com Sun Nov 22 04:09:24 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Sun, 22 Nov 2009 14:09:24 +0200 Subject: Syntax... (errata) In-Reply-To: <5b64245b60020cff4d5e613c2efc5c93.squirrel@imap.fit.cvut.cz> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <15e8b9d20911201518h64378a3eodcaad351d812a8fa@mail.gmail.com> <4B074859.2050107@univ-mlv.fr> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <4B083852.8090906@gmail.com> <398c4a165428ad5f8adf9f3097177b84.squirrel@imap.fit.cvut.cz> <560fb5ed0911220217o23b98c80wc4bcf9f86fd5f5f9@mail.gmail.com> <5b64245b60020cff4d5e613c2efc5c93.squirrel@imap.fit.cvut.cz> Message-ID: <4B0929F4.8030602@gmail.com> tronicek at fit.cvut.cz wrote: > It is not only 'fun' vs. '#'. Compare: > > #String(int, double) throws IOException | InterruptedException p; > > vs. > > fun String p(int, double) throws IOException, InterruptedException; Exactly. In my proposal definition of the function is an exact match to definition of regular java method. class A { public static int staticMethod(int x) throws Exception {...} public static fun int staticFun(int x) throws Exception => {...} } > And > > p.invoke(42, 3.14); > > vs. > > p(42, 3.14); if would be really great if invoke in the class implementing marker interface java.lang.Function could be invoked using simple syntax. And if "invoke" will be named "apply" for transparent Scala interop - in would be superb:) -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091122/58c040eb/attachment.bin From reinier at zwitserloot.com Sun Nov 22 04:48:51 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 22 Nov 2009 13:48:51 +0100 Subject: Syntax... (errata) In-Reply-To: <5b64245b60020cff4d5e613c2efc5c93.squirrel@imap.fit.cvut.cz> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <4B083852.8090906@gmail.com> <398c4a165428ad5f8adf9f3097177b84.squirrel@imap.fit.cvut.cz> <560fb5ed0911220217o23b98c80wc4bcf9f86fd5f5f9@mail.gmail.com> <5b64245b60020cff4d5e613c2efc5c93.squirrel@imap.fit.cvut.cz> Message-ID: <560fb5ed0911220448h40d888ft561bf345c2b2d9e3@mail.gmail.com> Sure, there are plenty of syntax concerns, but in most proposals, there's some sort of unique symbol or keyword used to mark a closure. I vote that we use 'fn' or '#' and not 'fun', because that looks, frankly, ridiculous to me. A taste thing I guess. So, consider it just a vote, no more, and no less. The problem with: p(1, 2) where 'p' is an identifier pointing at a closure, is namespace collisions. Java has separate namespaces for variables versus method calls, so when the compiler meets a statement of the form: identifier '(' paramList[opt] ')' it doesn't know what to do. There are 3 possible rules, all of which suck (IMO): rule #1: If 'identifier' refers to a legal variable name, then attempt to run 'apply closure' on it. Otherwise, check if there's a method named 'identifier' and run that instead. This will totally break backwards compatibility, as now variable names shadow method names. Unacceptable. Letting the compiler check both and generate an error on conflict does not avoid breaking backwards compatibility. rule #2: If 'identifier' refers to an existing variable name *whose type is a closure*, run apply closure on it. Otherwise (so, if the identifier isn't a variable name in the current lexical scope, or it is, but that variable's type isn't a closure type), check the method namespace. Technically backwards/migration compatible, but this would mean that changing the type of a variable pointing at a closure from the closure type to 'Object' makes the code do something else and may not even generate an error. Highly undesirable. This idea might be acceptable if the closure type space is entirely separate (so, #(int)int would not be a subtype of java.lang.Object). rule #3: Like rule #1, except reverse priorities: If there's a method and a variable both with the same name, and you write 'name(params);', then the method is run, not the closure. Backwards compatible, but will probably be rather confusing, and sets a weird precedent: In java, you can usually use the same name for variables as for methods, except when these variables are to be used for closures, then you can't. Apologies if this issue has been raised before on closures-dev, or if someone has found a solution. If not, I propose we relegate the idea of applying closures via 'varname '(' params[opt] ')' into the dustbin. Is writing 'varname.apply/invoke/run(params);' really that much worse? --Reinier Zwitserloot On Sun, Nov 22, 2009 at 12:46 PM, wrote: > It is not only 'fun' vs. '#'. Compare: > > #String(int, double) throws IOException | InterruptedException p; > > vs. > > fun String p(int, double) throws IOException, InterruptedException; > > or > > #String p(int, double) throws IOException, InterruptedException; > > > And > > p.invoke(42, 3.14); > > vs. > > p(42, 3.14); > > > Z. > -- > Zdenek Tronicek > FIT CTU in Prague > > > Reinier Zwitserloot napsal(a): > > fun? + a few million to the idea of using 'fn' or # instead. > > > > Zdenek, I'm guessing that you find: > > > > fun X => {codeblock} > > > > readable primarily because you have experience with plenty of other > > languages. Java users that don't take an interest to closures-dev usually > > don't have that experience, so any statements about whether something > > looks > > 'natural' or 'feels java-like' by any of us is probably not worth all > that > > much. We've been tainted by too much knowledge :) > > > > --Reinier Zwitserloot > > > > On Sun, Nov 22, 2009 at 10:25 AM, wrote: > > > >> Hi, > >> > >> this is very readable for me. In grammar, commas between params are > >> missing and there is ambiguity: > >> > >> fun X => { throw new NullPointerException(); } > >> > >> because X can be a name of closure or a return type. But probably this > >> is > >> not crucial, because anonymous lambda and named functions will not > >> appear > >> on the same place. > >> > >> Z. > >> -- > >> Zdenek Tronicek > >> FIT CTU in Prague > >> > >> > >> Vladimir Kirichenko napsal(a): > >> > >> > a) Anonymous lambda: > >> > > >> > EBNF: > >> > > >> > /AnonymousLambda/: > >> > fun /TypeSpec/ => /Body/ > >> > /TypeSpec/: > >> > /Type/? /ParamsSpec/? /ThrowsSpec/? > >> > /ParamsSpec/: > >> > ( /Param/+ ) > >> > /Param/: > >> > /Type/ ID > >> > /ThrowsSpec/: > >> > throws /ExceptionType/+ > >> > /Body/: > >> > /Expression/ | { /StatementList/ } > >> > > >> ... > >> > b) Named function declaration: > >> > > >> > It's very similar to the anonymous lambda except it has identifier, > >> uses > >> > assignment operator instead of implication ( => ), and has no param > >> > identifiers: > >> > > >> > EBNF: > >> > > >> > /Function/: > >> > fun /TypeSpec/ /Assignment/? > >> > /Assignment/: > >> > = /AnonymousLambda/ > >> > /TypeSpec/: > >> > /Type/? ID /ParamsSpec/? /ThrowsSpec/? > >> > /ParamsSpec/: > >> > ( /Type/+ ) > >> > /ThrowsSpec/: > >> > throws /ExceptionType/+ > >> > > >> ... > >> > c) Named function declaration aka short form. Difference between c) > >> and > >> > b) are IDs in param spec and implication (=>) instead of assignment. > >> So > >> > basically it's Anonymous lambda with name: > >> > > >> > EBNF: > >> > > >> > /Function/: > >> > fun /TypeSpec/ => /Body/ > >> > /TypeSpec/: > >> > /Type/? ID /ParamsSpec/? /ThrowsSpec/? > >> > /ParamsSpec/: > >> > ( /Param/+ ) > >> > /Param/: > >> > /Type/ ID > >> > /ThrowsSpec/: > >> > throws /ExceptionType/+ > >> > /Body/: > >> > /Expression/ | { /StatementList/ } > >> > > >> > >> > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091122/b0e91e53/attachment-0001.html From ali.ebrahimi1781 at gmail.com Sun Nov 22 04:54:29 2009 From: ali.ebrahimi1781 at gmail.com (Ali Ebrahimi) Date: Sun, 22 Nov 2009 16:24:29 +0330 Subject: First code then select Syntax Message-ID: <5ab441490911220454r48fdaeddmf77c4d753f7d637a@mail.gmail.com> Hi All. Just compare the different versions of following sample codes And then vote them: -------------------------------------------------------------- Sample code 1: new language construct with closures version 1: int x=0; loop{ //do some thing x++; } unitl {x == 10} version 2: int x = 0; loop({ //do some thing x++; }).until( {x == 10}); version 3: int x = 0; loop((){ //do some thing x++; }).until( (){x == 10}); version 4: int x = 0; loop(#(){ //do some thing x++; }).until( #(){x == 10}); -------------------------------------------------------------- Sample code 2: query on Collections version 1: from myCollection where x > 10 select x +10 ; version 2: from myCollection where {x > 10} select {x+10}; version 3: from myCollection where (int x) x > 10 select (int x) x+10; version 4: from myCollection where (int x){ x > 10} select (int x){ x+10}; version 5: from(myCollection ).where( (int x){ x > 10}).select( (int x){ x+10}); version 6: from(myCollection ).where( #(int x){ x > 10}).select( #(int x){ x+10}); .. You can add your own versions to list. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091122/4a871f22/attachment.html From vladimir.kirichenko at gmail.com Sun Nov 22 05:41:23 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Sun, 22 Nov 2009 15:41:23 +0200 Subject: Syntax... (errata) In-Reply-To: <560fb5ed0911220448h40d888ft561bf345c2b2d9e3@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <4B083852.8090906@gmail.com> <398c4a165428ad5f8adf9f3097177b84.squirrel@imap.fit.cvut.cz> <560fb5ed0911220217o23b98c80wc4bcf9f86fd5f5f9@mail.gmail.com> <5b64245b60020cff4d5e613c2efc5c93.squirrel@imap.fit.cvut.cz> <560fb5ed0911220448h40d888ft561bf345c2b2d9e3@mail.gmail.com> Message-ID: <4B093F83.9030303@gmail.com> Reinier Zwitserloot wrote: > Sure, there are plenty of syntax concerns, but in most proposals, > there's some sort of unique symbol or keyword used to mark a closure. I > vote that we use 'fn' or '#' and not 'fun', because that looks, frankly, > ridiculous to me. fn is a sorta abbreviation of fun. What is the difference? "fun" used in ocaml, erlang. > The problem with: > > p(1, 2) There are no problems here. First at all there would not be backward compatibility issues because there is no existing code that would not compile and run exactly the same with new compiler. The name resolution is not a problem to - a lots of languages (starting from C, any languages with function as First-Class Object, or function references, etc ) dealing with this stuff successfully. Rule is simple: same id of function variable and method name - name clash, compilation error. So there is no way you could compile this way anything, and there is no preexisting code that does not fit this rule. -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091122/e575ea2e/attachment.bin From vladimir.kirichenko at gmail.com Sun Nov 22 05:55:52 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Sun, 22 Nov 2009 15:55:52 +0200 Subject: First code then select Syntax In-Reply-To: <5ab441490911220454r48fdaeddmf77c4d753f7d637a@mail.gmail.com> References: <5ab441490911220454r48fdaeddmf77c4d753f7d637a@mail.gmail.com> Message-ID: <4B0942E8.8070502@gmail.com> Ali Ebrahimi wrote: > Hi All. > > Just compare the different versions of following sample codes And then > vote them: Those are not realistic. There is no LINQ in java, it's noway parens going to be optional, general language design is not going to be changed backward incompatible, and custom control structures should not be primary goal of this. So here are mine. 1. Anonymous: a) array.sort(#boolean(int a, int b) a > b); b) array.sort(fun boolean(int a, int b) => a > b); 2. Named: a) #boolean(int,int) p = #boolean(int a, int b) a > b; array.sort(p); b) ^boolean(int,int) p = #boolean(int a, int b) a > b; array.sort(p); c) fun boolean p(int a,int b) => a > b; array.sort(p); -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091122/8e30b1c2/attachment.bin From ali.ebrahimi1781 at gmail.com Sun Nov 22 07:05:11 2009 From: ali.ebrahimi1781 at gmail.com (Ali Ebrahimi) Date: Sun, 22 Nov 2009 18:35:11 +0330 Subject: First code then select Syntax In-Reply-To: <4B0942E8.8070502@gmail.com> References: <5ab441490911220454r48fdaeddmf77c4d753f7d637a@mail.gmail.com> <4B0942E8.8070502@gmail.com> Message-ID: <5ab441490911220705s22347984lfec2519c138e352f@mail.gmail.com> On Sun, Nov 22, 2009 at 5:25 PM, Vladimir Kirichenko < vladimir.kirichenko at gmail.com> wrote: > Ali Ebrahimi wrote: > > Hi All. > > > > Just compare the different versions of following sample codes And then > > vote them: > > Those are not realistic. There is no LINQ in java, But Criteria API exists in java (JPA 2). I think lang features must be help to highly readable codes. it's noway parens > going to be optional, general language design is not going to be changed > backward incompatible, and custom control structures should not be > primary goal of this. > > So here are mine. > > 1. Anonymous: > > a) > array.sort(#boolean(int a, int b) a > b); > > b) > array.sort(fun boolean(int a, int b) => a > b); > c) array.sort((int a, int b) a > b); > > 2. Named: > > a) > #boolean(int,int) p = #boolean(int a, int b) a > b; > array.sort(p); > > b) > ^boolean(int,int) p = #boolean(int a, int b) a > b; > array.sort(p); > > c) > fun boolean p(int a,int b) => a > b; > array.sort(p); > d) boolean(int,int) p = (int a, int b) a > b; > -- > Best Regards, > Vladimir Kirichenko > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091122/16787c4c/attachment.html From vladimir.kirichenko at gmail.com Sun Nov 22 07:51:21 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Sun, 22 Nov 2009 17:51:21 +0200 Subject: First code then select Syntax In-Reply-To: <5ab441490911220705s22347984lfec2519c138e352f@mail.gmail.com> References: <5ab441490911220454r48fdaeddmf77c4d753f7d637a@mail.gmail.com> <4B0942E8.8070502@gmail.com> <5ab441490911220705s22347984lfec2519c138e352f@mail.gmail.com> Message-ID: <4B095DF9.40306@gmail.com> Ali Ebrahimi wrote: > But Criteria API exists in java (JPA 2). > > I think lang features must be help to highly readable codes. It requires explression trees implementation and is not a part of current discussion. And anyway "SQL-like" syntax is not the best way to do it. Personally I dont like the way it is in C#. > c) array.sort((int a, int b) a > b); > d) boolean(int,int) p = (int a, int b) a > b; no return type. If it's inferred, why not inferring argument types? And also try it for, you'll see a problem: fun boolean p => true; -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091122/13c7d739/attachment.bin From reinier at zwitserloot.com Sun Nov 22 07:56:45 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 22 Nov 2009 16:56:45 +0100 Subject: Syntax... (errata) In-Reply-To: <4B093F83.9030303@gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <4B083852.8090906@gmail.com> <398c4a165428ad5f8adf9f3097177b84.squirrel@imap.fit.cvut.cz> <560fb5ed0911220217o23b98c80wc4bcf9f86fd5f5f9@mail.gmail.com> <5b64245b60020cff4d5e613c2efc5c93.squirrel@imap.fit.cvut.cz> <560fb5ed0911220448h40d888ft561bf345c2b2d9e3@mail.gmail.com> <4B093F83.9030303@gmail.com> Message-ID: <560fb5ed0911220756i52c5ac9dya53bf7bbcb0d30a2@mail.gmail.com> As I said, personal taste. I think 'fun' looks 'funny', mostly because of the 'fun' being an english word and all. Also, at least in mathematical circles, I see a lot more 'fn' than fun. On a perhaps more pragmatic note, java has absolutely no shortened keywords right now. All keywords are written out in full. So, we have 'synchronized', and not 'sync'. We have 'protected' and not 'prot', 'extends' and 'implements' instead of 'ext' or 'impl' or '::' or some other symbol. So, if it is to be a keyword instead of a symbol, then 'function' seems to be more in line with existing java keywords than 'fun'. --Reinier Zwitserloot On Sun, Nov 22, 2009 at 2:41 PM, Vladimir Kirichenko < vladimir.kirichenko at gmail.com> wrote: > Reinier Zwitserloot wrote: > > Sure, there are plenty of syntax concerns, but in most proposals, > > there's some sort of unique symbol or keyword used to mark a closure. I > > vote that we use 'fn' or '#' and not 'fun', because that looks, frankly, > > ridiculous to me. > > fn is a sorta abbreviation of fun. What is the difference? > > "fun" used in ocaml, erlang. > > > > > The problem with: > > > > p(1, 2) > > There are no problems here. > > First at all there would not be backward compatibility issues because > there is no existing code that would not compile and run exactly the > same with new compiler. > > The name resolution is not a problem to - a lots of languages (starting > from C, any languages with function as First-Class Object, or function > references, etc ) dealing with this stuff successfully. > > Rule is simple: same id of function variable and method name - name > clash, compilation error. > > So there is no way you could compile this way anything, and there is no > preexisting code that does not fit this rule. > > > > -- > Best Regards, > Vladimir Kirichenko > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091122/03a5e51b/attachment.html From vladimir.kirichenko at gmail.com Sun Nov 22 08:16:52 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Sun, 22 Nov 2009 18:16:52 +0200 Subject: Syntax... (errata) In-Reply-To: <560fb5ed0911220756i52c5ac9dya53bf7bbcb0d30a2@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <4B083852.8090906@gmail.com> <398c4a165428ad5f8adf9f3097177b84.squirrel@imap.fit.cvut.cz> <560fb5ed0911220217o23b98c80wc4bcf9f86fd5f5f9@mail.gmail.com> <5b64245b60020cff4d5e613c2efc5c93.squirrel@imap.fit.cvut.cz> <560fb5ed0911220448h40d888ft561bf345c2b2d9e3@mail.gmail.com> <4B093F83.9030303@gmail.com> <560fb5ed0911220756i52c5ac9dya53bf7bbcb0d30a2@mail.gmail.com> Message-ID: <4B0963F4.2030901@gmail.com> Reinier Zwitserloot wrote: > On a perhaps more > pragmatic note, java has absolutely no shortened keywords right now. All > keywords are written out in full. enum, strictfp, int :) > So, we have 'synchronized', and not 'sync'. We have 'protected' and not > 'prot', 'extends' and 'implements' instead of 'ext' or 'impl' or '::' or > some other symbol. The reason is why fun shortened from function is practical - most usages of lambda are in-place. BTW one more language with "fun" is F# (which is not a surprise). So we have erlang, ocaml, F# which makes more weighted that "fun" is to be usual practice with lambda. > So, if it is to be a keyword instead of a symbol, then 'function' seems > to be more in line with existing java keywords than 'fun'. it's ok too, JavaScript has it, but it's soo looooong.... :) -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091122/1c3ec31b/attachment-0001.bin From neal at gafter.com Sun Nov 22 08:25:28 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 22 Nov 2009 08:25:28 -0800 Subject: Boxing function types In-Reply-To: References: Message-ID: <15e8b9d20911220825r25a5ceaeq7f8e338fa89dc81e@mail.gmail.com> Kochurov- This is an interesting idea, but you have the variance backwards for argument types. The argument types in the function on the right-hand-side of the assignment must be subtypes (not supertypes) of the argument types in the function on the left-hand-side. Cheers, Neal 2009/11/21 Kochurov Alexander > Gentlemens, > > what about introducing boxing/unboxing for functional types? > > As Java generics don't allow us to use primitive types as type parameters, > all java implementations of collection algorithms (such as map, fold, > filter, etc.) would possibly use wrapper types such as Integer, Float and > function types with wrapper arguments. > > So it would be great if every function type with argument types A[1], > A[2],.. A[n] and result type Ra may be implicitly boxed into any other > function type with argument types B[1], B[2], .. B[n] and result type Rb if > either A[i] = B[i] or A[i] can be converted into B[i] using implicit > convertion for any i = 1..n and if it's result type Ra either matches Rb or > may be converted implicitly. > (So I mean not only boxing/unboxing but also widening convertions for > primitive types, e.g. function with result of short may be converted > implicitly into function which returns int, long, float, double, Short, > Integer, Long, Float, Double but not byte, Byte, etc.) > > Alex > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091122/78e253bf/attachment.html From peter.levart at gmail.com Sun Nov 22 08:30:46 2009 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 22 Nov 2009 17:30:46 +0100 Subject: Syntax... In-Reply-To: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> Message-ID: <200911221730.46242.peter.levart@gmail.com> One point to consider is that it is always easier to type SHIFT-ed characters that are closer to either left or right SHIFT key than those that are further. I have to use both hands to type '^' and that slows me down. If lambdas get into Java I'm going to be typing lots of '#'s (or '^'s)... Peter On Friday 20 November 2009 20:44:25 Neal Gafter wrote: > How would you feel about using ^ instead of # for function types and > lambda > From neal at gafter.com Sun Nov 22 08:37:11 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 22 Nov 2009 08:37:11 -0800 Subject: Boxing function types In-Reply-To: <560fb5ed0911220233x44a01ec5w3aa416e8ff4189c0@mail.gmail.com> References: <560fb5ed0911220233x44a01ec5w3aa416e8ff4189c0@mail.gmail.com> Message-ID: <15e8b9d20911220837jb0243a5t28ddb6f05919f9c9@mail.gmail.com> On Sun, Nov 22, 2009 at 2:33 AM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > Another point I'm noticing when looking through PA's classes is that a lot > of suggested duplication is unfair reasoning. For example, PA has separate > interfaces for MinReducer and MaxReducer. They are both SAMs with the same > signature on the one method. Clearly the design of PA fundamentally > disagrees with the notion that, for situations where closures work better, > giving the types of the closures a name and a place for javadoc is not > useful. > Reinier- MinReducer and MaxReducer were concrete classes, not abstract interfaces. The BGGA port of ForkJoin did not change the shape of those classes: http://www.javac.info/jsr166z/jsr166z/forkjoin/Ops.MaxReducer.html. However, those classes are no longer part of the ParallelArray API set, replaced by two static methods: http://gee.cs.oswego.edu/dl/jsr166/dist/extra166ydocs/extra166y/CommonOps.html#maxReducer%28java.util.Comparator%29 . Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091122/e2c42503/attachment.html From jp at hapra.at Sun Nov 22 09:46:13 2009 From: jp at hapra.at (Jakob Praher) Date: Sun, 22 Nov 2009 18:46:13 +0100 Subject: Syntax... In-Reply-To: <15e8b9d20911210928t47aecc24v9b031fe1d7f2b381@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <1af45fa312bda7b03856555e3848efed.squirrel@imap.fit.cvut.cz> <4B07E965.1070907@hapra.at> <15e8b9d20911210810l7f83687duc21800e320acd844@mail.gmail.com> <4B0820D7.1040809@hapra.at> <15e8b9d20911210928t47aecc24v9b031fe1d7f2b381@mail.gmail.com> Message-ID: <4B0978E5.70703@hapra.at> Daer Neal, thanks for your reply. Neal Gafter schrieb: > On Sat, Nov 21, 2009 at 9:18 AM, Jakob Praher > wrote: > > Why did you change to # for introducing function types and > creating closures? > > > Because the # syntax for references to methods is already part of the > Java mindset from its use in javadoc. That naturally generalizes to a > corresponding syntax for lambdas and therefore function types. IMHO it is not. # for me stems from the fact that javadoc renders a class as a page and uses HTML anchor names (as URL fragments) to identify subelements of that page. # is also used for fields e.g.: http://java.sun.com/javase/6/docs/api/java/lang/System.html#err Furthermore it is already used heavily having different meaning in other languages: * Shell scripts and a lot of scripting languages use it as a comment * It is often used as preprocessor escape (not only in C/C++/C#) * The Java Server Faces expression language uses it as value binding (denoting more or less evaluation/dereferencing, not closure creation) > But I think having to write: > > int[] result = x.select( #(int c) c % 2 == 0) > > is harder to read. Don't you think? > > > Not especially. > Accpeted. It is subjective. Personally I have difficulties with that syntax. Also note that the D language (which is syntactically quite similar to Java) is able to create anonymous functions/closures in the following way [1]: FunctionLiteral: function Typeopt ParameterAttributes opt FunctionBody delegate Typeopt ParameterAttributes opt FunctionBody ParameterAttributes FunctionBody FunctionBody ParameterAttributes: Parameters Parameters FunctionAttributes Which means the following is also valid in D: int abc(int delegate(long i)); void test() { int b = 3; abc( (long c) { return 6 + b; } ); } Plus the ability to omit the the argument list, if there are no parameters: double test() { double d = 7.6; float f = 2.3; void loop(int k, int j, void delegate() statement) { for (int i = k; i < j; i++) { statement(); } } loop(5, 100, { d += 1; } ); loop(3, 10, { f += 3; } ); return d + f; } --Jakob [1] http://www.digitalmars.com/d/2.0/expression.html#FunctionLiteral From ali.ebrahimi1781 at gmail.com Sun Nov 22 20:07:32 2009 From: ali.ebrahimi1781 at gmail.com (Ali Ebrahimi) Date: Mon, 23 Nov 2009 07:37:32 +0330 Subject: First code then select Syntax In-Reply-To: <4B095DF9.40306@gmail.com> References: <5ab441490911220454r48fdaeddmf77c4d753f7d637a@mail.gmail.com> <4B0942E8.8070502@gmail.com> <5ab441490911220705s22347984lfec2519c138e352f@mail.gmail.com> <4B095DF9.40306@gmail.com> Message-ID: <5ab441490911222007ic64c4cfr234216d791ba8521@mail.gmail.com> On Sun, Nov 22, 2009 at 7:21 PM, Vladimir Kirichenko < vladimir.kirichenko at gmail.com> wrote: > Ali Ebrahimi wrote: > > > But Criteria API exists in java (JPA 2). > > > > I think lang features must be help to highly readable codes. > > It requires explression trees implementation and is not a part of > current discussion. And anyway "SQL-like" syntax is not the best way to > do it. Personally I dont like the way it is in C#. > > > c) array.sort((int a, int b) a > b); > > d) boolean(int,int) p = (int a, int b) a > b; > > no return type. If it's inferred, why not inferring argument types? > In current Neal's proposal return types can be inferred: #int(int,int) plus = #(int x, int y) x+y; > And also try it for, you'll see a problem: > > fun boolean p => true; > > I disagree with adding new keyword. > > -- > Best Regards, > Vladimir Kirichenko > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091123/ca70f930/attachment.html From tronicek at fit.cvut.cz Sun Nov 22 23:05:10 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Mon, 23 Nov 2009 08:05:10 +0100 Subject: First code then select Syntax In-Reply-To: <5ab441490911222007ic64c4cfr234216d791ba8521@mail.gmail.com> References: <5ab441490911220454r48fdaeddmf77c4d753f7d637a@mail.gmail.com> <4B0942E8.8070502@gmail.com> <5ab441490911220705s22347984lfec2519c138e352f@mail.gmail.com> <4B095DF9.40306@gmail.com> <5ab441490911222007ic64c4cfr234216d791ba8521@mail.gmail.com> Message-ID: Ali Ebrahimi napsal(a): > > In current Neal's proposal return types can be inferred: > > #int(int,int) plus = #(int x, int y) x+y; > In current proposal (v0.6) the return type is always inferred. It cannot be stated as part of lambda and it is questionable if this is better than to have it in declaration. Z. -- Zdenek Tronicek FIT CTU in Prague From reinier at zwitserloot.com Mon Nov 23 06:04:23 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 23 Nov 2009 15:04:23 +0100 Subject: Boxing function types In-Reply-To: <3dd3f56a0911230216p7edd225dwee966c20147e1029@mail.gmail.com> References: <3dd3f56a0911230216p7edd225dwee966c20147e1029@mail.gmail.com> Message-ID: <560fb5ed0911230604o49ec32b0od8864d10d5826b76@mail.gmail.com> co- and contravariance is an intrinsic complexity inherent in the concept of generics. Generics without variance is not a good idea. If my memory serves, BGGA and the new CFJ offshoot of that will actually generate the appropriate type, including with non-boxing primitives, on the fly, so an #(int, int)int becomes a FunctionIII, not a Function. PA's API will still need to deal with the explosion of types caused by primitives, so exactly how much of a benefit this really is, is debatable. If you have the time, a test to compare the speed of late unboxed->boxed->unboxed conversion (which would closely parallel what PA would do if its closures are parameterized instead of using direct types like FunctionIII) against straight passing with PA would be interesting. Brian Goetz' theory on where CPUs are headed (devoxx talk) suggests that the penalty of unboxing->boxing->unboxing is statistically insignificant, as its entirely limited to a single core, and is unlikely to cause cache misses. It would be nice if we had practical proof of whether it does, or doesn't, matter. Technically, if it does, it may still be turned into a (performance-wise) inconsequential waste of cycles with some JDK optimizations. --Reinier Zwitserloot On Mon, Nov 23, 2009 at 11:16 AM, Howard Lovatt wrote: > I was a little surprised to see ParallelArray used as the poster child for > function types (structural typing). Having used the library a little I can't > see that function types would make much of a difference (note I am not > saying that shorter inner class/closure syntax wouldn't make a difference). > Having the JavaDoc for the different op types is useful and it also helps > the IDE. Also I don't think you will be able to replace the primitive > versions with generic versions, hence the saving of interface number will > not be that dramatic. The primitive version, ParallelDoubleArray, is > struggling already to show speedup on the code I am trying, so I find it > hard to imagine that the boxing version will fair well. > > Why not introduce something close to CISE and see if we really need all the > extra stuff. I think the big drive is for shorter syntax for inner classes > and for some internal iterators on lists, perhaps write access to captured > variables. So long as we don't preclude adding the other stuff at a latter > date; I think it is best to be cautious. Generics were basically a good idea > that got out of hand and made too radical a change (variance) - lets not > make the same mistake again. > > As an aside. The code I am porting is a reasonably standard parallel > benchmark used in weather prediction/climate modeling circles for selecting > parallel Fortran compilers and parallel hardware. The code is a finite > difference calculation, a common calculation type for weather/climate. This > benchmark, amongst others, was used by the company I work for to buy a share > in new supercomputer recently (they chose a Sun machine - > http://www.smh.com.au/technology/sci-tech/australias-new-supercomputer-outflops-the-lot-20091116-ihew.html). > I was not part of the decision process, which was joint across a number of > organizations, so I can't say how influential the benchmark was, other than > it is one that the selection group within my company quite like. > > -- Howard. > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091123/02e7d362/attachment.html From howard.lovatt at iee.org Mon Nov 23 02:16:46 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Mon, 23 Nov 2009 11:16:46 +0100 Subject: Boxing function types Message-ID: <3dd3f56a0911230216p7edd225dwee966c20147e1029@mail.gmail.com> I was a little surprised to see ParallelArray used as the poster child for function types (structural typing). Having used the library a little I can't see that function types would make much of a difference (note I am not saying that shorter inner class/closure syntax wouldn't make a difference). Having the JavaDoc for the different op types is useful and it also helps the IDE. Also I don't think you will be able to replace the primitive versions with generic versions, hence the saving of interface number will not be that dramatic. The primitive version, ParallelDoubleArray, is struggling already to show speedup on the code I am trying, so I find it hard to imagine that the boxing version will fair well. Why not introduce something close to CISE and see if we really need all the extra stuff. I think the big drive is for shorter syntax for inner classes and for some internal iterators on lists, perhaps write access to captured variables. So long as we don't preclude adding the other stuff at a latter date; I think it is best to be cautious. Generics were basically a good idea that got out of hand and made too radical a change (variance) - lets not make the same mistake again. As an aside. The code I am porting is a reasonably standard parallel benchmark used in weather prediction/climate modeling circles for selecting parallel Fortran compilers and parallel hardware. The code is a finite difference calculation, a common calculation type for weather/climate. This benchmark, amongst others, was used by the company I work for to buy a share in new supercomputer recently (they chose a Sun machine - http://www.smh.com.au/technology/sci-tech/australias-new-supercomputer-outflops-the-lot-20091116-ihew.html). I was not part of the decision process, which was joint across a number of organizations, so I can't say how influential the benchmark was, other than it is one that the selection group within my company quite like. -- Howard. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091123/a4ce6b12/attachment.html From howard.lovatt at iee.org Mon Nov 23 03:16:27 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Mon, 23 Nov 2009 12:16:27 +0100 Subject: Syntax... Message-ID: <3dd3f56a0911230316m5427a418xc99ab767c1d68c5e@mail.gmail.com> I think that you need to be careful when adding to a language, the key points are Clarity, Consistency, and Conciseness (in that order of priority). These three 'C's constrain a good addition to the language and can be used to compare competing proposals, i.e. if a proposal has more clarity to the reader of the code it is better, if the clarity id roughly the same then consistency with other language features is important, finally if the other Cs are roughly equal then Conciseness comes into play. For inner classes/closures/lambdas in Java the Cs translate into: 1. Use an unabbreviated keyword, I suggest method (see 2. - I am suggesting inner classes, hence method) - this is both clearer and more consistent with existing Java than other suggestions that use a symbol 2. Use an existing concept, i.e. Inner Classes (they are also more powerful since they enclose both scopes) - this is consistent with the existing language (don't introduce an overlapping concept) 3. Use existing interfaces, i.e. instead of function types (Lambda conversion only to use a BGGA term) - be consistent with the existing language (don't introduce an overlapping concept) NB if you introduce a source statement then you can have a new normal keyword, which would help any proposal a great deal -- Howard. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091123/cf54c0c6/attachment.html From howard.lovatt at iee.org Mon Nov 23 12:24:23 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Mon, 23 Nov 2009 21:24:23 +0100 Subject: Boxing function types In-Reply-To: <560fb5ed0911230604o49ec32b0od8864d10d5826b76@mail.gmail.com> References: <3dd3f56a0911230216p7edd225dwee966c20147e1029@mail.gmail.com> <560fb5ed0911230604o49ec32b0od8864d10d5826b76@mail.gmail.com> Message-ID: <3dd3f56a0911231224x76347e9fld9483dad3d17f4d3@mail.gmail.com> Answers inline below 2009/11/23 Reinier Zwitserloot > co- and contravariance is an intrinsic complexity inherent in the concept > of generics. Generics without variance is not a good idea. I would prefer the functionality of arrays only, i.e. no wild-cards just co-variant generic arguments (see http://www.artima.com/weblogs/viewpost.jsp?thread=222021). > > If my memory serves, BGGA and the new CFJ offshoot of that will actually > generate the appropriate type, including with non-boxing primitives, on the > fly, so an #(int, int)int becomes a FunctionIII, not a Function Integer, Integer>. PA's API will still need to deal with the explosion of > types caused by primitives, so exactly how much of a benefit this really is, > is debatable. > There is also a proposal to allow auto boxing as part of BGGA (suggest in this thread first - I think). > > If you have the time, a test to compare the speed of late > unboxed->boxed->unboxed conversion (which would closely parallel what PA > would do if its closures are parameterized instead of using direct types > like FunctionIII) against straight passing with PA would be interesting. > Brian Goetz' theory on where CPUs are headed (devoxx talk) suggests that the > penalty of unboxing->boxing->unboxing is statistically insignificant, as its > entirely limited to a single core, and is unlikely to cause cache misses. It > would be nice if we had practical proof of whether it does, or doesn't, > matter. Technically, if it does, it may still be turned into a > (performance-wise) inconsequential waste of cycles with some JDK > optimizations. > I did a quick conversion and compared ParallelDoubleArray to ParallelArray and found I lost around 40% of the speed. Brian Goetz could be right though, despite this result, that in the future this gap will narrow. Also the ParallelDoubleArray version is slow to begin with; much slower, factor of 10 slower than single-threaded code on a two core machine! It is therefore difficult to say how useful ParallelDoubleArray is compared with ParallelArray, since I wouldn't use either! The best solution I have found using ParallelArray is a single ParallelArray, where Rows is a data structure containing the rows from all the matrices (so that a single ParallelArray contains all the matrices in the problem). This still isn't that great though, about 5% quicker than single-threaded code on a two core machine. So currently I have reservations about the whole of the ParallelArray package. At the moment I am seeing if I can hand code something using Thread directly that is quicker, if I can do so then I can't see much point in the whole package. At the moment this is still preliminary and I am still hopeful that I can get ParallelArray working better, however I am currently disappointed because a parallel Fortran compiler does a good job on the benchmark. -- Howard. > > --Reinier Zwitserloot > > > > > On Mon, Nov 23, 2009 at 11:16 AM, Howard Lovatt wrote: > >> I was a little surprised to see ParallelArray used as the poster child for >> function types (structural typing). Having used the library a little I can't >> see that function types would make much of a difference (note I am not >> saying that shorter inner class/closure syntax wouldn't make a difference). >> Having the JavaDoc for the different op types is useful and it also helps >> the IDE. Also I don't think you will be able to replace the primitive >> versions with generic versions, hence the saving of interface number will >> not be that dramatic. The primitive version, ParallelDoubleArray, is >> struggling already to show speedup on the code I am trying, so I find it >> hard to imagine that the boxing version will fair well. >> >> Why not introduce something close to CISE and see if we really need all >> the extra stuff. I think the big drive is for shorter syntax for inner >> classes and for some internal iterators on lists, perhaps write access to >> captured variables. So long as we don't preclude adding the other stuff at a >> latter date; I think it is best to be cautious. Generics were basically a >> good idea that got out of hand and made too radical a change (variance) - >> lets not make the same mistake again. >> >> As an aside. The code I am porting is a reasonably standard parallel >> benchmark used in weather prediction/climate modeling circles for selecting >> parallel Fortran compilers and parallel hardware. The code is a finite >> difference calculation, a common calculation type for weather/climate. This >> benchmark, amongst others, was used by the company I work for to buy a share >> in new supercomputer recently (they chose a Sun machine - >> http://www.smh.com.au/technology/sci-tech/australias-new-supercomputer-outflops-the-lot-20091116-ihew.html). >> I was not part of the decision process, which was joint across a number of >> organizations, so I can't say how influential the benchmark was, other than >> it is one that the selection group within my company quite like. >> >> -- Howard. >> > > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > -- -- Howard. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091123/75c49a52/attachment.html From neal at gafter.com Mon Nov 23 12:35:59 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 23 Nov 2009 12:35:59 -0800 Subject: closures after all? In-Reply-To: <63b4e4050911231202x3454427fk3d088adb20e62743@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <997cab100911201635o3e682401k81ca9c9340a5aa37@mail.gmail.com> <15e8b9d20911201650o1d0375dau9d5ae7998e5e8474@mail.gmail.com> <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> <560fb5ed0911210844v93e7830t71d6136bcfe30c61@mail.gmail.com> <63b4e4050911211352pefb9cdaid9d6574d885fa95f@mail.gmail.com> <560fb5ed0911211546q78addf6w96ddb9df9e0525d5@mail.gmail.com> <63b4e4050911230743w51ad619clb78d3b5621210f84@mail.gmail.com> <560fb5ed0911230944j52f0cfc2g5692386ee537e2d3@mail.gmail.com> <63b4e4050911231202x3454427fk3d088adb20e62743@mail.gmail.com> Message-ID: <15e8b9d20911231235v7bc56d1dp614da379e2189133@mail.gmail.com> On Mon, Nov 23, 2009 at 12:02 PM, Tim Peierls wrote: > Here's an imperfect but suggestive analogy: More options in the treatment > of a disease might offer hope to millions, but the physician's job is harder > because she has to evaluate more options in the context of each patient. She > might be glad to be able to offer her patients a promising new therapy, but > she is working longer hours (or seeing fewer patients). > Doctors can do better by their patients by investing more time, with or without new techniques. On the other hand, she may be able to save more lives with the same effort by taking advantage of the new techniques. That seems to be the way it works in practice. Here's another: The addition of a new instrument when scoring a musical > theater piece broadens the palette of available colors. The orchestrator is > probably pleased when the producers cough up the extra dough for the player, > because now he can achieve certain effects more easily, but he also knows > that he'll be working harder -- it's another part to write. (But he's > getting paid more, so he's not going to object. :-)) > The ochestrator can do a better job by investing more time with or without new instruments. On the other hand, he may be able to better achieve his goals with the same cost and effort by taking advantage of a new instrument in place of a more traditional one. Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091123/9cb1e8e9/attachment.html From tim at peierls.net Mon Nov 23 13:30:03 2009 From: tim at peierls.net (Tim Peierls) Date: Mon, 23 Nov 2009 16:30:03 -0500 Subject: closures after all? In-Reply-To: <15e8b9d20911231235v7bc56d1dp614da379e2189133@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911201650o1d0375dau9d5ae7998e5e8474@mail.gmail.com> <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> <560fb5ed0911210844v93e7830t71d6136bcfe30c61@mail.gmail.com> <63b4e4050911211352pefb9cdaid9d6574d885fa95f@mail.gmail.com> <560fb5ed0911211546q78addf6w96ddb9df9e0525d5@mail.gmail.com> <63b4e4050911230743w51ad619clb78d3b5621210f84@mail.gmail.com> <560fb5ed0911230944j52f0cfc2g5692386ee537e2d3@mail.gmail.com> <63b4e4050911231202x3454427fk3d088adb20e62743@mail.gmail.com> <15e8b9d20911231235v7bc56d1dp614da379e2189133@mail.gmail.com> Message-ID: <63b4e4050911231330l5e906d89wdaba5a05b07aaaee@mail.gmail.com> On Mon, Nov 23, 2009 at 3:35 PM, Neal Gafter wrote: > On Mon, Nov 23, 2009 at 12:02 PM, Tim Peierls wrote: > >> Here's an imperfect but suggestive analogy: More options in the treatment >> of a disease might offer hope to millions, but the physician's job is harder >> because she has to evaluate more options in the context of each patient. She >> might be glad to be able to offer her patients a promising new therapy, but >> she is working longer hours (or seeing fewer patients). >> > > Doctors can do better by their patients by investing more time, with or > without new techniques. On the other hand, she may be able to save more > lives with the same effort by taking advantage of the new techniques. That > seems to be the way it works in practice. > Not the way the physicians I know talk about it. A new technique can be a great boon, but in practice it means more work for physicians. My wife, a physician, reacts to each new development with deep ambivalence: it's wonderful to have that new option, but now she has more to learn, and her list of things to check off for each patient just got that much longer. OTOH, she's terrible at API design. :-) > Here's another: The addition of a new instrument when scoring a musical >> theater piece broadens the palette of available colors. The orchestrator is >> probably pleased when the producers cough up the extra dough for the player, >> because now he can achieve certain effects more easily, but he also knows >> that he'll be working harder -- it's another part to write. (But he's >> getting paid more, so he's not going to object. :-)) >> > > The ochestrator can do a better job by investing more time with or without > new instruments. On the other hand, he may be able to better achieve his > goals with the same cost and effort by taking advantage of a new instrument > in place of a more traditional one. > Another part to write is another part to write, no matter how desirable the resulting sound. Much as I love being able to add drums to a plain piano part, because it makes it easier to get the rhythms across to the actors in performance, it's a *lot* of work, so much that every time I do it I think, "Hmm, how badly do I want drums in this song?" But getting back to the point: Neal and Reinier, you're working very hard to argue something general and hard to support -- that new language features don't mean more work for API designers -- when you should be arguing that a particular feature is *worth* the extra work. That's the important question. It's hard to engage in a meaningful discussion of costs and benefits if you don't acknowledge the possibility of costs. And while I don't think ParallelArray is a compelling case for function types over named interfaces based on my experience, I'm interested in hearing about other people's experiences with it, and I certainly think it's worth investigating other applications of function types that might prove more compelling. --tim -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091123/befcdba8/attachment-0001.html From news at kav.dk Mon Nov 23 13:48:56 2009 From: news at kav.dk (Kasper Nielsen) Date: Mon, 23 Nov 2009 22:48:56 +0100 Subject: Scalar PA performance Message-ID: The performance of the scalar versions of ParallelArray has been discussed a couple of times on the concurrency interest list. Here are some pointers. http://cs.oswego.edu/pipermail/concurrency-interest/2008-January/004899.html http://cs.oswego.edu/pipermail/concurrency-interest/2007-August/004314.html Short version: Often 4X faster sometimes up to 16X. Cheers Kasper From kevinb at google.com Mon Nov 23 14:36:47 2009 From: kevinb at google.com (Kevin Bourrillion) Date: Mon, 23 Nov 2009 14:36:47 -0800 Subject: closures after all? In-Reply-To: <63b4e4050911231330l5e906d89wdaba5a05b07aaaee@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> <560fb5ed0911210844v93e7830t71d6136bcfe30c61@mail.gmail.com> <63b4e4050911211352pefb9cdaid9d6574d885fa95f@mail.gmail.com> <560fb5ed0911211546q78addf6w96ddb9df9e0525d5@mail.gmail.com> <63b4e4050911230743w51ad619clb78d3b5621210f84@mail.gmail.com> <560fb5ed0911230944j52f0cfc2g5692386ee537e2d3@mail.gmail.com> <63b4e4050911231202x3454427fk3d088adb20e62743@mail.gmail.com> <15e8b9d20911231235v7bc56d1dp614da379e2189133@mail.gmail.com> <63b4e4050911231330l5e906d89wdaba5a05b07aaaee@mail.gmail.com> Message-ID: <108fcdeb0911231436h7790ea65l48e9388afe1a42e7@mail.gmail.com> Hello everyone, I have a particular interest in the current debate (over the potential deleterious effects of closures on APIs) as the person who, a few years ago, introduced the Function and Predicate interfaces into Google's internal codebase. To be sure, these have been useful, and we've found many great uses for them. I've also seen too many completely appalling usages of them to count. To give just one example, I once came across a class whose constructor required two Functions and Predicate, on various types, storing those in fields, and whose documentation (of course) quite glossed over the finer details of their semantics. So I asked the author, "why do it this way -- wouldn't it be more natural to just define three abstract methods, with regular old javadoc and the whole bit -- or define an interface with these three methods, to be passed in? Logically, it could be named Xxx, and that helps users understand what it's really all about." His response? "Oh, I hadn't thought of that! You're right, it's totally better that way." ::headdesk:: I think I went home early that day. But this wasn't an isolated incident. This kind of thing happens a LOT. Most developers, by FAR, do not really put conscious thought into the art of API design. Their job is usually to implement a feature, which requires them to make small changes at many different layers of the system -- so every API boundary they touch is one where they are both the implementor and the consumer. It doesn't feel too important to them how exactly they choose to talk to *themselves*. So they walk the path of least resistance. If their first thought is, "I need a way to get from a Foo to a Bar," then their second thought is, "ahh, that's a Function then!" When you consider how bloated and boilerplate-laden these Function and Predicate incantations are, then you can only conclude that this will be happening at a much greater scale once closures are here. Give me a shiny new hammer, and suddenly everything I see looks like a nail! Is potential for abuse alone ever a sufficient argument for killing a feature? Definitely not. And I'm not even opposed to this new closures proposal (such as I understand it); I think it will probably make a lot of code better. I do, however, think it is easily within the realm of possibility that it will make even more code worse. Lawrence is explaining some the reasons very well in this thread. My two cents. On Mon, Nov 23, 2009 at 1:30 PM, Tim Peierls wrote: > On Mon, Nov 23, 2009 at 3:35 PM, Neal Gafter wrote: > > > On Mon, Nov 23, 2009 at 12:02 PM, Tim Peierls wrote: > > > >> Here's an imperfect but suggestive analogy: More options in the > treatment > >> of a disease might offer hope to millions, but the physician's job is > harder > >> because she has to evaluate more options in the context of each patient. > She > >> might be glad to be able to offer her patients a promising new therapy, > but > >> she is working longer hours (or seeing fewer patients). > >> > > > > Doctors can do better by their patients by investing more time, with or > > without new techniques. On the other hand, she may be able to save more > > lives with the same effort by taking advantage of the new techniques. > That > > seems to be the way it works in practice. > > > > Not the way the physicians I know talk about it. A new technique can be a > great boon, but in practice it means more work for physicians. My wife, a > physician, reacts to each new development with deep ambivalence: it's > wonderful to have that new option, but now she has more to learn, and her > list of things to check off for each patient just got that much longer. > > OTOH, she's terrible at API design. :-) > > > > > Here's another: The addition of a new instrument when scoring a musical > >> theater piece broadens the palette of available colors. The orchestrator > is > >> probably pleased when the producers cough up the extra dough for the > player, > >> because now he can achieve certain effects more easily, but he also > knows > >> that he'll be working harder -- it's another part to write. (But he's > >> getting paid more, so he's not going to object. :-)) > >> > > > > The ochestrator can do a better job by investing more time with or > without > > new instruments. On the other hand, he may be able to better achieve his > > goals with the same cost and effort by taking advantage of a new > instrument > > in place of a more traditional one. > > > > Another part to write is another part to write, no matter how desirable the > resulting sound. Much as I love being able to add drums to a plain piano > part, because it makes it easier to get the rhythms across to the actors in > performance, it's a *lot* of work, so much that every time I do it I think, > "Hmm, how badly do I want drums in this song?" > > But getting back to the point: Neal and Reinier, you're working very hard > to > argue something general and hard to support -- that new language features > don't mean more work for API designers -- when you should be arguing that a > particular feature is *worth* the extra work. That's the important > question. > It's hard to engage in a meaningful discussion of costs and benefits if you > don't acknowledge the possibility of costs. > > And while I don't think ParallelArray is a compelling case for function > types over named interfaces based on my experience, I'm interested in > hearing about other people's experiences with it, and I certainly think > it's > worth investigating other applications of function types that might prove > more compelling. > > --tim > > -- Kevin Bourrillion @ Google internal: http://go/javalibraries external: guava-libraries.googlecode.com -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091123/3425f001/attachment.html From markmahieu at googlemail.com Mon Nov 23 16:31:12 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Tue, 24 Nov 2009 00:31:12 +0000 Subject: Closures, too much or too little? In-Reply-To: <560fb5ed0911231540u7fcc5514m4d2308a176758338@mail.gmail.com> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <3dd3f56a0911230644n4561202fpa5427d43f9f736aa@mail.gmail.com> <20e52370558774d23721da73fc41d661.squirrel@imap.fit.cvut.cz> <17b2302a0911230818w6715f7dcr882a82fe1f30ba37@mail.gmail.com> <4E140E62-15DD-4BB5-8262-9D4F2FC73583@googlemail.com> <6f1a14d95bf3f5a706992a598a18e637.squirrel@imap.fit.cvut.cz> <560fb5ed0911231540u7fcc5514m4d2308a176758338@mail.gmail.com> Message-ID: <04141A6C-F886-48E1-AD76-509A2CBF70CE@googlemail.com> IIRC, in javac desugaring happens after DA/DU analysis, so I imagine it'd require changes to both phases. Also, flow analysis understands things like loops which would be important here. I haven't put any real thought into it though, it just feels like a slightly more comfortable half-way house for the read-only cases. But I agree it doesn't help with closures that actually want to mutate the locals, so to speak. Mark On 23 Nov 2009, at 23:40, Reinier Zwitserloot wrote: > Mark, spec-wise, "turning final" is effectively equivalent to the compiler desugaring your source code snippet to: > > int count = 0; > final int count0; > count++; > > count0 = count; //generated > Runnable r = #() {doSomethingWith(count0);}; > > > I haven't done an exhaustive analysis, but it seems that, if such a desugaring results in legal code (e.g. the DA/DU rules don't cause an error on usage or assignment of count0), it boils down to the same thing. The key is to switch over to count0 at the right time. Neither right before closure usage, nor right after last mutation, will be suitable. > > > Presuming a simple spec and implementation for this feature is possible, I like it. However, as far as these things go, this change doesn't seem to have all that much impact on the concept of @Shared/public variables for closures. It won't get rid of needing to mutate outer scope - plenty of closures where the closure is run inline (some sort of withLock construct, for example), and the closure needs to communicate a result back to the outer scope. Neal's basic approach is not a bad idea, though the warning should not be generated if the gist of the warning can't actually happen, and the compiler can figure this out: So, that would mean, auto-final, and probably this concept of turning final just in time for the closure as well. > > A bonus here is that the static analysis of code to ascertain if lack of @Shared warrants a warning/error can be deferred until JDK8 if there's time pressure. It won't be backwards incompatible to stop generating frivolous warnings. > > --Reinier Zwitserloot > > NB: Mark, does closures-dev know about auto-final and not generating warning/error if there is no mutation after the closure is defined? > > > > On Mon, Nov 23, 2009 at 9:36 PM, Mark Mahieu wrote: > On 23 Nov 2009, at 19:37, tronicek at fit.cvut.cz wrote: > > > > >> So for me, a more practical variation of "auto-finalization" would be that > >> the variable only 'becomes' final at the point in the code where the > >> closure appears. > > > > What you mean by "becoming final"? Do you propose to flush all the > > (non-final) variables, which are used in the closure, to the shared memory > > at the point where this closure is declared? > > More musing on than proposing, but I'm suggesting that it's common for the local variable to only initially want to be mutable, whilst I'm in the process of setting up its value. After that's done with, I'd currently need to assign it to a final variable if I want to use its value in an anonymous class, which is annoying, even though (in my 'common' example) I make no attempt to assign to it again in the method, nor in any anonymous class (or closure) that references it. > > So I'm wondering whether there's a sensible (and clear) rule which would allow the compiler to do that 'annoying part' for me when necessary, such that: > > int count = 0; > count++; // ok, obviously > > // count 'becomes' final about here > Runnable r = #() { doSomethingWith(count); }; // still ok, not trying to assign to it > > count++; // compiler error - "Can't assign to variable 'count' after use in closure blah blah" > > > It's kinda like the "auto-finalization" that Josh referred to, but deferring the "finalization" part until it's actually needed ('needed' being highly subjective, admittedly). > > Dunno. > > Mark > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091124/6d846777/attachment.html From fredrik.ohrstrom at oracle.com Tue Nov 24 01:20:46 2009 From: fredrik.ohrstrom at oracle.com (=?KOI8-R?Q?Fredrik_O=22hrstro=22m?=) Date: Tue, 24 Nov 2009 10:20:46 +0100 Subject: Boxing function types In-Reply-To: <15e8b9d20911220825r25a5ceaeq7f8e338fa89dc81e@mail.gmail.com> References: <15e8b9d20911220825r25a5ceaeq7f8e338fa89dc81e@mail.gmail.com> Message-ID: <4B0BA56E.4010802@oracle.com> Neal Gafter skrev: > Kochurov- > > This is an interesting idea, but you have the variance backwards for > argument types. The argument types in the function on the > right-hand-side of the assignment must be subtypes (not supertypes) of > the argument types in the function on the left-hand-side. > This is in fact MethodHandle.invokeGeneric For those not following the JSR292 mailing list, the MethodHandle hides the target for a call, just like an interface, but more importantly the bytecode verifier will allow any signature to be used for invokeGeneric. I.e. (using the JSR292 pseudo java-syntax instead of pushing byte code) you can have: MethodHandle mh = (.... grab a method handle somewhere...) int xx = mh.invokeGeneric(42,"Hello"); Object oo = mh.invokeGeneric("Hi", "Hi"); There would be no objection to the above code by the bytecode verifier. If the methodhandle actually holds on to the method: int asillymethod(Object o, String s) { return 17; } then the code will actually execute with no runtime exceptions. xx will contain 17 and oo will contain a new Integer(17). The JVM (not the bytecode) will cast each argument to the target argument type. It will box primitives if necessary and it will cast/unbox if the target requires a primitive and is fed a reference. The same is applied to the return value. Obviously this will sometimes cause object allocations to occur as a side effect of the call. However this will not happen as often as you think. Especially when hot code is inlined and optimized, then the casting and boxing can be completely removed. (As I have shown here blogs.oracle.com/ohrstrom). invokeGeneric was not introduced on a whim, it was introduced to allow the JVM implementor to implement the generic transformations (currying of arguments, permuting arguments et al) in static bytecode (NO bytecode generation needed at runtime!) and not hidden inside a bunch of magic jni calls nor any bytecode spewing library. I do not believe that the generic transforms (generalized lambdas) can be implemented using any of the current closure proposals. Thus MethodHandle.invokeGeneric is an runtime checked function object. It supports contravariant arguments since the cast will only allow those. It supports covariant return values, again since this is what the cast of the return value will allow. It supports int->Integer Integer->int and similar boxing but not int->Long nor long->Integer. (For various reasons JSR292 also has invokeExact that will fail unless the types match exactly, no variance allowed at all, you have to cast a string to object, (Object)"Hello", for it to be accepted as an Object argument.) The MethodHandle can be bound to an object instance within which the method will execute, but it is not by itself a closure or a lambda in the future Java sense, and it surely has no function type available for javac compile time checking. But this does not mean that it cannot be the building block for closures on the inside instead of using interfaces. //Fredrik From markmahieu at googlemail.com Tue Nov 24 03:04:28 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Tue, 24 Nov 2009 11:04:28 +0000 Subject: Closures, too much or too little? In-Reply-To: References: Message-ID: <4DB9307E-E910-4053-8363-2C3A28424B59@googlemail.com> Yep, that's what I meant by the variable (count) 'becoming final'; the second count++ would cause a compiler error. Same deal here, as flow analysis would indicate that n is mutated 'after' being used in the closure: for (int n = 1; n <= 10; n++) { someList.add(#() n); // compile error } Mark On 24 Nov 2009, at 09:56, Roel Spilker wrote: > One more thing. If there is a write to count after the assignment to count0, the compiler should give at least a warning. Otherwise the reader of this code could thing the closure would see the modification if the closure is used after the modification. > > int count = 0; > count++; > Runnable r = #() {doSomethingWith(count);}; > count++; > r.run(); > > would desugar to > > int count = 0; > count++; > final int count0 = count; // generated > Runnable r = #() {doSomethingWith(count0);}; > count++; > r.run(); > > In this scenario, I'd like to get an error or at least a warning that count is modified after the final variable has been assigned. > > Roel > > > -----Oorspronkelijk bericht----- > Van: reinier at zwitserloot.com [mailto:coin-dev-bounces at openjdk.java.net] Namens Reinier Zwitserloot > Verzonden: dinsdag 24 november 2009 0:41 > Aan: Mark Mahieu > CC: coin-dev > Onderwerp: Re: Closures, too much or too little? > > Mark, spec-wise, "turning final" is effectively equivalent to the compiler desugaring your source code snippet to: > > int count = 0; > final int count0; > count++; > > count0 = count; //generated > Runnable r = #() {doSomethingWith(count0);}; > > From neal at gafter.com Tue Nov 24 08:47:31 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 24 Nov 2009 08:47:31 -0800 Subject: Boxing function types In-Reply-To: <15e8b9d20911220825r25a5ceaeq7f8e338fa89dc81e@mail.gmail.com> References: <15e8b9d20911220825r25a5ceaeq7f8e338fa89dc81e@mail.gmail.com> Message-ID: <15e8b9d20911240847x3ab5a967q8edf3bfc732efbdc@mail.gmail.com> On Sun, Nov 22, 2009 at 8:25 AM, Neal Gafter wrote: > This is an interesting idea, but you have the variance backwards for > argument types. The argument types in the function on the right-hand-side > of the assignment must be subtypes (not supertypes) of the argument types in > the function on the left-hand-side. > How embarrassing. You had it right the first time. Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091124/adec097b/attachment.html From markmahieu at googlemail.com Tue Nov 24 16:21:39 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 25 Nov 2009 00:21:39 +0000 Subject: Mark Reinhold's Blog - closures announcement Message-ID: <9A7415C9-353C-4F88-A6D3-EA321E48F410@googlemail.com> For anyone who hasn't seen it yet: http://blogs.sun.com/mr/entry/closures From ipris at inbox.ru Wed Nov 25 00:16:46 2009 From: ipris at inbox.ru (=?koi8-r?Q?=EB=CF=DE=D5=D2=CF=D7_=E1=CC=C5=CB=D3=C1=CE=C4=D2?=) Date: Wed, 25 Nov 2009 11:16:46 +0300 Subject: =?koi8-r?Q?Re[2]=3A_Boxing_function_types?= Message-ID: Neal, I reexamined my idea and want to highlight some reasons why is it usefull: 1) boxing function types allows you to change implementation details without breaking any code (e.g. if you need to replace collection of boxed primitives with array or Trove4j primitive collections for performance reasons you can just replace field/argument declatations and all closures would still be valid); 2) users of your API needn't to know a reason why you require their closures to return @NotNull Integer instead of int, but there is also no need to write #(Integer i) Integer.valueOf(someClosure.invoke(i.intValue())) every time for #int(int) someClosure reseived from user; 3) it's a generalisation of boxing concept; enchanced for-loop allows you to use implicit boxing/unboxing for loop variable, why closures don't? (for (int i: Arrays.asList(1, 2, 3)) does unboxing each iteration) 4) ... 5) PROFIT! Yes, it brings some flaws and performance drawbacks, but almost any syntactic sugar does. (moreover, IMHO java should allow methods with primitive arguments to override methods with boxed arguments, e.g. int method(int x) should override Integer method(Integer x) ) Thanks for your feedback, Alex -----Original Message----- From: Neal Gafter To: Kochurov Alexander Date: Tue, 24 Nov 2009 08:47:31 -0800 Subject: Re: Boxing function types > On Sun, Nov 22, 2009 at 8:25 AM, Neal Gafter wrote: > > > This is an interesting idea, but you have the variance backwards for > > argument types. The argument types in the function on the right-hand-side > > of the assignment must be subtypes (not supertypes) of the argument types in > the function on the left-hand-side. > > > > How embarrassing. You had it right the first time. > > Cheers, > Neal > > From neal at gafter.com Wed Nov 25 00:35:45 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 25 Nov 2009 00:35:45 -0800 Subject: Boxing function types In-Reply-To: References: <15e8b9d20911240847x3ab5a967q8edf3bfc732efbdc@mail.gmail.com> Message-ID: <15e8b9d20911250035l4c2e9201t5e8a3b9630bdb58f@mail.gmail.com> Alex- Java's "convertible" relationship is not transitive: there are conversions Integer->int->long->Long, but not Integer->Long. Yet the subtype relationship must be transitive for type inference and overriding. Therefore the convertible relationship cannot be used for subtyping. I agree that this situation is unfortunate. The jsr201 expert group considered this, and decided that they prefer things this way. In their judgment, it was more important to use the existing classes for boxed types (rather than interfaces related by inheritance, as Gilad and I proposed). In the process, they give up the likelihood of ever supporting the conversions as subtype relations. One consequence of the decision is that it is unlikely we will be able to extend generics to work over primitives, and consequently the kind of API duplication you see in the ParallelArray framework cannot easily be eliminated. I suspect some of the jsr201 participants now regret their decision, but it is too late to change it. Cheers, Neal 2009/11/25 Kochurov Alexander > Neal, > > I reexamined my idea and want to highlight some reasons why is it > usefull: > 1) boxing function types allows you to change implementation details > without breaking any code (e.g. if you need to replace collection of boxed > primitives with array or Trove4j primitive collections for performance > reasons you can just replace field/argument declatations and all closures > would still be valid); > 2) users of your API needn't to know a reason why you require their > closures to return @NotNull Integer instead of int, but there is also no > need to write #(Integer i) Integer.valueOf(someClosure.invoke(i.intValue())) > every time for #int(int) someClosure reseived from user; > 3) it's a generalisation of boxing concept; enchanced for-loop allows you > to use implicit boxing/unboxing for loop variable, why closures don't? (for > (int i: Arrays.asList(1, 2, 3)) does unboxing each iteration) > 4) ... > 5) PROFIT! > Yes, it brings some flaws and performance drawbacks, but almost any > syntactic sugar does. > (moreover, IMHO java should allow methods with primitive arguments to > override methods with boxed arguments, e.g. int method(int x) should > override Integer method(Integer x) ) > > Thanks for your feedback, > Alex > > -----Original Message----- > From: Neal Gafter > To: Kochurov Alexander > Date: Tue, 24 Nov 2009 08:47:31 -0800 > Subject: Re: Boxing function types > > > On Sun, Nov 22, 2009 at 8:25 AM, Neal Gafter wrote: > > > > > This is an interesting idea, but you have the variance backwards for > > > argument types. The argument types in the function on the > right-hand-side > > > of the assignment must be subtypes (not supertypes) of the argument > types in > > > the function on the left-hand-side. > > > > > > > How embarrassing. You had it right the first time. > > > > Cheers, > > Neal > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091125/3ba7bd94/attachment.html From ipris at inbox.ru Wed Nov 25 00:57:21 2009 From: ipris at inbox.ru (=?koi8-r?Q?=EB=CF=DE=D5=D2=CF=D7_=E1=CC=C5=CB=D3=C1=CE=C4=D2?=) Date: Wed, 25 Nov 2009 11:57:21 +0300 Subject: =?koi8-r?Q?Re[4]=3A_Boxing_function_types?= In-Reply-To: <15e8b9d20911250035l4c2e9201t5e8a3b9630bdb58f@mail.gmail.com> References: <15e8b9d20911250035l4c2e9201t5e8a3b9630bdb58f@mail.gmail.com> Message-ID: Neal, I didn't take that into account. But boxing conversions Integer -> int -> Integer, Long -> long -> Long, etc are still transitive and therefore could be used as covariant return types and contravariant argument types. -----Original Message----- From: Neal Gafter To: Kochurov Alexander Date: Wed, 25 Nov 2009 00:35:45 -0800 Subject: Re: Re[2]: Boxing function types > Alex- > > Java's "convertible" relationship is not transitive: there are conversions > Integer->int->long->Long, but not Integer->Long. Yet the subtype > relationship must be transitive for type inference and overriding. > Therefore the convertible relationship cannot be used for subtyping. > > I agree that this situation is unfortunate. The jsr201 expert group > considered this, and decided that they prefer things this way. In their > judgment, it was more important to use the existing classes for boxed types > (rather than interfaces related by inheritance, as Gilad and I proposed). > In the process, they give up the likelihood of ever supporting the > conversions as subtype relations. One consequence of the decision is that > it is unlikely we will be able to extend generics to work over primitives, > and consequently the kind of API duplication you see in the ParallelArray > framework cannot easily be eliminated. I suspect some of the jsr201 > participants now regret their decision, but it is too late to change it. > > Cheers, > Neal > > 2009/11/25 Kochurov Alexander > > > Neal, > > > > I reexamined my idea and want to highlight some reasons why is it > > usefull: > > 1) boxing function types allows you to change implementation details > > without breaking any code (e.g. if you need to replace collection of boxed > > primitives with array or Trove4j primitive collections for performance > > reasons you can just replace field/argument declatations and all closures > > would still be valid); > > 2) users of your API needn't to know a reason why you require their > > closures to return @NotNull Integer instead of int, but there is also no > > need to write #(Integer i) Integer.valueOf(someClosure.invoke(i.intValue())) > > every time for #int(int) someClosure reseived from user; > > 3) it's a generalisation of boxing concept; enchanced for-loop allows you > > to use implicit boxing/unboxing for loop variable, why closures don't? (for > > (int i: Arrays.asList(1, 2, 3)) does unboxing each iteration) > > 4) ... > > 5) PROFIT! > > Yes, it brings some flaws and performance drawbacks, but almost any > > syntactic sugar does. > > (moreover, IMHO java should allow methods with primitive arguments to > > override methods with boxed arguments, e.g. int method(int x) should > > override Integer method(Integer x) ) > > > > Thanks for your feedback, > > Alex > > > > -----Original Message----- > > From: Neal Gafter > > To: Kochurov Alexander > > Date: Tue, 24 Nov 2009 08:47:31 -0800 > > Subject: Re: Boxing function types > > > > > On Sun, Nov 22, 2009 at 8:25 AM, Neal Gafter wrote: > > > > > > > This is an interesting idea, but you have the variance backwards for > > > > argument types. The argument types in the function on the > > right-hand-side > > > > of the assignment must be subtypes (not supertypes) of the argument > > types in > > > > the function on the left-hand-side. > > > > > > > > > > How embarrassing. You had it right the first time. > > > > > > Cheers, > > > Neal > > > > > > > > > > From dl at cs.oswego.edu Wed Nov 25 08:19:36 2009 From: dl at cs.oswego.edu (Doug Lea) Date: Wed, 25 Nov 2009 11:19:36 -0500 Subject: Boxing function types In-Reply-To: <15e8b9d20911250035l4c2e9201t5e8a3b9630bdb58f@mail.gmail.com> References: <15e8b9d20911240847x3ab5a967q8edf3bfc732efbdc@mail.gmail.com> <15e8b9d20911250035l4c2e9201t5e8a3b9630bdb58f@mail.gmail.com> Message-ID: <4B0D5918.4040600@cs.oswego.edu> I'm not sure exactly why I was CCed on this and haven't haven't been closely following recent discussions but I signed up to this list to reply explaining some of the issues here. First: If you want parallel speedups (especially for operations on aggregates/arrays/collections), you need to minimize interference across parallel threads; And you need to do this at all levels -- CPUs, memory, JVM support, Java support. Boxing is among the enemies of parallelization. When you box things, you get less locality, hence more interference, among threads. If you have for example arrays where each cell points to some data rather than being that data, you face the possibility that the actual data are randomly strewn across memory. So you not only get a lot more cache misses (which are increasingly very expensive ) but you also have cacheline ping-ponging due to different data items being operated on by different threads just so happening to be nearby. In other words, boxing not only has constant-time time/space overhead, but is also a scalability impediment. These are not small problems. You can easily create ForkJoin programs that speed up linearly when using localized data but barely speed up at all otherwise (plus of course the sequential cases is slower to begin with under boxing). So, improving locality control is among the biggest upcoming issues for those of us trying to improve parallelization support in core libraries and JVMs. For example, I think it is a sure thing that at some point there will need to be embeddable value/struct/tuple support, (these things will probably NOT be java.lang.Objects). As is already seen in languages like X10 and Fortress, which are targeted to be able to run on JVMs, so JVMs will probably evolve to support them even if there is no Java language support. There are plenty of other issues along these lines too, like coping with MPs vs Multicore vs MPs-of-Multicores wrt cache affinities vs cache pollution. But not allowing efficiencies when we can get them already (like the case of plain scalars) would be a bad move. I really, really don't want to do is release an overhyped facility for parallel programming that doesn't actually speed up anyone's applications. -Doug From neal at gafter.com Wed Nov 25 16:39:09 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 25 Nov 2009 16:39:09 -0800 Subject: Boxing function types In-Reply-To: <4B0D5918.4040600@cs.oswego.edu> References: <15e8b9d20911240847x3ab5a967q8edf3bfc732efbdc@mail.gmail.com> <15e8b9d20911250035l4c2e9201t5e8a3b9630bdb58f@mail.gmail.com> <4B0D5918.4040600@cs.oswego.edu> Message-ID: <15e8b9d20911251639p331ea4a9v4f9c42e112f0e771@mail.gmail.com> Doug- The value of supporting the assignment conversions in the function subtype relation is that it enables one to generalize generics over primitive types. That can be optimized automatically by code specialization, which eliminates the boxing and unboxing at runtime. But as I said, we may have already designed ourselves out of this option. Cheers, Neal On Wed, Nov 25, 2009 at 8:19 AM, Doug Lea
wrote: > I'm not sure exactly why I was CCed on this and > haven't haven't been closely following recent > discussions but I signed up to this list to > reply explaining some of the issues here. > > First: If you want parallel speedups (especially > for operations on aggregates/arrays/collections), > you need to minimize interference across parallel > threads; And you need to do this at all levels -- > CPUs, memory, JVM support, Java support. > > Boxing is among the enemies of parallelization. > When you box things, you get less locality, > hence more interference, among threads. If you > have for example arrays where each cell points to > some data rather than being that data, you > face the possibility that the actual data > are randomly strewn across memory. So you not only > get a lot more cache misses (which are increasingly > very expensive ) but you also have cacheline > ping-ponging due to different data items being > operated on by different threads just so happening to > be nearby. In other words, boxing not only has > constant-time time/space overhead, but is also > a scalability impediment. > > These are not small problems. You can easily > create ForkJoin programs that speed up linearly > when using localized data but barely speed up > at all otherwise (plus of course the sequential > cases is slower to begin with under boxing). > > So, improving locality control is among the > biggest upcoming issues for those of us trying > to improve parallelization support in core > libraries and JVMs. For example, I think it is > a sure thing that at some point there will > need to be embeddable value/struct/tuple support, > (these things will probably NOT be java.lang.Objects). > As is already seen in languages like X10 and > Fortress, which are targeted to be able to run > on JVMs, so JVMs will probably evolve to support > them even if there is no Java language support. > > There are plenty of other issues along these > lines too, like coping with MPs vs Multicore > vs MPs-of-Multicores wrt cache affinities vs > cache pollution. But not allowing efficiencies > when we can get them already (like the case of > plain scalars) would be a bad move. I really, > really don't want to do is release an overhyped > facility for parallel programming that doesn't > actually speed up anyone's applications. > > -Doug > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091125/73eece6a/attachment.html From dl at cs.oswego.edu Thu Nov 26 04:43:40 2009 From: dl at cs.oswego.edu (Doug Lea) Date: Thu, 26 Nov 2009 07:43:40 -0500 Subject: Boxing function types In-Reply-To: <15e8b9d20911251639p331ea4a9v4f9c42e112f0e771@mail.gmail.com> References: <15e8b9d20911240847x3ab5a967q8edf3bfc732efbdc@mail.gmail.com> <15e8b9d20911250035l4c2e9201t5e8a3b9630bdb58f@mail.gmail.com> <4B0D5918.4040600@cs.oswego.edu> <15e8b9d20911251639p331ea4a9v4f9c42e112f0e771@mail.gmail.com> Message-ID: <4B0E77FC.2040701@cs.oswego.edu> Neal Gafter wrote: > The value of supporting the assignment conversions in the function > subtype relation is that it enables one to generalize generics over > primitive types. That can be optimized automatically by code > specialization, which eliminates the boxing and unboxing at runtime. It would be great if people worked on turning that "can be" into the combination of source-level compiler support, bytecode tools, class-loading facilities and JIT support that could perform specialization well enough for people to rely on. The Scala folks have done some of this for scalars using @specialized (upcoming for Scala 2.8), and X10 generics etc have been defined to support it for scalars and structs (see http://dist.codehaus.org/x10/documentation/languagespec/x10-200.pdf). And similarly but less so in C#. My main point is that there is a cluster of language features and underlying support for multicore-friendly parallel programming that you need to consider as a group, even if they are not all introduced as a group in a particular Java release. Including lambda-like closures, function types, embeddable structs/values/tuples, improved arrays (especially 2d dense), revising JLS exception rules to better deal with async failures, and possibly further extensions for non-shared-memory parallelism. All of these correspond to likely directions for evolving improved platform-level support, leveraging the natural advantages of JVMs over other platforms (dynamic compilation, high-performance GC, etc) when it comes to supporting parallelism. Digressing further: The situation for fine-grained parallelism right now is not too different than it was for coarser-grained concurrency in 1995: There was a big gap between language features (threads+synchronized+wait/notify) and what most people building concurrent middleware etc wanted to do. We reduced that gap in JDK5 java.util.concurrent, but that was a bit easier since it didn't interact much with language features. Some days I think the Java language evolution story is just too hard, and that it would be more profitable to focus on developing other JVM-hosted languages like X10 that have worked out a more coherent story about it. But every now and again people surprise me by suggesting that we give a serious shot at incremental Java language changes that might get us closer to these goals. I'm all for trying this. But... > > But as I said, we may have already designed ourselves out of this option. And as I said, let's not do this again by ignoring the nearly-inevitable follow-ons. -Doug From vladimir.kirichenko at gmail.com Thu Nov 26 21:50:03 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Fri, 27 Nov 2009 07:50:03 +0200 Subject: Syntax... In-Reply-To: <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074604.7090601@gmail.com> <4B074AF3.9090504@gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> <4B083B52.5050000@gmail.com> <15e8b9d20911211117i1d2ba197pafafdf3d9557eaa0@mail.gmail.com> <4B083DFF.4070505@gmail.com> <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> Message-ID: <4B0F688B.20403@gmail.com> Hi, all I have a question about process. So we had a discussion about possible syntax and...? Is it good or bad or doesn't matter or is there any place to fill some forms to proceed, polls to vote or anything? -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091127/2437d49c/attachment.bin From neal at gafter.com Thu Nov 26 22:17:17 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 26 Nov 2009 22:17:17 -0800 Subject: Syntax... In-Reply-To: <4B0F688B.20403@gmail.com> References: <15e8b9d20911201144m2ba10a09p20e2ff719dd3cb91@mail.gmail.com> <4B074D14.6050005@gmail.com> <15e8b9d20911202152g6affff2ekbdc9041f225e2359@mail.gmail.com> <4B082F2D.8020008@gmail.com> <15e8b9d20911211103k2fb1f94fq73d7843c114d2f32@mail.gmail.com> <4B083B52.5050000@gmail.com> <15e8b9d20911211117i1d2ba197pafafdf3d9557eaa0@mail.gmail.com> <4B083DFF.4070505@gmail.com> <15e8b9d20911211204i5a4628adi7072ea4f836805c1@mail.gmail.com> <4B0F688B.20403@gmail.com> Message-ID: <15e8b9d20911262217h54957464la64dfc7777b775f9@mail.gmail.com> On Thu, Nov 26, 2009 at 9:50 PM, Vladimir Kirichenko < vladimir.kirichenko at gmail.com> wrote: > I have a question about process. So we had a discussion about possible > syntax and...? Is it good or bad or doesn't matter or is there any place > to fill some forms to proceed, polls to vote or anything? > Ultimately, a democratic process doesn't tend to turn out good language designs. The best approach is to have a benevolent and skilled language designer drive the process and make the final decision. I don't know how Sun intends to run the process. Sun hasn't yet put someone with the right profile in a position to drive closures. I don't work for Sun. I only have control over the specification and prototype I've been working on. I have no idea how it lines up with Sun's plans. Personally, I like the idea of using a keyword here, but that kind of decision should be taken for the language as a whole rather than for a single feature. Until someone at Sun engages me about these issues, I prefer not to do that in the spec. Therefore, I'm going to leave things as they stand for now until we have more information about how Sun intends to run the process. Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091126/8f6e6b2c/attachment.html From pbenedict at apache.org Thu Nov 26 23:26:38 2009 From: pbenedict at apache.org (Paul Benedict) Date: Fri, 27 Nov 2009 01:26:38 -0600 Subject: v7 Changes? Message-ID: Neal, Do you have a mental list of changes that you think will go into your v7 proposal? There's been a pretty good size discussion thus far, as I estimate. Sometimes it's tough to keep track which suggestions are on solid footing and which others are in quicksand. Paul From reinier at zwitserloot.com Fri Nov 27 03:44:59 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 27 Nov 2009 12:44:59 +0100 Subject: Boxing function types In-Reply-To: <4B0E77FC.2040701@cs.oswego.edu> References: <15e8b9d20911240847x3ab5a967q8edf3bfc732efbdc@mail.gmail.com> <15e8b9d20911250035l4c2e9201t5e8a3b9630bdb58f@mail.gmail.com> <4B0D5918.4040600@cs.oswego.edu> <15e8b9d20911251639p331ea4a9v4f9c42e112f0e771@mail.gmail.com> <4B0E77FC.2040701@cs.oswego.edu> Message-ID: <560fb5ed0911270344p56c47c0fm94a40e6349ea827d@mail.gmail.com> Crazy idea, perhaps, but can't the hotspot compiler rather easily eliminate an sequential boxing-unboxing, even across a method boundary? Let's say that methodA does this: long x = someLong(); callB(x); and B looks like: public void callB(Long y) { long x = y; // ... never touch y again } after inlining, the bytecode should read: //long on stack invokestatic java/lang/Long valueOf //there was a method call here, but it's been inlined. invokevirtual java/lang/Long longValue //long on stack again. when seeing this exact pattern with any primitive, the jit compiler can just nix both invokes; they are each others opposite. Now, some method taking a primitive wrapper, immediately unboxing it, and then never touching the boxed version again is not _that_ common, but if whatever closure proposal java ends up with does try to 'fit' closures into existing SAM types AND will consider boxing/unboxing of type (so a #(long)int could get auto-converted into a SAM where the SAM's method signature is (Long)Integer), then this would happen rather a lot. Regardless of speed reasons, this would be quite convenient. After all, if the closure proposal does NOT support this, then this: Collections.sort(integerList, #(int a, int b) a-b;); wouldn't actually work; you'd have to write #(Integer a, Integer b), and I can imagine that is somewhat confusing. That's not exactly an easy conversion due to all the concerns stated in this thread, but if it can be done, then something like PA's Ops file will lose 90% of the interfaces in there; you can then use an Op; it would be exactly as fast as a LongOp after JIT. I did some testing on this topic. Right now, this optimization is quite clearly not happening. I took a part of the ParallelArray code and rewrite ParallelLongArray to call into an Op instead of into a LongOp, and the implementation of this Op unboxed as first action, then never touched the boxed version again. So, ParallelArray boxes at the latest possible moment, and the 'closure' unboxes at the earliest possible moment. Yet, in a PA operation with very little to do per loop, this takes more than twice the time compared to the real PA, with customized 'LongOp' interface. (tested jvm 1.6.0_15-b03-226 with hotspot 14.1-b02-92 mixed mode) Once I changed the code to calculate a Base64 of the long per loop, the boxing/unboxing became insignificant (less than 2% performance drop), but that's not surprising. --Reinier Zwitserloot On Thu, Nov 26, 2009 at 1:43 PM, Doug Lea
wrote: > Neal Gafter wrote: > >> The value of supporting the assignment conversions in the function subtype >> relation is that it enables one to generalize generics over primitive types. >> That can be optimized automatically by code specialization, which >> eliminates the boxing and unboxing at runtime. >> > > It would be great if people worked on turning > that "can be" into the combination of source-level > compiler support, bytecode tools, class-loading > facilities and JIT support that could perform > specialization well enough for people to rely on. > The Scala folks have done some of this for scalars > using @specialized (upcoming for Scala 2.8), and > X10 generics etc have been defined to > support it for scalars and structs (see > http://dist.codehaus.org/x10/documentation/languagespec/x10-200.pdf). > And similarly but less so in C#. > > My main point is that there is a cluster > of language features and underlying support > for multicore-friendly parallel programming that > you need to consider as a group, even if they are > not all introduced as a group in a particular > Java release. Including lambda-like closures, > function types, embeddable structs/values/tuples, > improved arrays (especially 2d dense), revising > JLS exception rules to better deal with async > failures, and possibly further extensions for > non-shared-memory parallelism. All of these > correspond to likely directions for evolving > improved platform-level support, leveraging the > natural advantages of JVMs over other platforms > (dynamic compilation, high-performance GC, etc) > when it comes to supporting parallelism. > > Digressing further: The situation for fine-grained > parallelism right now is not too different than > it was for coarser-grained concurrency in 1995: > There was a big gap between language features > (threads+synchronized+wait/notify) and what most > people building concurrent middleware etc wanted to > do. We reduced that gap in JDK5 java.util.concurrent, > but that was a bit easier since it didn't interact > much with language features. Some days I think the > Java language evolution story is just too hard, > and that it would be more profitable to focus > on developing other JVM-hosted languages like X10 that > have worked out a more coherent story about it. > But every now and again people surprise me by > suggesting that we give a serious shot at > incremental Java language changes that might > get us closer to these goals. I'm all for > trying this. But... > > > >> But as I said, we may have already designed ourselves out of this option. >> > > And as I said, let's not do this again by ignoring > the nearly-inevitable follow-ons. > > -Doug > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091127/ce0799d0/attachment.html From fredrik.ohrstrom at oracle.com Fri Nov 27 06:40:09 2009 From: fredrik.ohrstrom at oracle.com (=?UTF-8?B?RnJlZHJpayDDlmhyc3Ryw7Zt?=) Date: Fri, 27 Nov 2009 15:40:09 +0100 Subject: Boxing function types In-Reply-To: <560fb5ed0911270344p56c47c0fm94a40e6349ea827d@mail.gmail.com> References: <15e8b9d20911240847x3ab5a967q8edf3bfc732efbdc@mail.gmail.com> <15e8b9d20911250035l4c2e9201t5e8a3b9630bdb58f@mail.gmail.com> <4B0D5918.4040600@cs.oswego.edu> <15e8b9d20911251639p331ea4a9v4f9c42e112f0e771@mail.gmail.com> <4B0E77FC.2040701@cs.oswego.edu> <560fb5ed0911270344p56c47c0fm94a40e6349ea827d@mail.gmail.com> Message-ID: <4B0FE4C9.3000003@oracle.com> Reinier Zwitserloot skrev: > Crazy idea, perhaps, but can't the hotspot compiler rather easily > eliminate an sequential boxing-unboxing, even across a method boundary? > It is not crazy at all! I do not know about Hotspot, but JRockit can definitely do this. Have a look at: http://blogs.oracle.com/ohrstrom/2009/05/pulling_a_machine_code_rabbit.html (Scroll down to: The question is, how well will JRockit optimize *int test(int i)*?) For something that works with currently released JRockits, go to: http://blogs.oracle.com/ohrstrom/2009/05/the_jsr292_endgame.htm (Scroll down to: public class Example) //Fredrik From neal at gafter.com Fri Nov 27 10:29:19 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 27 Nov 2009 10:29:19 -0800 Subject: v7 Changes? In-Reply-To: References: Message-ID: <15e8b9d20911271029pf53cefbybde872118034e323@mail.gmail.com> Paul- Actually, you've only seen part of the v0.6 specification. I expect to publish the rest within a week or so. Cheers, Neal On Thu, Nov 26, 2009 at 11:26 PM, Paul Benedict wrote: > Neal, > > Do you have a mental list of changes that you think will go into your > v7 proposal? There's been a pretty good size discussion thus far, as I > estimate. Sometimes it's tough to keep track which suggestions are on > solid footing and which others are in quicksand. > > Paul > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091127/f3ed6a07/attachment-0001.html From pbenedict at apache.org Sun Nov 29 12:22:31 2009 From: pbenedict at apache.org (Paul Benedict) Date: Sun, 29 Nov 2009 14:22:31 -0600 Subject: The philosophy of Nothing Message-ID: I have a philosophical problem with this portion of the spec: > Nothing is a subtype of every obect type. How can something be a subtype of nothing? I think my philosophy professors would have flunked me in college if I were to assert that. :-) Are we really going to see java.lang.Object now as a subtype of java.lang.Nothing in the API docs? Paul From reinier at zwitserloot.com Sun Nov 29 12:26:56 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 29 Nov 2009 21:26:56 +0100 Subject: The philosophy of Nothing In-Reply-To: References: Message-ID: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> You've got it flipped around. Nothing is a subtype of Object. (and of String, and of Number, and of Integer, etc). --Reinier Zwitserloot Need to receive donations via the web? Check https://tipit.to/ On Sun, Nov 29, 2009 at 9:22 PM, Paul Benedict wrote: > I have a philosophical problem with this portion of the spec: > > Nothing is a subtype of every obect type. > > How can something be a subtype of nothing? I think my philosophy > professors would have flunked me in college if I were to assert that. > :-) > > Are we really going to see java.lang.Object now as a subtype of > java.lang.Nothing in the API docs? > > Paul > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091129/4d0765c8/attachment.html From pbenedict at apache.org Sun Nov 29 12:33:19 2009 From: pbenedict at apache.org (Paul Benedict) Date: Sun, 29 Nov 2009 14:33:19 -0600 Subject: The philosophy of Nothing In-Reply-To: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> Message-ID: Yes, I do have it flipped around. Thank you. I shouldn't enjoy making big blunders in public so much. :-) So let me ask the opposite: How can nothing be a type of something? Paul On Sun, Nov 29, 2009 at 2:26 PM, Reinier Zwitserloot wrote: > You've got it flipped around. > Nothing is a subtype of Object. (and of String, and of Number, and of > Integer, etc). > --Reinier Zwitserloot From jim.andreou at gmail.com Sun Nov 29 12:41:27 2009 From: jim.andreou at gmail.com (Dimitris Andreou) Date: Sun, 29 Nov 2009 22:41:27 +0200 Subject: The philosophy of Nothing In-Reply-To: References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> Message-ID: <7d7138c10911291241v1f0b1ab6o521b3febaa97f583@mail.gmail.com> But you *do* understand that the empty set is a subset of any other set, right? 2009/11/29 Paul Benedict : > Yes, I do have it flipped around. Thank you. I shouldn't enjoy making > big blunders in public so much. :-) > > So let me ask the opposite: > How can nothing be a type of something? > > Paul > > On Sun, Nov 29, 2009 at 2:26 PM, Reinier Zwitserloot > wrote: >> You've got it flipped around. >> Nothing is a subtype of Object. (and of String, and of Number, and of >> Integer, etc). >> --Reinier Zwitserloot > From neal at gafter.com Sun Nov 29 12:57:28 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 29 Nov 2009 12:57:28 -0800 Subject: The philosophy of Nothing In-Reply-To: References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> Message-ID: <15e8b9d20911291257r78afdae9n2da958b9bf79fb56@mail.gmail.com> On Sun, Nov 29, 2009 at 12:33 PM, Paul Benedict wrote: > Yes, I do have it flipped around. Thank you. I shouldn't enjoy making > big blunders in public so much. :-) > > So let me ask the opposite: > How can nothing be a type of something? > A type T is a *subtype *of a type S iff all of the elements of the type T are elements of the type S. For example, String is a subtype of Object because all of the elements of the type String are elements of the type Object. There are no elements of the type Nothing. Therefore all of the elements of the type Nothing are elements of the type T, for every T. Therefore Nothing is a subtype of the type T, for every T. Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091129/5494a2d0/attachment.html From vladimir.kirichenko at gmail.com Sun Nov 29 14:44:41 2009 From: vladimir.kirichenko at gmail.com (Vladimir Kirichenko) Date: Mon, 30 Nov 2009 00:44:41 +0200 Subject: Closures discussion migrated... Message-ID: <4B12F959.8090200@gmail.com> ...to scala mailing list: http://old.nabble.com/Interesting-message-for-Java%2C-the-platform%2C-concurrency%2C-and-platform--limitations-(by-Doug-Lea)-td26536000.html :)) -- Best Regards, Vladimir Kirichenko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 259 bytes Desc: OpenPGP digital signature Url : http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091130/c545906c/attachment.bin From neal at gafter.com Sun Nov 29 15:44:13 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 29 Nov 2009 15:44:13 -0800 Subject: Boxing function types In-Reply-To: <4B0E77FC.2040701@cs.oswego.edu> References: <15e8b9d20911240847x3ab5a967q8edf3bfc732efbdc@mail.gmail.com> <15e8b9d20911250035l4c2e9201t5e8a3b9630bdb58f@mail.gmail.com> <4B0D5918.4040600@cs.oswego.edu> <15e8b9d20911251639p331ea4a9v4f9c42e112f0e771@mail.gmail.com> <4B0E77FC.2040701@cs.oswego.edu> Message-ID: <15e8b9d20911291544n7f98e07by2d6e7cb1ca55346a@mail.gmail.com> On Thu, Nov 26, 2009 at 4:43 AM, Doug Lea
wrote: > ... there is a cluster > of language features and underlying support > for multicore-friendly parallel programming that > you need to consider as a group, even if they are > not all introduced as a group in a particular > Java release. Including ... revising > JLS exception rules to better deal with async > failures ... > Doug- I'd love to hear you expand on this. I can't imagine what you might want to change in the core language's exception checking rules. I've done some language design to support asynchrony, and it transposes to Java very nicely assuming you have support for disjunctive types (exception transparency). Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091129/26e7d680/attachment.html From neal at gafter.com Sun Nov 29 16:01:46 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 29 Nov 2009 16:01:46 -0800 Subject: Boxing function types In-Reply-To: <15e8b9d20911291544n7f98e07by2d6e7cb1ca55346a@mail.gmail.com> References: <15e8b9d20911240847x3ab5a967q8edf3bfc732efbdc@mail.gmail.com> <15e8b9d20911250035l4c2e9201t5e8a3b9630bdb58f@mail.gmail.com> <4B0D5918.4040600@cs.oswego.edu> <15e8b9d20911251639p331ea4a9v4f9c42e112f0e771@mail.gmail.com> <4B0E77FC.2040701@cs.oswego.edu> <15e8b9d20911291544n7f98e07by2d6e7cb1ca55346a@mail.gmail.com> Message-ID: <15e8b9d20911291601h43cc4cafte4c1c7bf75393f5@mail.gmail.com> On Sun, Nov 29, 2009 at 3:44 PM, Neal Gafter wrote: > I'd love to hear you expand on this. I can't imagine what you might want > to change in the core language's exception checking rules. I've done some > language design to support asynchrony, and it transposes to Java very nicely > assuming you have support for disjunctive types (exception transparency). > Regarding the async language support I've been working on, see the video http://microsoftpdc.com/Sessions/FT11 from about 40:05 to 52:00. This is asynchrony in the coroutine sense, which I suspect is not what you have in mind. Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091129/9bc67fff/attachment.html From markmahieu at googlemail.com Sun Nov 29 16:46:30 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Mon, 30 Nov 2009 00:46:30 +0000 Subject: Boxing function types In-Reply-To: <15e8b9d20911291601h43cc4cafte4c1c7bf75393f5@mail.gmail.com> References: <15e8b9d20911240847x3ab5a967q8edf3bfc732efbdc@mail.gmail.com> <15e8b9d20911250035l4c2e9201t5e8a3b9630bdb58f@mail.gmail.com> <4B0D5918.4040600@cs.oswego.edu> <15e8b9d20911251639p331ea4a9v4f9c42e112f0e771@mail.gmail.com> <4B0E77FC.2040701@cs.oswego.edu> <15e8b9d20911291544n7f98e07by2d6e7cb1ca55346a@mail.gmail.com> <15e8b9d20911291601h43cc4cafte4c1c7bf75393f5@mail.gmail.com> Message-ID: <0EB7A79E-9803-442B-BCC4-A97C58EB02BA@googlemail.com> On 30 Nov 2009, at 00:01, Neal Gafter wrote: > > Regarding the async language support I've been working on, see the video http://microsoftpdc.com/Sessions/FT11 from about 40:05 to 52:00. This is asynchrony in the coroutine sense, which I suspect is not what you have in mind. That looks very, very cool. We're jumping through hoops to do that kind of thing in the product I'm working on at the moment. It'll be a pig to maintain too. Mark -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091130/8edbc860/attachment.html From dl at cs.oswego.edu Mon Nov 30 05:29:24 2009 From: dl at cs.oswego.edu (Doug Lea) Date: Mon, 30 Nov 2009 08:29:24 -0500 Subject: Boxing function types In-Reply-To: <15e8b9d20911291544n7f98e07by2d6e7cb1ca55346a@mail.gmail.com> References: <15e8b9d20911240847x3ab5a967q8edf3bfc732efbdc@mail.gmail.com> <15e8b9d20911250035l4c2e9201t5e8a3b9630bdb58f@mail.gmail.com> <4B0D5918.4040600@cs.oswego.edu> <15e8b9d20911251639p331ea4a9v4f9c42e112f0e771@mail.gmail.com> <4B0E77FC.2040701@cs.oswego.edu> <15e8b9d20911291544n7f98e07by2d6e7cb1ca55346a@mail.gmail.com> Message-ID: <4B13C8B4.50706@cs.oswego.edu> Neal Gafter wrote: > > I'd love to hear you expand on this. I can't imagine what you might > want to change in the core language's exception checking rules. I've > done some language design to support asynchrony, and it transposes to > Java very nicely assuming you have support for disjunctive types > (exception transparency). > Suppose you'd like to parallelize some function f(x) by dividing it into left and right parts. Using you-know-what-I-mean syntax: invokeAll(new F(left(x)), new F(right(x))); by which you have implicitly claimed that the left and right computations commute (i.e., order of evaluation doesn't matter, so can run in parallel). But suppose you are wrong about this claim in that: when run sequentially, the left side throws an exception before proceeding to right. Now suppose that the right side also throws an exception. And finally suppose that when run in parallel, the right side throws an exception before the left even starts. We want to (and do in FJ) just throw that right-side exception, and make no claims in this case about the left side, since we really don't know what would have happened if run sequentially; and further are free not to run it at all or kill it if the right side throws. So the issue is: If a programmer (perhaps implicitly) claims that two computations commute, then the exception thrown should be able to reflect that assumption, so (re)throwing any exception encountered should be OK. (Some people take the alternative view that you should throw a bundled Exception that represents all encountered exceptions, but doing so is hard to mesh with common policies to cancel sibling tasks upon first exception.) -Doug From neal at gafter.com Mon Nov 30 08:34:47 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 30 Nov 2009 08:34:47 -0800 Subject: Boxing function types In-Reply-To: <4B13C8B4.50706@cs.oswego.edu> References: <15e8b9d20911240847x3ab5a967q8edf3bfc732efbdc@mail.gmail.com> <15e8b9d20911250035l4c2e9201t5e8a3b9630bdb58f@mail.gmail.com> <4B0D5918.4040600@cs.oswego.edu> <15e8b9d20911251639p331ea4a9v4f9c42e112f0e771@mail.gmail.com> <4B0E77FC.2040701@cs.oswego.edu> <15e8b9d20911291544n7f98e07by2d6e7cb1ca55346a@mail.gmail.com> <4B13C8B4.50706@cs.oswego.edu> Message-ID: <15e8b9d20911300834w244e1386p7c481e869512345@mail.gmail.com> On Mon, Nov 30, 2009 at 5:29 AM, Doug Lea
wrote: > Neal Gafter wrote: > >> >> I'd love to hear you expand on this. I can't imagine what you might want >> to change in the core language's exception checking rules. I've done some >> language design to support asynchrony, and it transposes to Java very nicely >> assuming you have support for disjunctive types (exception transparency). >> >> > Suppose you'd like to parallelize some function f(x) > by dividing it into left and right parts. > Using you-know-what-I-mean syntax: > invokeAll(new F(left(x)), new F(right(x))); > by which you have implicitly claimed that the left > and right computations commute (i.e., order of evaluation > doesn't matter, so can run in parallel). But suppose > you are wrong about this claim in that: > when run sequentially, the left side > throws an exception before proceeding to right. > Now suppose that the right side also throws an exception. > And finally suppose that when run in parallel, the right > side throws an exception before the left even starts. > We want to (and do in FJ) just throw that right-side > exception, and make no claims in this case about > the left side, since we really don't know what would have > happened if run sequentially; and further are free not > to run it at all or kill it if the right side throws. > > So the issue is: If a programmer (perhaps implicitly) > claims that two computations commute, then > the exception thrown should be able to reflect > that assumption, so (re)throwing any exception encountered > should be OK. (Some people take the alternative > view that you should throw a bundled Exception > that represents all encountered exceptions, but > doing so is hard to mesh with common > policies to cancel sibling tasks upon first exception.) > Doug- That sounds great, but it also sounds like an API implementation issue, not a language issue, since it is up to the API to decide what order (or concurrently) to execute the two functions that are passed in (and what to do with any exceptions that may arise). Specifically, in the original code, the "new F..." creates a function object. That creation probably throws no exceptions. It is only the later invocation of the function that may throw an exception. Since there is no invocation of the function appearing in this source code, the Java Language Specification doesn't say anything at all about the order in which those exceptions may occur. So there is nothing in the JLS to relax regarding these circumstances. In other words, I don't see any issue with that the JLS currently says and what FJ currently does. The only thing I can imagine changing in the JLS regarding this situation is the addition of disjunction types (exception trandparency), so that it is possible to correctly type the functions so that checked exceptions can flow through these APIs. In other words (using the syntax of 0.6 and greatly simplifying the fork-join APIs), instead of declaring invokeAll like so: *void invokeAll(#void() left, #void() right) { ... }* which doesn't allow the functions to throw any checked exceptions, you declare it like so: * void invokeAll(#void()throws X left, #void()throws X right) throws X { ... }* (the implementation is probably the same) which allows the functions to throw any checked exception types, and causes the compiler to infer that any checked exception type that can be thrown by either function will be thrown by the invocation of invokeAll. I know the fork-join framework does not currently allow these workers to throw checked exceptions (because of limited expressivity of Java without something like the exception transparency of BGGA). But I don't think there is any issue about the *order* in which they're thrown. Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091130/b71e1a66/attachment.html From pbenedict at apache.org Mon Nov 30 08:57:12 2009 From: pbenedict at apache.org (Paul Benedict) Date: Mon, 30 Nov 2009 10:57:12 -0600 Subject: The philosophy of Nothing In-Reply-To: <15e8b9d20911300815l14c04b46r63bb2d512182fed@mail.gmail.com> References: <9f5c28201d5a4206fa4e59ab4881382e.squirrel@imap.fit.cvut.cz> <4B13691D.4090805@apache.org> <560fb5ed0911300223g43a5edecvfd0c6c4bb453e0dd@mail.gmail.com> <15e8b9d20911300815l14c04b46r63bb2d512182fed@mail.gmail.com> Message-ID: I am moving this discussion to closures-dev because that's where it should have been from the beginning. The original thread is here: http://mail.openjdk.java.net/pipermail/coin-dev/2009-November/002573.html Neal, Thanks for all your explanations thus far. What I am concerned about is the simplicity of the language. I fear having three very similar Java type for nothing is going to make the language confusing: * java.lang.Void * java.lang.Nothing * null type When I sit down and think about the need for java.lang.Nothing, I can't answer why java.lang.Void isn't considered. That effectively is nothing (a void). Couldn't that existing type fit the bill? Given this example: #() { throws AssertionError(); } Couldn't the compiler infer java.lang.Void and prevent assignment? Paul From neal at gafter.com Mon Nov 30 09:05:01 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 30 Nov 2009 09:05:01 -0800 Subject: The philosophy of Nothing In-Reply-To: References: <9f5c28201d5a4206fa4e59ab4881382e.squirrel@imap.fit.cvut.cz> <4B13691D.4090805@apache.org> <560fb5ed0911300223g43a5edecvfd0c6c4bb453e0dd@mail.gmail.com> <15e8b9d20911300815l14c04b46r63bb2d512182fed@mail.gmail.com> Message-ID: <15e8b9d20911300905o4282ea7bg8af7824d3ea6e302@mail.gmail.com> On Mon, Nov 30, 2009 at 8:57 AM, Paul Benedict wrote: > I am moving this discussion to closures-dev because that's where it > should have been from the beginning. The original thread is here: > http://mail.openjdk.java.net/pipermail/coin-dev/2009-November/002573.html > > Neal, > > Thanks for all your explanations thus far. What I am concerned about > is the simplicity of the language. I fear having three very similar > Java type for nothing is going to make the language confusing: > * java.lang.Void > * java.lang.Nothing > * null type > > When I sit down and think about the need for java.lang.Nothing, I > can't answer why java.lang.Void isn't considered. That effectively is > nothing (a void). Couldn't that existing type fit the bill? > > Given this example: > #() { throws AssertionError(); } > > Couldn't the compiler infer java.lang.Void and prevent assignment? > The requirement is to *allow* assignment to a variable of type #int(), not prevent it. The issue occurs no so much in the lambda conversion (where Nothing is not required for this behavior), but in the function subtype relationship. Void is a *unit* type, having a single valid value. As such, it is legal for void to occur in the flow of a program (and indeed it does occur everywhere you call a void method). Nothing on the other hand has *no*valid values. As such, reachable statement analysis can correctly infer that calling a method whose result is Nothing cannot complete normally. Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091130/4ae0102d/attachment.html From peter.levart at gmail.com Mon Nov 30 13:52:58 2009 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 30 Nov 2009 22:52:58 +0100 Subject: Disjunctive types In-Reply-To: <15e8b9d20911300834w244e1386p7c481e869512345@mail.gmail.com> References: <15e8b9d20911240847x3ab5a967q8edf3bfc732efbdc@mail.gmail.com> <4B13C8B4.50706@cs.oswego.edu> <15e8b9d20911300834w244e1386p7c481e869512345@mail.gmail.com> Message-ID: <200911302252.59105.peter.levart@gmail.com> Disjunctive types for exception transparency sound interesting. But how powerful can they be actually? Or to rephrase the question: How powerful are they allowed to be (by SUN)? For example: On Monday 30 November 2009 17:34:47 Neal Gafter wrote (in Re: Boxing function types): > void invokeAll(#void()throws X left, #void()throws X right) > throws X { ... } > would it be possible to call the above method with this: invokeAll( #() { if (new Random().nextBoolean()) throw new IOException(); else throw InterruptedException(); }, #() { if (new Random().nextBoolean()) throw new ParseException(); else throw InterruptedException(); } ); ...and expect the compiler to infer X to be IOException | ParseException | InterruptedException ? Maybe this is not the right way to express the intention. Would then at least be possible to change the signature of the above method to: void invokeAll(#void()throws X left, #void()throws Y right) throws X|Y; ...to achieve the same effect? Peter From neal at gafter.com Mon Nov 30 14:01:52 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 30 Nov 2009 14:01:52 -0800 Subject: Disjunctive types In-Reply-To: <200911302252.59105.peter.levart@gmail.com> References: <15e8b9d20911240847x3ab5a967q8edf3bfc732efbdc@mail.gmail.com> <4B13C8B4.50706@cs.oswego.edu> <15e8b9d20911300834w244e1386p7c481e869512345@mail.gmail.com> <200911302252.59105.peter.levart@gmail.com> Message-ID: <15e8b9d20911301401u7d99eb58s4bc4ef3e36f75e95@mail.gmail.com> Peter- I can't speak for Sun, but I can tell you that the exception transparency support in the BGGA prototype handles this kind of example with a single exception type parameter. There are situations where adding a type parameter for each closure doesn't work (e.g. if the method accepts an unbounded number of closures using varargs or a collection). Cheers, Neal On Mon, Nov 30, 2009 at 1:52 PM, Peter Levart wrote: > Disjunctive types for exception transparency sound interesting. > > But how powerful can they be actually? > > Or to rephrase the question: How powerful are they allowed to be (by SUN)? > > For example: > > On Monday 30 November 2009 17:34:47 Neal Gafter wrote (in Re: Boxing > function types): > > void invokeAll(#void()throws X left, #void()throws X right) > > throws X { ... } > > > > would it be possible to call the above method with this: > > invokeAll( > #() { > if (new Random().nextBoolean()) throw new IOException(); > else throw InterruptedException(); > }, > #() { > if (new Random().nextBoolean()) throw new ParseException(); > else throw InterruptedException(); > } > ); > > ...and expect the compiler to infer X to be IOException | ParseException | > InterruptedException > ? > > Maybe this is not the right way to express the intention. Would then at > least be possible to > change the signature of the above method to: > > void invokeAll(#void()throws X left, #void()throws Y > right) throws X|Y; > > ...to achieve the same effect? > > Peter > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091130/a682f509/attachment.html From pbenedict at apache.org Mon Nov 30 21:08:35 2009 From: pbenedict at apache.org (Paul Benedict) Date: Mon, 30 Nov 2009 23:08:35 -0600 Subject: The Philosophy of Nothing Message-ID: <4B14A4D3.3060300@apache.org> Some questions about Nothing that the spec may want to address: 1) How can the compiler absolutely prove that "statements or expressions cannot complete normally"? I imagine that can only be done if a "throw" is literally found in the method body. Can't method calls prevent the inference? 2) Outside of the whole closure conversation, can java.lang.Nothing be used? And is there value in it? For example: class Test { public Nothing throw_it() { throw new AssertionError(); } } 3) In regards to byte-code manipulation, what would happen at runtime if a class transformer takes the body of method that cannot return normally ("returns" java.lang.Nothing) and actually returns? The opposite case must be considered too. Would a JVM error be thrown? Paul From neal at gafter.com Mon Nov 30 21:53:08 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 30 Nov 2009 21:53:08 -0800 Subject: The Philosophy of Nothing In-Reply-To: <4B14A4D3.3060300@apache.org> References: <4B14A4D3.3060300@apache.org> Message-ID: <15e8b9d20911302153s5390b14g203501dd23bb79ef@mail.gmail.com> On Mon, Nov 30, 2009 at 9:08 PM, Paul Benedict wrote: > Some questions about Nothing that the spec may want to address: > > 1) How can the compiler absolutely prove that "statements or expressions > cannot complete normally"? I imagine that can only be done if a "throw" is > literally found in the method body. Can't method calls prevent the > inference? > The compiler has a conservative flow analysis that can prove that certain code is definitely unreachable. The specification for that is already in JLS3, and referenced in the 0.6 spec, with the appropriate additions already noted in 0.6. Throwing an exception is the most common way for it to happen, but with the introduction of Nothing calling a method that returns Nothing is another way. 2) Outside of the whole closure conversation, can java.lang.Nothing be used? > And is there value in it? For example: > class Test { > public Nothing throw_it() { > throw new AssertionError(); > } > } > Yes, but the most important use cases arise with closures. 3) In regards to byte-code manipulation, what would happen at runtime if a > class transformer takes the body of method that cannot return normally > ("returns" java.lang.Nothing) and actually returns? The opposite case must > be considered too. Would a JVM error be thrown? > Yes. It would be a NullPointerException at the call site (that's the only value the verifier would let be returned from a Nothing-returning method). The opposite case (failing to return from a method) isn't an issue. Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091130/8b4e63ef/attachment.html From pbenedict at apache.org Mon Nov 30 22:31:06 2009 From: pbenedict at apache.org (Paul Benedict) Date: Tue, 01 Dec 2009 00:31:06 -0600 Subject: The Philosophy of Nothing In-Reply-To: <15e8b9d20911302153s5390b14g203501dd23bb79ef@mail.gmail.com> References: <4B14A4D3.3060300@apache.org> <15e8b9d20911302153s5390b14g203501dd23bb79ef@mail.gmail.com> Message-ID: <4B14B82A.4070509@apache.org> Neal, 2) Outside of the whole closure conversation, can java.lang.Nothing be used? And is there value in it? For example: > > class Test { > public Nothing throw_it() { > throw new AssertionError(); > } > } > > > Yes, but the most important use cases arise with closures. Java existed all this time without caring whether methods complete or not. Neither Java reflection, dynamic language support, or JSR-292 has had a pressing desire to know this. Are we sure this is a good advancement in the language design? Aside from closure support, what is the value in saying a method returns Nothing? > 3) In regards to byte-code manipulation, what would happen at > runtime if a class transformer takes the body of method that > cannot return normally ("returns" java.lang.Nothing) and actually > returns? The opposite case must be considered too. Would a JVM > error be thrown? > > > Yes. It would be a NullPointerException at the call site (that's the > only value the verifier would let be returned from a Nothing-returning > method). The opposite case (failing to return from a method) isn't an > issue. I don't think NPE is very descript in this situation or useful in helping debugging. I think the error goes beyond bogus pointers and into something more deep. Can you consider a new Exception for this? Paul -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091201/24360ae1/attachment.html From neal at gafter.com Mon Nov 30 23:02:58 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 30 Nov 2009 23:02:58 -0800 Subject: The Philosophy of Nothing In-Reply-To: <4B14B82A.4070509@apache.org> References: <4B14A4D3.3060300@apache.org> <15e8b9d20911302153s5390b14g203501dd23bb79ef@mail.gmail.com> <4B14B82A.4070509@apache.org> Message-ID: <15e8b9d20911302302q33c931dau637985a7108e9e8a@mail.gmail.com> On Mon, Nov 30, 2009 at 10:31 PM, Paul Benedict wrote: > 2) Outside of the whole closure conversation, can java.lang.Nothing be > used? And is there value in it? For example: > > class Test { >> public Nothing throw_it() { >> throw new AssertionError(); >> } >> } >> > > Yes, but the most important use cases arise with closures. > > > > Java existed all this time without caring whether methods complete or not. > Neither Java reflection, dynamic language support, or JSR-292 has had a > pressing desire to know this. Are we sure this is a good advancement in the > language design? Aside from closure support, what is the value in saying a > method returns Nothing? > I don't think it is a critical feature in a language that doesn't have closures. 3) In regards to byte-code manipulation, what would happen at runtime if a >> class transformer takes the body of method that cannot return normally >> ("returns" java.lang.Nothing) and actually returns? The opposite case must >> be considered too. Would a JVM error be thrown? >> > > Yes. It would be a NullPointerException at the call site (that's the only > value the verifier would let be returned from a Nothing-returning method). > The opposite case (failing to return from a method) isn't an issue. > > > I don't think NPE is very descript in this situation or useful in helping > debugging. I think the error goes beyond bogus pointers and into something > more deep. Can you consider a new Exception for this? > Given that null is not a valid value for Nothing, and triggering the "problem" requires working under the covers, I don't see much value in adding to the platform another exception type. I did have to diagnose this kind of problem while writing the closures implementation, and I found it easy with the null pointer exception. I'd be interested to hear any experience to the contrary. Cheers, Neal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091130/51bb434b/attachment-0001.html