This page is no longer maintained — Please continue to the home page at www.scala-lang.org

projection + map + find is cheating...

5 replies
John Nilsson
Joined: 2008-12-20,
User offline. Last seen 42 years 45 weeks ago.
Hi,

The following code prints

1
2
3

I expected

1
2

Is this a bug?


  case class F(i:Int) extends (()=> Int)
  {
    override def apply() = {
      println(i)
      i
    }
  }
 
  def main(args: Array[String]) = {
    val l = F(1) :: F(2) :: F(3) :: F(4) :: Nil
    val m = l.projection.map(_().toString).find(_ == "2")
    ()
  }

BR,
John
David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: projection + map + find is cheating...
It seems that the stream is evaluating the element beyond the one found.  Try seeding with List(F(1), F(2), F(3), F(4), F(5), F(6)).

On Sat, Jan 3, 2009 at 8:55 PM, John Nilsson <john [at] milsson [dot] nu> wrote:
Hi,

The following code prints

1
2
3

I expected

1
2

Is this a bug?


  case class F(i:Int) extends (()=> Int)
  {
    override def apply() = {
      println(i)
      i
    }
  }
 
  def main(args: Array[String]) = {
    val l = F(1) :: F(2) :: F(3) :: F(4) :: Nil
    val m = l.projection.map(_().toString).find(_ == "2")
    ()
  }

BR,
John



--
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
Florian Hars
Joined: 2008-12-18,
User offline. Last seen 42 years 45 weeks ago.
Re: projection + map + find is cheating...

John Nilsson schrieb:
> val m = l.projection.map(_().toString).find(_ == "2")

My goolge-fu is failing me right now, but I seem to recall a similar
discussion where the answer was that several non-strict constructs in
scala always evaluate the element after the current, so they know
whether they have a next element or not.
Anyway, the semantics of projections in the presence of side effects
(like your println) is underspecified:
http://lampsvn.epfl.ch/trac/scala/ticket/1081

I also found this, which is interesting, too, but for a slightly
different problem:
http://www.nabble.com/Re%3A-Re%3A-Two-questions-about-"yield"-p17298441.html

- Florian.

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: projection + map + find is cheating...

On Sun, Jan 4, 2009 at 5:55 AM, John Nilsson wrote:
> Hi,
>
> The following code prints
>
> 1
> 2
> 3
>
> I expected
>
> 1
> 2
>
> Is this a bug?
>
>
It's currently the expected behavior: the projection of a List is
defined to be a Stream, and Streams always evaluate their head
elements. This is likely to change in 2.8.0, though (I mean, that
List's projection is a Stream).

Cheers

John Nilsson
Joined: 2008-12-20,
User offline. Last seen 42 years 45 weeks ago.
Re: projection + map + find is cheating...
On Sun, Jan 4, 2009 at 1:16 PM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:
It's currently the expected behavior: the projection of a List is
defined to be a Stream, and Streams always evaluate their head
elements. This is likely to change in 2.8.0, though (I mean, that
List's projection is a Stream).

Ah ok. Great to hear. Was hoping to avoid some costly calculations by using projection...

BR,
John
dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: projection + map + find is cheating...

Just to be clear, the problem is that find evaluates the next element, not
with the projection itself.

If you used "val m = l.projection.map(_().toString).tail.head" instead, the
result would be the one you expected.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland