Question on projections

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

Question on projections

by Derek Chen-Becker-2 :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

I had a light bulb moment with projections this week and I've been
playing around with some sample code. I have a few questions on how it
all works.

1. When the docs say that a projection allows for a non-strict filter,
map, etc, is that essentially saying that the projection is evaluated at
each call vs at creation? Am I glossing over or missing some major
aspect of projections?

2. If my first statement is true, is there any reason you'd ever
purposely use a projection with an immutable structure? I understand
that this might happen if you have a method that, say, takes a base type
(Seq vs ArrayBuffer, etc),  but otherwise it seems like eval at call
would just be redundant if it's a projection on an immutable struct.

Thanks!

Derek

Re: Question on projections

by Jamie Webb-2 :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

On 2008-01-05 07:59:53 Derek Chen-Becker wrote:
> I had a light bulb moment with projections this week and I've been
> playing around with some sample code. I have a few questions on how it
> all works.
>
> 1. When the docs say that a projection allows for a non-strict filter,
> map, etc, is that essentially saying that the projection is evaluated
> at each call vs at creation? Am I glossing over or missing some major
> aspect of projections?

Yes, if I understand you correctly. Consider:

  // A sequence of 100 numbers, with instrumentation
  val xs = new Iterable[Int] {
      def elements = new Iterator[Int] {
          var x = 0
          def hasNext = x < 100
          def next = {
              x += 1
              println("Returning "+x)
              x
          }
      }
  }

Two versions of code to get the first 5 even numbers:

  // This evaluates the entire sequence
  xs.filter(_ % 2 == 0).take(5)

  // This evaluates only what's needed
  xs.projection.filter(_ % 2 == 0).take(5)

> 2. If my first statement is true, is there any reason you'd ever
> purposely use a projection with an immutable structure? I understand
> that this might happen if you have a method that, say, takes a base
> type (Seq vs ArrayBuffer, etc),  but otherwise it seems like eval at
> call would just be redundant if it's a projection on an immutable
> struct.

I'd advise against using projections with mutable structures. The
resulting side-effect coupling is rather error-prone.

IMO, projections are best used is simply to change the space/time
behaviour of a data structure. This is the FP thing again of course,
but aliasing mutable structures is not a great idea.

/J

Re: Question on projections

by Derek Chen-Becker-2 :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

Jamie Webb wrote:
> Two versions of code to get the first 5 even numbers:
>
>   // This evaluates the entire sequence
>   xs.filter(_ % 2 == 0).take(5)
>
>   // This evaluates only what's needed
>   xs.projection.filter(_ % 2 == 0).take(5)

OK, that right there is exactly the example I needed. I hadn't though of
it in terms of lazy evaluation. Is lazy the appropriate term?

> I'd advise against using projections with mutable structures. The
> resulting side-effect coupling is rather error-prone.

OK, since I hadn't thought of the example you gave, the only thing I was
thinking was that you might want to use it with mutable structures
specifically for the side-effect coupling. I think I understand them a
little better now.

Thanks!

Derek


Parent Message unknown Re: Question on projections

by Jamie Webb-2 :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

On 2008-01-05 08:55:15 Derek Chen-Becker wrote:

> Jamie Webb wrote:
> > Two versions of code to get the first 5 even numbers:
> >
> >   // This evaluates the entire sequence
> >   xs.filter(_ % 2 == 0).take(5)
> >
> >   // This evaluates only what's needed
> >   xs.projection.filter(_ % 2 == 0).take(5)
>
> OK, that right there is exactly the example I needed. I hadn't though
> of it in terms of lazy evaluation. Is lazy the appropriate term?

Laziness tends to imply some sort of memoisation. E.g.

  // f will be evaluated once, no matter how many times x is read:
  lazy val x = f()

By contrast, the filter above will be re-executed every time the result
is iterated, so it's really just a... projection.

/J