}val mouthes = mouthProducer.getThoseMouthes()mouthes.foreach { mouth =>mouth.feed(food.next)mouth.clean(toothbrush) // Yeah, we're using the same tooth brush}mouthes
}mouth.feed(food.next)mouth.clean(toothbrush)
mouth
Rather than getting into arguments about the aesthetic of the code (which I'll leave to someone else)…
What you're relying on here is that map is consecutive and sequential. This is something you can generally rely on for non-parallel Seq, but you're technically not supposed to. In theory, Seq is free to run the map iteration in any order that is convenient. If that semantic changes (and it could), your code will unexpectedly break.
Is this a flagrant abuse of map? I
That is correct. IF you want sequential behavior, you have to run: foo.seq.map ....
Even foo.seq.map does not guarantee traversal order, only synchronicity and result order.
Daniel
Let me make something clear before things get too confused: the above
example will ALWAYS print 1, 2, 3. Seq is guaranteed not to be
parallel. It is GenSeq that allows the behavior described.
--
Daniel C. Sobral
I travel to the future all the time.
On the contrary. Guaranteeing traversal order is precisely what ".seq" does.
It does. It absolutely does. Every Seq guarantees traversal order.
GenSeq and ParSeq do not (a GenSeq may be either a Seq or a ParSeq).
And since we are speaking of sequentiality, Seq guarantees elements
are kept in such an order that let you refer to them by an index. Set,
Map, Iterable and Traversable do not offer this guarantee -- one can't
say that element x comes before or after element y (LinkedHashMap and
ListMap are exceptions to this rule). At any rate, this guarantee --
that you can say that some element comes before another -- is a
different guarantee than traversal order. A ParSeq does not guarantee
traversal order, while still being able to distinguish which element
comes first.
>
> On Thu, Apr 5, 2012 at 11:28 AM, Josh Suereth <joshua....@gmail.com>
> wrote:
>>
>> eh? It doesn't guarantee traveral order on anything that'd not a Seq, but
>> for a subclass of Seq that has a well-defined "order" to elements, .seq will
>> make it both synchronous and in-order. Not sure why you thought it
>> didn't....
>>
>>
>> On Thu, Apr 5, 2012 at 11:24 AM, Daniel Spiewak <djsp...@gmail.com>
>> wrote:
>>>
>>>
>>>> That is correct. IF you want sequential behavior, you have to run:
>>>> foo.seq.map ....
>>>
>>>
>>> Even foo.seq.map does not guarantee traversal order, only synchronicity
>>> and result order.
>>>
>>> Daniel
>>
>>
>
--
That guarantee did not exist, but when parallel collections were added
to the mix, it came to be, as we discovered lots of code depended on
it.
>
> Daniel
>
>
> On Thu, Apr 5, 2012 at 10:28 AM, Josh Suereth <joshua....@gmail.com>
> wrote:
>>
>> eh? It doesn't guarantee traveral order on anything that'd not a Seq, but
>> for a subclass of Seq that has a well-defined "order" to elements, .seq will
>> make it both synchronous and in-order. Not sure why you thought it
>> didn't....
>>
>>
>> On Thu, Apr 5, 2012 at 11:24 AM, Daniel Spiewak <djsp...@gmail.com>
>> wrote:
>>>
>>>
>>>> That is correct. IF you want sequential behavior, you have to run:
>>>> foo.seq.map ....
>>>
>>>
>>> Even foo.seq.map does not guarantee traversal order, only synchronicity
>>> and result order.
>>>
>>> Daniel
>>
>>
>
--
I'm not much of a fan of source-code-based requirements, but there's a
bigger issue here. When parallel collections were added to the mix,
and Seq could suddenly be a ParSeq, things broke. They did not break
because stuff was happening in parallel (though there's certainly
potential for that too), they broke because things were not happening
in an expected order.
I looked over the docs right now and I couldn't find any reference to
what Gen* guarantees or not, and how Traversable&children are expected
to work, and I think it is very important that it does.
That is correct. IF you want sequential behavior, you have to run: foo.seq.map ....
Order is guaranteed to be retained, but the order in which map traverses the sequence is not guaranteed.
Or rather, reading the rest of the posts, I can't figure out if that is in fact true. Regardless, it ought to be true, so I'm now convinced to stop such heretic coding.
IEnumerable is very different to Seq.
I do not think it has guaranteed order, see:
http://msdn.microsoft.com/en-us/library/dd460714.aspx
Yes, AsParallel
(http://msdn.microsoft.com/en-us/library/dd413237.aspx)'s ParallelQuery
is an IEnumerable:
http://msdn.microsoft.com/en-us/library/dd383736.aspx
IEnumerable is not immutable.
It's also not type-safe. IEnumerable.Select is subject to different
reasoning as a consequence of being mutable. Indeed, under any type
system that enforces these differences, IEnumerable.Select does not
correspond to map at all and Functor.map with a side-effecting argument
in Scala corresponds to traverse (Essence of the Iterator Pattern), not
map. That Scala conflates map and traverse ensures these topics in their
general form dominate discussion.
By the way, C# does have all the immutable structures of Scala and many
more -- I wrote them.
--
Tony Morris
http://tmorris.net/