summary of point lambdafication survey

Stuart Marks stuart.marks at oracle.com
Fri Sep 23 11:29:39 PDT 2011


Here are some comments on the survey results. These are my opinions only; no 
decisions have been made on any of this stuff yet.

> * java.util.logging.Logger -- log(level, Callable<String>) -- 3 requests
>    - pass a function that generates a log message
>    - avoids overhead of string creation if level isn't enabled
>    - variations for finest(), info(), etc.
>    - need to deal with Exception thrown from Callable.call()

The current logging APIs seem to be a sore point; the main concerns seem to be 
avoiding useless message creation overhead and code clutter. Seems like lambda 
can help a lot here.

This is an instance of using lambda for delayed evaluation.

> * BufferedReader.eachLine(block) -- 3 requests
>    - run a block on each line read
>    - variations with filtering

This was pretty popular too. However, current thinking seems to be to expose 
the individual items of an aggregate as an Iterable instead of adding 
forEach(block) APIs. Having an Iterable facilitates use of the enhanced-for 
statement. It also facilitates passing to the new filter(), map(), etc. 
functions. This seems quite attractive, as it avoids filtered, extracted, 
massaged, etc. variations that would seem to be necessary if we were to add a 
forEach(block) style API.

> * java.util.concurrent.locks.Lock -- withLock(block) -- 2 requests
>    - runs block with lock held, release lock in finally-clause
>    - variations for lock with timeout, tryLock

An example of the execute-around idiom; seems like it would save some code clutter.

> * java.util.regex -- each() on Pattern, Matcher, or String -- 2 requests
>    - run a block on each match, possibly returning a replacement

Possibly expose an Iterable instead of forEach(lambda). Seems promising, 
especially in conjunction with enhanced line processing in BufferedReader.

> * java.sql.ResultSet -- each(block) -- 2 requests
>    - run a block for each row in a ResultSet
>
> * java.nio.Buffer family -- forEach(block)
>    - runs block on each buffer element

More examples of forEach that are probably better off as Iterables.

> * Swing/AWT event listeners -- multiple requests
>    - rearrange non-SAM listeners to be suitable for lambdas
>
> * SwingUtilities executeAndWait(callable), invokeAndWait(callable)
>    - convenience functions for current APIs, possibly also returning a value
>
> * SwingWorker(callable)
>    - convenience method for creating a SwingWorker
>    - callable supplies implementation of doInBackground()

I'm kind of distant from AWT/Swing, but those APIs seem to be a fertile ground 
for improvements using lambda. I'll forward this stuff to the client folks. Of 
course, anyone is free to suggest these ideas on the appropriate mailing lists 
(probably swing-dev or awt-dev).

> * java.nio.channels.FileChannel -- lockDuring(block)
>    - runs block with file lock held, release lock in finally-clause
>    - variation for tryLock

Another execute-around.

> * java.nio.file.Files -- eachFile(block)
>    - run block for each file in a directory

Another example better expressed via Iterable. This would also be interesting 
in combination with the nio FileVisitor stuff exposed as an Iterable.

> * Collections.toMap(keyGen)
>    - for each element in a Collection, generate a key, store into a Map
>    - could be a static utility method or an extension method

This is interesting. It's sort-of halfway between two different ideas.

One take would be for it to take a value-generating lambda (a Mapper) which 
would be run over each element in a Set. The result would be a Map object whose 
keys are the elements from the Collection and whose values are the results from 
the Mapper.

Another take is to generate keys from each element of a Collection; the 
question then what to do in the case of duplicate keys. We'd want the resulting 
Map to have multiple values for a single key. This could be expressed as a 
(hypothetical) MultiMap, or as an ordinary Map whose values are Lists.

> * Process.onExit(block)
>    - execute block when the process exits
>
> * Integer.times(block) -- execute block N times
>
> * Objects.equals(obj1, obj2, fieldGetters...)
>    - helper method for writing equals() methods
>    - handles identity, casting, field-by-field comparisons
>
> * Throwable.visitCauses(block)
>    - run block for each throwable in the chain of causes
>
> * ThreadLocal(callable)
>    - callable supplies the implementation of initialValue()
>    - provides lazy initialization of thread-locals
>
> s'marks


More information about the lambda-dev mailing list