alessiostalla at gmail.com
Tue Jul 13 09:10:32 PDT 2010
On Tue, Jul 13, 2010 at 5:23 PM, Neal Gafter <neal at gafter.com> wrote:
> On Tue, Jul 13, 2010 at 1:45 AM, Alessio Stalla <alessiostalla at gmail.com>
>> > What you call "code block" would likely be used in most circumstances
>> > without any contained control-flow
>> > constructs. In other words, you appear to be naming distinct use cases
>> > rather than distinct language constructs.
>> No, because the two "use cases" give the language different semantics.
>> With lambdas-as-functions one can copy-paste the body of a method in
>> the body of a closure and it will "just work". With lambdas-as-blocks
>> that doesn't hold.
> With lambdas-as-blocks you can just copy-paste a block of code into a lambda
> to delay its execution. With lambdas-as-method-bodies that doesn't hold.
I agree! That's why the two are different language constructs, not
simply different use cases for the same construct.
>> > Many languages that have "functions" that can nest, side-effects, and
>> > acknowledge failure also have
>> > transparent "return" (lisp, smalltalk, scala, etc).
>> I don't know Smalltalk nor Scala, but Lisp surely has no transparent
>> return by default.
> Common lisp's "return" will pass transparently though any number of
> intervening lambda boundaries.
Not really. First, "return" is not the default way to return a value
in Lisp; most of the time you don't use an explicit return, and the
value of the last expression in the function body is returned. Second,
Common Lisp's return is equivalent to (return-from nil), i.e., it
returns from the lexically closest block named nil. Functions do not
introduce such a block, so by default, return indeed will pass through
a function call (note that I said function, not lambda). However, the
user can introduce blocks and limit the extent of the return. In
short, CL's return does not exactly map to any concept in Java,
already present or proposed here.
>> You have to tell it explicitly to do a long return
>> with (return-from <enclosing-lexical-block-name>), and that's a
>> seldom-used feature (but Lisp has macros, making the use of closures
>> for control structures unnecessary).
> Macros and transparent lambdas are incomparable in expressive power.
Yes, it's just that macros are often used to implement control
structures that, without macros, would likely be implemented with
>> Languages in the ML family also
>> don't have long return, at least not by default.
> Not a "local" return. But you can define a returning construct, which would
> then be transparent.
i.e., it's not the default.
>> > Designing a new language construct to do exactly what you can already do
>> > is
>> > not the best way to increase the flexibility of the language.
>> > In any case, my suggested definition appears here:
>> > <http://gafter.blogspot.com/2007/01/definition-of-closures.html>. Feel
>> > free
>> > to substitute "lambda" for "closure" in most of that. That post also
>> > has
>> > pointers to a number of papers that explain in more detail the utility
>> > of
>> > lambdas in the sense defined there.
>> Lambda and closure are two orthogonal concepts. Lambda means anonymous
>> function, where "function" does not necessarily imply "closure".
>> Closure means a function that captures the lexical environment it's
>> been defined in, and can be named or unnamed (lambda). In that sense,
>> lambdas can be mapped to anonymous SAM types in Java, while closures
>> cannot (since anonymous inner classes only capture a fraction of their
>> outer lexical environment, final local variables).
> Lambdas are *capable* of capturing the lexical environment; when they do,
> they are closures. You've found one of many reasons that anonymous inner
> classes are neither lambdas nor full closures.
Lambdas are capable iff functions are capable. It is conceivable to
have a language with lambda but without lexical closures; early,
dynamically scoped Lisps were like that. Of course, functions which
are also closures are the norm nowadays, for good reasons. However, if
one considers SAM classes as approximations of first-class functions,
then Java's "functions" are not closures. So if you speak of adding
closures to Java, one can and often will interpret it as making SAMs
be real closures. That's why I'm advocating to use different words
than lambda and closure, if you have different objectives.
>> In any case, long
>> control transfer by default ihmo contrasts with the concept of
>> function altogether, so neither lambda nor closure would be a fitting
> Indeed, a void-returning thing contrasts with the concept of function
> altogether as well.
I think you're constantly missing the "by default" part. Yes, if
"functions" returned void by default, and returning a value was the
exception, they wouldn't be really functions. If they return a value
by default, but have the option to return no value, and to make long
returns, they're still functions, with a few more features. That's
subjective, to a certain degree, but programming language concepts are
rarely black-or-white. You can write purely imperative code in Java,
but that doesn't make it less OO. You can write OO code in C, but that
doesn't make it less imperative. You can write all your functions with
long return in ML or Lisp, but that won't change the nature of
functions in those languages.
>> I'd really keep the two concepts separate; the same object
>> cannot be both a function to be mapped over the elements of a
>> collection and the body of a user-defined control structure.
> Huh? Why not? The only difference is whether or not it yields a new value
> or not (void result type).
And whether, when it yields a value, it does so by default with a
local or long return. And note that the yield keyword is not the
default way to return a value in Java. I think that returning void or
not is much less significant; after all, if something other than void
is returned when no-one expects a value, it will be discarded. If void
is returned when someone expects a value, a compile-time error is
raised. That's how Java works today.
More information about the lambda-dev