Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #7813
| From | BGB <cr88192@hotmail.com> |
|---|---|
| Newsgroups | comp.lang.java.programmer |
| Subject | Re: new Java lambda syntax |
| Date | 2011-09-11 11:08 -0700 |
| Organization | albasani.net |
| Message-ID | <j4item$o69$1@news.albasani.net> (permalink) |
| References | <j4b80q$u30$1@dont-email.me> <alpine.DEB.2.00.1109101445260.18967@urchin.earth.li> <llbsj8-b59.ln1@news.simpsonst.f2s.com> <alpine.DEB.2.00.1109111255530.13018@urchin.earth.li> <9j3vj8-aqe.ln1@news.simpsonst.f2s.com> |
On 9/11/2011 9:18 AM, Steven Simpson wrote:
> On 11/09/11 13:06, Tom Anderson wrote:
>> On Sat, 10 Sep 2011, Steven Simpson wrote:
>>> * 'effectively final' - A non-final local variable can be immutably
>>> captured by a lambda, so long as it's shown not to be assigned to
>>> subsequently.
>>
>> Seems sensible. I would have been happy with a requirement for
>> explicit finality, but i recognise that many people would have been
>> annoyed by it, and i don't think this introduces any danger. Any idea
>> how hard it is for the compiler to prove that the variable cannot be
>> modified?
>
> Hmm, it's more strict than I thought (but easier to compile). It seems
> you have to be able to add final to the variable declaration. This
> compiles fine:
>
> void func() {
> int i = 0;
>
> Runnable action = () -> { System.out.println(i); };
> }
>
> ...but any assignment to 'i', before or after creating 'action',
> prevents 'i' from being effectively final.
>
> Hardly a disaster. :-)
>
I would have also liked to see lexical variable capture.
FFS, I added this (along with closures) to a C compiler before, can't be
too hard (never-mind the eventual fate of said C compiler, but alas, a
sad example of slow compile times and my apparently inability to
effectively debug it...).
more interestingly, they would look just like normal C function
pointers, and survive past the end of the parent scope (unlike, say,
their C++0x analogues, which apparently follow the much weaker/lamer
semantics of GCC's nested functions...).
in the case of lexically captured variables (both captured and mutable),
an implicit heap-based object could be created, representing any such
captured variables.
so:
void func()
{
int i=0;
Runnable fcn = ()=>{ i++; };
... do stuff with fcn ...
System.out.println(i);
}
the 'i' above could be itself folded into a class (any references to 'i'
would themselves implicitly be directed through this class).
sort of like (it compiled to):
void func()
{
private class __cap { public int i=0; } //invisible
__cap _cap=new __cap(); //invisible
Runnable fcn = ()=>{ _cap.i++; };
... do stuff with fcn ...
System.out.println(_cap.i);
}
now, assuming that the variable is effectively final, none of the above
is done, and the variable is copied by value (thus avoiding the cost of
the additional object).
>>> * 'long this' - In the body of a lambda, 'this' has the same meaning
>>> as it would in the enclosing scope. It does not refer to the
>>> object that ultimately fulfils the lambda.
>>
>> Also seems sensible. Are there any cases where you would want to refer
>> to the lambda object itself? I'm sure people will come up with them
>> once lambdas come into use. Will there be any way to get hold of such
>> a reference?
>
> Some corner cases came up, along with some work-arounds. They were
> probably recursive. I think assignment rules were altered slightly so
> that a lambda body could refer to itself:
>
> Runnable x = () -> { x.run(); };
>
> It was deemed okay to allow this because you can be certain that x will
> be ready before it is run.
>
yep.
still idly thinking here of syntax sugar for SAM types.
maybe even abusing an existing keyword:
public interface void SomeFunc(int x);
implicitly is (more or less) the equivalent of:
public interface SomeFunc
{
public void run(int x);
}
and maybe with a little syntax sugar also on the caller end:
SomeFunc func;
...
func(i); //internally: func.run(i);
...
granted, yes, it is all syntax sugar at this point.
>>> * 'throws T' - A set of exceptions can be expressed as a generic
>>> type parameter, so they can be relayed from the lambda's signature
>>> to the signature of the method that calls it.
>>
>> Oh, cool.
>
> Yes, except I'm not sure how useful it will be in practice with
> concurrent APIs. With a serial contract, like a library version of the
> for-each loop, it's clearly useful:
>
> interface Block<E, throws T> {
> void apply(E val) throws T;
> }
>
> static<E, throws T> void forEach(Iterable<E> coll, Block<E, T> block)
> throws T {
> for (Iterator<E> iter = coll.iterator(); iter.hasNext(); ) {
> E elem = iter.next();
> block.apply(elem);
> }
> }
>
> Now the forEach method can generically throw the same set of exceptions
> T that the block itself can throw.
>
> But if there is no serial guarantee on invoking the block, you have to
> choose whether you return arbitrarily just the first exception thrown,
> or pack them into some structure, or something else. I've a feeling
> that, most of the time, such methods will require the SAM type to throw
> nothing, so <throws T> won't get used.
>
>>> It could be argued that these restrictions seem to reduce lambdas to
>>> just a shorter syntax for certain anonymous inner classes. However, I
>>> think there's an aspiration to implement them more cheaply than
>>> normal objects.
>>
>> I'd be happy with them actually being syntactic sugar for anonymous
>> classes (i am quite unsophisticated my tastes!). The VM boffins could
>> then focus on making anonymous classes cheaper in general.
>
> I think they don't foresee such savings for anon classes generally,
> because they potentially have fields and multiple user-defined methods.
> When you're certain such complexities don't exist, which is the case for
> lambdas, certain optimizations become possible.
>
yes, optimize the special cases, this is generally how it works...
if one tries to optimize for the general cases, then one almost
invariably ends up with much added complexity and generally poor results.
potentially in cases where there is only a single method and no state
capture, ... the VM could potentially internally decay it into being
essentially a plain function pointer or similar (eliminating any class
or instances thereof).
less aggressive would be to only ever create a single instance, and all
references are to this, and probably some special-case call optimization.
>>> There are no automatically generated families of function types
>>> (yet), so you have to rely on SAM (single abstract method) types.
>>> Lambdas are just a syntactic construct until you've expressed or
>>> implied the SAM type, with an assignment, initialization or a cast.
>>
>> Oh, wait, what? Wow. There's no function type? So you can *only* use
>> lambdas as SAMs? Have i understood that correctly? That's kinky.
>
> You seem disturbingly excited by that! :-) Here are some arguments about
> it (not necessarily mine):
>
> * Function types would introduce a form of structural typing, which
> is a little alien to Java. We saw a thread here just a few days
> ago ("simple method to simulate function pointers in java"), where
> someone was hand-crafting generic function types, and some of the
> advice was just to define interfaces per situation, partly because
> it documents better, and partly because it's more idiomatic for Java.
> * Function types could be added in such a way that they would be SAM
> types, so if you can get lambdas to work with SAM types (which
> you'd probably have to do anyway to take advantage of old APIs),
> they should automatically work with function types added later.
> * A limited number of generic SAM types are being defined to extend
> the Collections API. They will probably serve as well as function
> types in the most common cases.
> * If a lambda is always typed as a SAM, how you invoke it is settled
> - it's the name of the SAM's method, of course. I recall seeing
> proposals where you could write obj(args), or obj.(args), or
> obj.invoke(args), where obj was a function type. Leave it as a
> SAM, and you don't have to make a decision about that.
>
lame, IMO...
having spent more of my time using languages with much nicer first-class
functions (yes, I will include C here, as well as JavaScript and
similar...), having to have extra syntax (both to declare and use these
types) is IMO lame.
in all cases, one would type "obj(args)".
idiomatic for Java or not, the more compact declarations and invocations
are more what people who use most other languages are likely to expect
(and ideally the compiler can be smart enough to figure out what
"obj(args)" with a SAM means).
although I kind of doubt this:
has anyone also considered the ability to grab existing methods from
objects/classes, and assign them to new method-fields?... (probably
restricted to a single parent class).
this can be nifty for some types of programs (mostly games, IME), as
then one can more easily have context-dependent methods.
C# also has something like this.
>
>> You say 'yet' - can we expect function types before it's finished?
>
> IIRC, no plans for Java 8 - back burner, I think. ISTR some difficulties
> arose, so maybe they decided they needed more time for something deemed
> not essential.
>
yep...
this is partly why I continued investing time/effort/... into my own VM
and language-design efforts. mature languages are slow-moving targets,
and so will not be like what oneself may want them to be "anytime soon".
a person may be then better off throwing together their own custom
language with the features they want, and mostly leave the people
working on more mature technology to do what they do well: keep the
thing as a reasonably "solid" piece of technology, as something which
changes too much too quickly may be perceived as being a bit flaky (and
this may actually be the case, if the addition of new features outpaces
things like optimizing and debugging them).
and, at the same time, the person who wants a more specialized language,
can have this as well...
the world isn't perfect but it is generally good enough...
Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Next in thread | Find similar
new Java lambda syntax markspace <-@.> - 2011-09-08 13:19 -0700
Re: new Java lambda syntax Roedy Green <see_website@mindprod.com.invalid> - 2011-09-08 15:18 -0700
Re: new Java lambda syntax Arne Vajhøj <arne@vajhoej.dk> - 2011-09-08 18:27 -0400
Re: new Java lambda syntax BGB <cr88192@hotmail.com> - 2011-09-08 15:40 -0700
Re: new Java lambda syntax Arne Vajhøj <arne@vajhoej.dk> - 2011-09-08 19:27 -0400
Re: new Java lambda syntax BGB <cr88192@hotmail.com> - 2011-09-08 16:29 -0700
Re: new Java lambda syntax Arne Vajhøj <arne@vajhoej.dk> - 2011-09-08 19:48 -0400
Re: new Java lambda syntax Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2011-09-08 17:56 -0700
Re: new Java lambda syntax BGB <cr88192@hotmail.com> - 2011-09-08 22:23 -0700
Re: new Java lambda syntax "Nasser M. Abbasi" <nma@12000.org> - 2011-09-08 16:41 -0700
Re: new Java lambda syntax Joshua Cranmer <Pidgeot18@verizon.invalid> - 2011-09-08 20:50 -0500
Re: new Java lambda syntax bugbear <bugbear@trim_papermule.co.uk_trim> - 2011-09-09 09:33 +0100
Re: new Java lambda syntax Tom Anderson <twic@urchin.earth.li> - 2011-09-10 14:48 +0100
Re: new Java lambda syntax Steven Simpson <ss@domain.invalid> - 2011-09-10 16:17 +0100
Re: new Java lambda syntax Tom Anderson <twic@urchin.earth.li> - 2011-09-11 13:06 +0100
Re: new Java lambda syntax Steven Simpson <ss@domain.invalid> - 2011-09-11 17:18 +0100
Re: new Java lambda syntax BGB <cr88192@hotmail.com> - 2011-09-11 11:08 -0700
Re: new Java lambda syntax Steven Simpson <ss@domain.invalid> - 2011-09-11 20:14 +0100
Re: new Java lambda syntax BGB <cr88192@hotmail.com> - 2011-09-11 14:08 -0700
Re: new Java lambda syntax Joshua Cranmer <Pidgeot18@verizon.invalid> - 2011-09-11 17:07 -0500
Re: new Java lambda syntax BGB <cr88192@hotmail.com> - 2011-09-11 16:18 -0700
Re: new Java lambda syntax Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-09-13 02:00 +0200
Re: new Java lambda syntax Arne Vajhøj <arne@vajhoej.dk> - 2011-09-12 20:59 -0400
Re: new Java lambda syntax Joshua Cranmer <Pidgeot18@verizon.invalid> - 2011-09-12 21:24 -0500
Re: new Java lambda syntax Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-09-13 21:04 +0200
Re: new Java lambda syntax Joshua Cranmer <Pidgeot18@verizon.invalid> - 2011-09-13 15:22 -0500
Re: new Java lambda syntax Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-09-13 23:25 +0200
Re: new Java lambda syntax Tom Anderson <twic@urchin.earth.li> - 2011-09-13 21:29 +0100
Re: new Java lambda syntax Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-09-13 23:26 +0200
Re: new Java lambda syntax supercalifragilisticexpialadiamaticonormalizeringelimatisticantations <supercalifragilisticexpialadiamaticonormalizeringelimatisticantations@averylongandannoyingdomainname.com> - 2011-09-13 20:25 -0400
Re: new Java lambda syntax Tom Anderson <twic@urchin.earth.li> - 2011-09-15 21:58 +0100
Re: new Java lambda syntax Joshua Cranmer <Pidgeot18@verizon.invalid> - 2011-09-13 21:36 -0500
Re: new Java lambda syntax supercalifragilisticexpialadiamaticonormalizeringelimatisticantations <supercalifragilisticexpialadiamaticonormalizeringelimatisticantations@averylongandannoyingdomainname.com> - 2011-09-13 22:49 -0400
Re: new Java lambda syntax "supercalifragilisticexpialadiamaticonormalizeringelimatisticantations" <supercalifragilisticexpialadiamaticonormalizeringelimatisticantations@averylongandannoyingdomainname.com> - 2011-09-14 02:49 -0400
Re: new Java lambda syntax supercalifragilisticexpialadiamaticonormalizeringelimatisticantations <supercalifragilisticexpialadiamaticonormalizeringelimatisticantations@averylongandannoyingdomainname.com> - 2011-09-14 03:01 -0400
Re: new Java lambda syntax "winkleMeister" <..00@00.00.00.1> - 2011-09-14 09:59 +0000
Re: new Java lambda syntax supercalifragilisticexpialadiamaticonormalizeringelimatisticantations <supercalifragilisticexpialadiamaticonormalizeringelimatisticantations@averylongandannoyingdomainname.com> - 2011-09-15 10:16 -0400
Re: new Java lambda syntax supercalifragilisticexpialadiamaticonormalizeringelimatisticantations <supercalifragilisticexpialadiamaticonormalizeringelimatisticantations@averylongandannoyingdomainname.com> - 2011-09-14 06:40 -0400
Re: new Java lambda syntax supercalifragilisticexpialadiamaticonormalizeringelimatisticantations <supercalifragilisticexpialadiamaticonormalizeringelimatisticantations@averylongandannoyingdomainname.com> - 2011-09-15 10:16 -0400
Re: new Java lambda syntax lightworker <etts@0n.org.null> - 2011-09-16 01:57 +0000
Re: new Java lambda syntax thoolen <th00len@th0lenbot.thorium> - 2011-09-15 22:41 -0400
Re: new Java lambda syntax Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-09-14 06:29 -0300
Re: new Java lambda syntax BGB <cr88192@hotmail.com> - 2011-09-14 07:40 -0700
Re: new Java lambda syntax Lew <lewbloch@gmail.com> - 2011-09-14 08:01 -0700
Re: new Java lambda syntax BGB <cr88192@hotmail.com> - 2011-09-14 14:50 -0700
Re: new Java lambda syntax Lew <lewbloch@gmail.com> - 2011-09-14 18:02 -0700
Re: new Java lambda syntax BGB <cr88192@hotmail.com> - 2011-09-14 21:08 -0700
csiph-web