Iterable::forEach not returning Iterable
Brian Goetz
brian.goetz at oracle.com
Sun May 20 07:04:25 PDT 2012
The API invariant of "returns Iterable <==> is lazy" is a pretty
powerful self-documentation mechanism that helps people learn about and
reason confidently about what is going on. (More precisely, "returns
the same stream type as the input", since returning a Collection is in
some sense returning an Iterable.)
Breaking this just because "someone might want to write code like this"
seemed a questionable tradeoff.
On 5/20/2012 8:21 AM, Tomasz Kowalczewski wrote:
> I understand that forEach is eager and do not suggest it should be
> changed (although I can imagine lazy versions on some specialized
> collections working just fine for the user). This is rather an
> argument towards something that potentially is more user friendly and
> is based on the fluent interface pattern. Iterable::into is eager and
> does return a collection which allows user to chain the calls further,
> why not forEach then?
>
> Also, if some collection can be a start to a lazy->lazy->eager chain
> of calls then I do not see why operation such as forEach cannot be a
> start of another such chain (l->l->e->l etc..).
>
> Tomasz
>
> On Thu, May 17, 2012 at 7:16 PM, François Sarradin<fsarradin at gmail.com> wrote:
>> There are monads for these... ;)
>>
>> francois-
>> Le 17 mai 2012 16:30, "Rémi Forax"<forax at univ-mlv.fr> a écrit :
>>
>>> On 05/17/2012 04:05 PM, Brian Goetz wrote:
>>>> Of course, no one would write production code like this. Mappers are
>>>> supposed to be side-effect-free. But it is an acceptable sin for
>>>> temporary debugging code.
>>>
>>> Haskell guys, please don't read ...
>>>
>>> but logging is side effect free until you read the log in the program.
>>>
>>> Rémi
>>>
>>>>
>>>> On 5/17/2012 9:26 AM, Remi Forax wrote:
>>>>> You can use
>>>>> map(it -> {
>>>>> Log.log(it);
>>>>> return it;
>>>>> }).
>>>>> instead of forEach.
>>>>>
>>>>> Rémi
>>>>>
>>>>> Sent from my Phone
>>>>>
>>>>> ----- Reply message -----
>>>>> From: "Tomasz Kowalczewski"<tomasz.kowalczewski at gmail.com>
>>>>> To: "lambda-dev"<lambda-dev at openjdk.java.net>
>>>>> Subject: Iterable::forEach not returning Iterable
>>>>> Date: Thu, May 17, 2012 12:33
>>>>>
>>>>>
>>>>> Hi,
>>>>>
>>>>> I was trying out the new jdk8 build with lambdas and while doing some
>>>>> simple towards-lamda-refactoring I stumbled on following use case:
>>>>>
>>>>> List<File> files...
>>>>> files.filter( File::isFile ).filter( ... ).map(
>>>>> ConfigurationFile::new );
>>>>>
>>>>> I wanted to inject some debugging code inside this chain using forEach
>>>>> and realized that it returns void and not Iterable. Its default
>>>>> delegates to Iterables::forEach that returns Interable, so I guess it
>>>>> is just a matter of deciding if forEach should seal the pipe or allow
>>>>> more processing.
>>>>>
>>>>> Based on my example I think there is a great value in changing the
>>>>> return type from void as in my opinion it will be harder to debug and
>>>>> step through such lambdanized code than through several (ugly)
>>>>> for-each loops doing same work.
>>>>>
>>>>> P.S.: Atttaching eclipse debugger to this code being run in a simple
>>>>> main() instantly crashes the debugged JVM. But I guess debugging is
>>>>> not yet supported anyway :)
>>>>>
>>>
>>>
>>>
>>
>
More information about the lambda-dev
mailing list