London Lambdas Hackday: Existing Code

Richard Warburton richard.warburton at gmail.com
Wed Jul 4 05:55:51 PDT 2012


> Well, we learned one thing -- that easy examples just work.  That's
> something.

Yes, I've heard a few people express concerns to me that lambdas will
be a language feature that few understand correctly.  The concern
seems especially prevalent from those who work with offshore'd
development teams.  I don't think I've seen any changes that
compromise readability so far in sequential cases, so even if it might
not allay the fears then it does demonstrate that they aren't grounded
in reality.

>> My only comment building on this is that variable scoping makes
>> converting anonymous inner classes more difficult than absolutely
>> necessary. The context to this was a programmer converting anonymous
>> inner classes in some existing code to lambdas in order to remove
>> boilerplate.  Due to the fact that the inner function had a variable
>> with the same name as a variable that had been defined in the outer
>> method, he received a “error: variable num is already defined in
>> method” message.
>
> This is one of those things that is still under discussion.  The "no
> shadowing" rule comes from a motivation that lambdas are more like ordinary
> blocks of code (like the body of an 'if') than like inner classes, and
> shadowing is prohibited in those contexts.  But we're not sure if this helps
> or hurts.

Hmm, but blocks don't have the "only effectively final capture"
property that lambdas do, they just exist in the scope of the method,
I suspect that people will be caught out by this.

>> People using Guava's predicate library already will have an interface
>> doing something identical to the Java 8 Predicate.  Furthermore they
>> will be able to
>
> to?

hmm, apologies, let's back this sentence up a bit:

Furthermore they already have a large body of predicate instances that
exist within the guava space.  Or that they may be using within their
own code.  These won't be usable with Java 8 predicates because they
are of a different nominal type.

The only way I could think of addressing this issue was allowing
implicit type conversions at target typed locations between functional
interfaces if they have the same structural type.  So you'd be able to
write:

 java.util.functions.Predicate<?> TT =
com.google.common.base.Predicates.alwaysTrue();

I used the full imports used for the sake of making the example clear,
not advocating that as idiomatic.  You'd also be able to pass in
existing guava predicates into the common libraries.  Again I mention
that its not just guava that this issue will crop up with, there's
quite a few other libraries with similar constructs.

> Actually, its more complicated than that.  You can take a method reference
> to an instance method in two ways, bound and unbound.  Both are useful; I
> think the unbound form is probably more useful.  For class C, if you have an
> instance method foo of type T->U, then
>
>   C::foo
>
> is of type (C, T) -> U and
>
>   instanceOfC::foo
>
> is of type T -> U.
>
> The unbound form shows up in "map" a lot:
>
>       people.filter(Person::isTall)
>             .map(Person::getHeight)
>             .into(tallPeopleHeights);
>
> Here, the instance is provided by the stream.

Ahh yes, I had totally missed that, my bad.  But it does make the
point even clearer that people need to take some thought before they
can actually get to grips with method references.

> Good point.  In this case, maybe better to just use a lambda for
> readability:
>
>   timestamps.map(t -> LocalDate.from(t))
>             .into(...)

Ahh yes, so its really a question of whether you should be using
method references at all in this circumstance.

regards,

  Richard


More information about the lambda-dev mailing list