Magic of for(if) expression

View: New views
10 Messages — Rating Filter:   Alert me  

Magic of for(if) expression

by Eastsun :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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 Project Euler problems: Click here

Re: Magic of for(if) expression

by Paul Phillips-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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 answers
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.

Re: Magic of for(if) expression

by Eastsun :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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 answers
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 Project Euler problems: Click here

Re: Magic of for(if) expression

by Daniel Sobral :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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@...> 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
> answers
> 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:
http://eastsun.javaeye.com/category/34059 Click here
--
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.

Re: Magic of for(if) expression

by Vladimir Kirichenko-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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.

--
Best Regards,
Vladimir Kirichenko



signature.asc (265 bytes) Download Attachment

Re: Magic of for(if) expression

by martin odersky-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



Sent from my iPhone

On Oct 7, 2009, at 14:52, Eastsun <flushtime@...> 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
>> answers
>> 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:
> http://eastsun.javaeye.com/category/34059 Click here
> --
> 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.
>

Re: Magic of for(if) expression

by Eastsun :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks for your reply.

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 <flushtime@126.com> 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
>> answers
>> 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:
> http://eastsun.javaeye.com/category/34059 Click here
> --
> 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.
>
My scala solutions for Project Euler problems: Click here

Re: Magic of for(if) expression

by Eastsun :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

And a filterMap or partialMap as mentioned in http://www.nabble.com/-scala--Scala-List-processing-performance-td10763786.html 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 <flushtime@126.com> 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
>> answers
>> 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:
> http://eastsun.javaeye.com/category/34059 Click here
> --
> 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.
>
My scala solutions for Project Euler problems: Click here

Re: Magic of for(if) expression

by Marcus Downing :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


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

Re: Magic of for(if) expression

by Eastsun :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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 }


And a filterMap or partialMap as mentioned in http://www.nabble.com/-scala--Scala-List-processing-performance-td10763786.html 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 <flushtime@126.com> 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
>> answers
>> 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:
> http://eastsun.javaeye.com/category/34059 Click here
> --
> 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.
>

My scala solutions for Project Euler problems: Click here