# Magic of for(if) expression

9 replies
Eastsun 2
Joined: 2008-12-20,

Consider the problem:
count the number of different continuous parts in a List, e.g.
count(1::1::1::2::2::1::1::1::Nil) == 3

The first solution:

scala> def count[T](ls: List[T]): Int ={
| if(ls.isEmpty) return 0
| var pre = ls.head
| var cnt = 1
| for(x <- ls) if(x != pre){ pre = x; cnt += 1 }
| cnt
| }
count: [T](List[T])Int

scala> count(1::1::1::2::2::1::1::1::Nil)
res4: Int = 3

And there is another solution modify from the first one:
scala> def count2[T](ls: List[T]): Int = {
| if(ls.isEmpty) return 0
| var pre = ls.head
| var cnt = 0
| for(x <- ls;if x != pre){ pre = x; cnt += 1 }
| cnt
| }
count2: [T](List[T])Int

It's seems OK at the first sight,let's check it:
scala> count2(1::1::1::2::2::1::1::1::Nil)
res6: Int = 2

Oops, what's wrong?
Because in scala the
for(e <- ls; if cond) { expr }
would translate to something like this:
ls.filter{e => cond}.foreach{ expr }

And then
for(x <- ls;if x != pre){ pre = x; cnt += 1 }
would translate to
ls.filter{ _ != pre}.foreach{ x => pre = x; cnt += 1}

So it doesn't work as expected.

My question: Is there any special reason is scala that for(e <- ls;if cond){
expr } translate to
ls.filter{e => cond}.foreach{e => expr }
rather than
ls.foreach{ case e if cond => expr; case _ => } ?

-----
My scala solutions for http://projecteuler.net/ Project Euler problems:

extempore
Joined: 2008-12-17,
Re: Magic of for(if) expression

On Tue, Oct 06, 2009 at 10:24:55PM -0700, Eastsun wrote:
> My question: Is there any special reason is scala that for(e <- ls;if
> cond){ expr } translate to ls.filter{e => cond}.foreach{e => expr }
> rather than ls.foreach{ case e if cond => expr; case _ => } ?

http://lampsvn.epfl.ch/trac/scala/ticket/757
"For comprehensions with a foreach should desugar guards differently."

And on the same general subject:

http://lampsvn.epfl.ch/trac/scala/ticket/1336
"filter incorrectly optimized away"

Eastsun 2
Joined: 2008-12-20,
Re: Magic of for(if) expression

Is there any plan to change the behavior of for(if) expression in Scala 2.8?

Paul Phillips wrote:
>
> On Tue, Oct 06, 2009 at 10:24:55PM -0700, Eastsun wrote:
>> My question: Is there any special reason is scala that for(e <- ls;if
>> cond){ expr } translate to ls.filter{e => cond}.foreach{e => expr }
>> rather than ls.foreach{ case e if cond => expr; case _ => } ?
>
> http://lampsvn.epfl.ch/trac/scala/ticket/757
> "For comprehensions with a foreach should desugar guards differently."
>
> And on the same general subject:
>
> http://lampsvn.epfl.ch/trac/scala/ticket/1336
> "filter incorrectly optimized away"
>

dcsobral
Joined: 2009-04-23,
Re: Magic of for(if) expression
Surely not, as it would break lots of code.   The behavior of "if" is perfectly functional -- it is a guard on the values comprehended by the for comprehension. It's easily parallelizable too.   On Wed, Oct 7, 2009 at 9:52 AM, Eastsun <flushtime [at] 126 [dot] com> wrote:

Is there any plan to change the behavior of for(if) expression in Scala 2.8?

Paul Phillips wrote:
>
> On Tue, Oct 06, 2009 at 10:24:55PM -0700, Eastsun wrote:
>> My question: Is there any special reason is scala that for(e <- ls;if
>> cond){ expr } translate to ls.filter{e => cond}.foreach{e => expr }
>> rather than ls.foreach{ case e if cond => expr; case _ => } ?
>
> http://lampsvn.epfl.ch/trac/scala/ticket/757
> "For comprehensions with a foreach should desugar guards differently."
>
> And on the same general subject:
>
> http://lampsvn.epfl.ch/trac/scala/ticket/1336
> "filter incorrectly optimized away"
>
> --
> Paul Phillips      | On two occasions, I have been asked, 'Mr. Babbage, if
> you
> Imperfectionist    | put into the machine wrong figures, will the right
> Empiricist         | come out?' I am not able to rightly apprehend the
> kind of
> slap pi uphill!    | confusion of ideas that could provoke such a
> question.
>
>

-----
My scala solutions for  http://projecteuler.net/ Project Euler  problems:
--
View this message in context: http://www.nabble.com/Magic-of-for%28if%29-expression-tp25780727p25783961.html
Sent from the Scala - Debate mailing list archive at Nabble.com.

--
Daniel C. Sobral

Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
Joined: 2009-02-19,
Re: Magic of for(if) expression

Eastsun wrote:
> Is there any plan to change the behavior of for(if) expression in Scala 2.8?

As for me I'm pretty sure that it should not be changed that way.
for-comprehension is not c-like for loop, so do not expect stateful
behavior.

Martin Odersky
Joined: 2009-10-07,
Re: Magic of for(if) expression

Sent from my iPhone

On Oct 7, 2009, at 14:52, Eastsun wrote:

>
> Is there any plan to change the behavior of for(if) expression in
> Scala 2.8?

No plans so far, but it can be discussed. But whatever we do should
work the same for for-yield. --m
>
> Paul Phillips wrote:
>>
>> On Tue, Oct 06, 2009 at 10:24:55PM -0700, Eastsun wrote:
>>> My question: Is there any special reason is scala that for(e <-
>>> ls;if
>>> cond){ expr } translate to ls.filter{e => cond}.foreach{e => expr }
>>> rather than ls.foreach{ case e if cond => expr; case _ => } ?
>>
>> http://lampsvn.epfl.ch/trac/scala/ticket/757
>> "For comprehensions with a foreach should desugar guards
>> differently."
>>
>> And on the same general subject:
>>
>> http://lampsvn.epfl.ch/trac/scala/ticket/1336
>> "filter incorrectly optimized away"
>>

Eastsun 2
Joined: 2008-12-20,
Re: Magic of for(if) expression

In my mind, the filter method shoudn't be use in both for(if cond){expr} and
for(if) yield {expr}.
For one thing,it could improve the performance of the for(if) expression by
this way.
For another, it should make variable in the {cond} visible in {expr} as
Java.

I'm not an expert in scala, so forgive me if my opinon looks silly.

martin odersky-2 wrote:
>
>
>
> Sent from my iPhone
>
> On Oct 7, 2009, at 14:52, Eastsun wrote:
>
>>
>> Is there any plan to change the behavior of for(if) expression in
>> Scala 2.8?
>
> No plans so far, but it can be discussed. But whatever we do should
> work the same for for-yield. --m
>>
>> Paul Phillips wrote:
>>>
>>> On Tue, Oct 06, 2009 at 10:24:55PM -0700, Eastsun wrote:
>>>> My question: Is there any special reason is scala that for(e <-
>>>> ls;if
>>>> cond){ expr } translate to ls.filter{e => cond}.foreach{e => expr }
>>>> rather than ls.foreach{ case e if cond => expr; case _ => } ?
>>>
>>> http://lampsvn.epfl.ch/trac/scala/ticket/757
>>> "For comprehensions with a foreach should desugar guards
>>> differently."
>>>
>>> And on the same general subject:
>>>
>>> http://lampsvn.epfl.ch/trac/scala/ticket/1336
>>> "filter incorrectly optimized away"
>>>
>>> --
>>> Paul Phillips | On two occasions, I have been asked, 'Mr.
>>> Babbage, if
>>> you
>>> Imperfectionist | put into the machine wrong figures, will the
>>> right
>>> Empiricist | come out?' I am not able to rightly apprehend
>>> the
>>> kind of
>>> slap pi uphill! | confusion of ideas that could provoke such a
>>> question.
>>>
>>>
>>
>>
>> -----
>> My scala solutions for http://projecteuler.net/ Project Euler
>> problems:

Eastsun 2
Joined: 2008-12-20,
Re: Magic of for(if) expression

And a filterMap or partialMap as mentioned in
http://www.nabble.com/-scala--Scala-List-processing-performance-td107637...
http://www.nabble.com/-scala--Scala-List-processing-performance-td107637...
would solve the problem.

def partialMap[B, That](f: PartialFunction[A,B])(implicit bf:
BuilderFactory[B, That, Repr]): That = {
val b = bf(repr)
for (x <- this) if(f.isDefineAt(x)) b += f(x)
b.result
}

for(e <- xs;if cond) yield expr
<=>
xs.partialMap(...)

martin odersky-2 wrote:
>
>
>
> Sent from my iPhone
>
> On Oct 7, 2009, at 14:52, Eastsun wrote:
>
>>
>> Is there any plan to change the behavior of for(if) expression in
>> Scala 2.8?
>
> No plans so far, but it can be discussed. But whatever we do should
> work the same for for-yield. --m
>>
>> Paul Phillips wrote:
>>>
>>> On Tue, Oct 06, 2009 at 10:24:55PM -0700, Eastsun wrote:
>>>> My question: Is there any special reason is scala that for(e <-
>>>> ls;if
>>>> cond){ expr } translate to ls.filter{e => cond}.foreach{e => expr }
>>>> rather than ls.foreach{ case e if cond => expr; case _ => } ?
>>>
>>> http://lampsvn.epfl.ch/trac/scala/ticket/757
>>> "For comprehensions with a foreach should desugar guards
>>> differently."
>>>
>>> And on the same general subject:
>>>
>>> http://lampsvn.epfl.ch/trac/scala/ticket/1336
>>> "filter incorrectly optimized away"
>>>
>>> --
>>> Paul Phillips | On two occasions, I have been asked, 'Mr.
>>> Babbage, if
>>> you
>>> Imperfectionist | put into the machine wrong figures, will the
>>> right
>>> Empiricist | come out?' I am not able to rightly apprehend
>>> the
>>> kind of
>>> slap pi uphill! | confusion of ideas that could provoke such a
>>> question.
>>>
>>>
>>
>>
>> -----
>> My scala solutions for http://projecteuler.net/ Project Euler
>> problems:

Joined: 2008-12-21,
Re: Magic of for(if) expression

Eastsun wrote:
>
> Consider the problem:
> count the number of different continuous parts in a List, e.g.
> count(1::1::1::2::2::1::1::1::Nil) == 3
>

val list = List(1, 1, 1, 2, 2, 1, 1, 1, Nil)
val sections = list.foldLeft(0)(a, b => if (a == b) None else
Some(a)).flatten
val count = sections.length

Eastsun 2
Joined: 2008-12-20,
Re: Magic of for(if) expression

I find that filterMap is exist in Scala2.8.0 which be marked with
@experimental just now.
Well, then, it is natural and simple way to translate
for(e <- ls;if cond) yield { expr }
to
ls.filterMap{ case e if cond => expr }

Eastsun wrote:
>
> And a filterMap or partialMap as mentioned in
> http://www.nabble.com/-scala--Scala-List-processing-performance-td107637...
> http://www.nabble.com/-scala--Scala-List-processing-performance-td107637...
> would solve the problem.
>
>
> def partialMap[B, That](f: PartialFunction[A,B])(implicit bf:
> BuilderFactory[B, That, Repr]): That = {
> val b = bf(repr)
> for (x <- this) if(f.isDefineAt(x)) b += f(x)
> b.result
> }
>
> for(e <- xs;if cond) yield expr
> <=>
> xs.partialMap(...)
>
>
> martin odersky-2 wrote:
>>
>>
>>
>> Sent from my iPhone
>>
>> On Oct 7, 2009, at 14:52, Eastsun wrote:
>>
>>>
>>> Is there any plan to change the behavior of for(if) expression in
>>> Scala 2.8?
>>
>> No plans so far, but it can be discussed. But whatever we do should
>> work the same for for-yield. --m
>>>
>>> Paul Phillips wrote:
>>>>
>>>> On Tue, Oct 06, 2009 at 10:24:55PM -0700, Eastsun wrote:
>>>>> My question: Is there any special reason is scala that for(e <-
>>>>> ls;if
>>>>> cond){ expr } translate to ls.filter{e => cond}.foreach{e => expr }
>>>>> rather than ls.foreach{ case e if cond => expr; case _ => } ?
>>>>
>>>> http://lampsvn.epfl.ch/trac/scala/ticket/757
>>>> "For comprehensions with a foreach should desugar guards
>>>> differently."
>>>>
>>>> And on the same general subject:
>>>>
>>>> http://lampsvn.epfl.ch/trac/scala/ticket/1336
>>>> "filter incorrectly optimized away"
>>>>
>>>> --
>>>> Paul Phillips | On two occasions, I have been asked, 'Mr.
>>>> Babbage, if
>>>> you
>>>> Imperfectionist | put into the machine wrong figures, will the
>>>> right
>>>> Empiricist | come out?' I am not able to rightly apprehend
>>>> the
>>>> kind of
>>>> slap pi uphill! | confusion of ideas that could provoke such a
>>>> question.
>>>>
>>>>
>>>
>>>
>>> -----
>>> My scala solutions for http://projecteuler.net/ Project Euler
>>> problems:
>>> --
>>> View this message in context:
>>> http://www.nabble.com/Magic-of-for%28if%29-expression-tp25780727p2578396...
>>> Sent from the Scala - Debate mailing list archive at Nabble.com.
>>>
>>
>>
>
>

-----
My scala solutions for http://projecteuler.net/ Project Euler problems: