Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!news.albasani.net!.POSTED!not-for-mail From: BGB Newsgroups: comp.lang.java.programmer Subject: Re: new Java lambda syntax Date: Sun, 11 Sep 2011 16:18:59 -0700 Organization: albasani.net Lines: 86 Message-ID: References: <9j3vj8-aqe.ln1@news.simpsonst.f2s.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Trace: news.albasani.net /BSlkT2oz86Fit8YXP726jQzZKvS2Iv0fuMXs94fMVADjlBHxHjy/Cooon4q6DeKrNoiRmO+DNThRwISNbHtKg== NNTP-Posting-Date: Sun, 11 Sep 2011 23:18:51 +0000 (UTC) Injection-Info: news.albasani.net; logging-data="kzygRjlwuwENPCxdyWRxiJohQXd1Z1MTe0crlW9yVIkrIGbgenO7jSRDqXmogplj8hax4hP67cQPc1uR660uwSX3D5PFOHOh7j9QgUQ87yDPvQORZn+AEsM3xMZX1Bvj"; mail-complaints-to="abuse@albasani.net" User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20110902 Thunderbird/6.0.2 In-Reply-To: Cancel-Lock: sha1:swq6uJUNfB3K7T47CUqnrspFNrA= Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:7836 On 9/11/2011 3:07 PM, Joshua Cranmer wrote: > On 9/11/2011 2:14 PM, Steven Simpson wrote: >> On 11/09/11 19:08, BGB wrote: >>> 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 >> >> At this stage, I don't think the issue is how, but whether/when to >> permit it. > > There are other issues like does it capture the value or does it use the > same variable. e.g., what would this produce: > > List runners = new LinkedList(); > for (int i = 0; i < 10; i++) { > runners.add(() => { System.out.println("Value of i is " + i); }); > } > for (Runnable r : runners) { > r.run(); > } > > Should you see 0..9 or 10 repeated 10 times? > most languages I am aware of with closures (and mutable state) capture the variable itself, so one would see 10 repreated 10 times (since the original variable now holds 10). in a different context, I had run into this issue, and added a special form to the block (theoretically, IIRC not yet implemented) to explicitly capture the state of the variable at that point (rather than a reference to this variable). interestingly, this internally converted into a closure which accepted the variables as arguments and was then called with these variables. a more generalized form of this would look something like: for(i=0; i<10; i++) begin(i) { ... } ... with "begin(i) { ... }" basically meaning to execute '...' with 'i' having been captured (by value). this could also be user like "begin(i, j) {...}" to capture two values, or "begin(i, j=i*251) {...}" to capture the value of i and bind j as a computed value (sort of like "(let)" and friends in Lisp and Scheme). however, I have doubts that such a feature would map nearly so cleanly to Java or the JVM. in C++0x, the type of variable capture was made explicit in the lambda syntax: "[](...) {...}" (no capture allowed) vs "[&](...) {...}" (capture by reference) vs "[=](...) {...}" (capture by value). vs more complex forms... >> For invocations, having to type obj.run() instead of obj() is hardly >> onerous. Plus, invocations will be much rarer than lambda declarations. >> Also note that the invocation site is unaware of whether the object is a >> lambda. > > Also, note the (slight) benefits of explicitly saying what you are > doing. You might choose, reasonably, to call the callback parameter for > an asyncForEach function `block', at which point the functional call > specification becomes block(value), which can be visually ambiguous as > to what it's doing. block.call(value) is clearer, on the other hand. > yes, but I guess it depends some on what one is doing, and whether or not it is better to complicate some potential use cases for sake of preventing people from shooting themselves in the foot in others (or, OTOH, gloss over certain complexities at the risk of people then shooting themselves in the foot...). or such...