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

(fwd) Re: new motivation for applyIfDefined

6 replies
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.

Since I started us off on our frequent cc-to-the-bouncing-address jaunt
I'll try to nip it in the bud by forwarding this before replying.

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: new motivation for applyIfDefined

On Wed, Jan 26, 2011 at 08:21:42PM +0100, martin odersky wrote:
> Hi Paul, yes, it's a good argument. But the spec also says that guards
> are supposed to be side-effect free, and that the compiler is free to
> apply optimizations assuming that. So we have striictly speaking an
> invalid test and not a compiler failure.

Right, strictly speaking. And it's safe to say that few want to speak
quite this strictly.

But that sword cuts both ways: we could memoize the guards. That would
lead to even more surprising (but still strictly speaking correct)
behavior for something like this because you might have memoized the
result of a "does this directory exist" test a week ago. But it would
prevent this problem!

> That said, I also think it would be much better to go the
> applyIfDefined route. I'd have to page the mailoing list discussion
> back into my memory to get a feeling what the tendency was then. I
> remember there was no lack of proposals!

Rex did a bunch of performance tests and one of the more obscure options
came out looking real good. I believe I am summarizing it correctly: an
index of Int => Case is created, and end up with something like:

def whereDefinedAt(x: T): Int = guards indexWhere (gd => gd(x))
def applyAtIndex(x: T, idx: Int) = cases(idx)(x)
def applyIfDefined(x: T) = {
val idx = whereDefinedAt(x)
if (idx < 0) None else Some(applyAtIndex(x, idx))
}

// compat
def isDefinedAt(x: T) = whereDefinedAt(x) >= 0
def apply(x: T) = cases(whereDefinedAt(x))(x)

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: Re: new motivation for applyIfDefined


On Fri, Jan 28, 2011 at 2:32 PM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:


On Fri, Jan 28, 2011 at 2:17 PM, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
Yes, but you're pushing the issue onto users of partial functions.  I'm not sure that's intuitive, and we'd still get back to the same issue for those who do not define missing case (say, an anonymous partial function).

Not at all. The collect method needs to take as argument a
 
I should have written "needs to take as formal parameter".

subclass of Function1 which defines missingCase. The user just writes a closure, as always.

Cheers

 -- Martin

Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
Re: Re: new motivation for applyIfDefined
Yes... I see how you can extend any function class using a closure.
However, what type should the function be?
Currently collect takes a map A => B where the collection has an element of type A.
To utilize the hook correctly, collect would create it's own subclass of function that deifnes missingCase with.... what?
It seems the function would have to be A => Option[B], or collect would have missingCase throw a stored exception (for speed reasons) and continue on...
I'm not sure either of this solutions is a huge win.  However I do *love* the idea of closures being able to automatically create anonymous subclasses of any single-abstract-method class.  Having this just apply to subclass of function still seems a huge win, but I don't see a large gain in the problem we're looking at.

On Fri, Jan 28, 2011 at 8:33 AM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:


On Fri, Jan 28, 2011 at 2:32 PM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:


On Fri, Jan 28, 2011 at 2:17 PM, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
Yes, but you're pushing the issue onto users of partial functions.  I'm not sure that's intuitive, and we'd still get back to the same issue for those who do not define missing case (say, an anonymous partial function).

Not at all. The collect method needs to take as argument a
 
I should have written "needs to take as formal parameter".

subclass of Function1 which defines missingCase. The user just writes a closure, as always.

Cheers

 -- Martin


odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: Re: new motivation for applyIfDefined


On Fri, Jan 28, 2011 at 2:47 PM, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
Yes... I see how you can extend any function class using a closure.
However, what type should the function be?
Currently collect takes a map A => B where the collection has an element of type A.
To utilize the hook correctly, collect would create it's own subclass of function that deifnes missingCase with.... what?
It seems the function would have to be A => Option[B], or collect would have missingCase throw a stored exception (for speed reasons) and continue on...

Yes, stored exception seems to be our only choice if we want to keep the same interface. If collect takes a map A => Option[B],
the whole issue is moot of course, then collect is just an alias for flatMap.

 -- Martin

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Re: new motivation for applyIfDefined

On Fri, Jan 28, 2011 at 03:00:25PM +0100, martin odersky wrote:
> Yes, stored exception seems to be our only choice if we want to keep
> the same interface. If collect takes a map A => Option[B], the whole
> issue is moot of course, then collect is just an alias for flatMap.

It occurs to me we could synthesize an override for lift which amounted
to applyIfDefined. Then collect can take the same argument and call
lift in the implementation.

Couldn't sleep thinking about all these fascinating problems though, so
I'm not advocating anything with the above as I don't know if it's
crazier than usual. I DO know that I too am keen on this idea that one
could implement any SAM-style interface with case syntax.

Also, since the names aren't set: if we end up with a special
"missingCase" type method and also end up with a "missingMethod" method
(which is not called that) in the Dynamic trait, then timingwise we have
lucked into a chance to find consistent naming. I know they're not in
the same category but they have relevant similarities.

Ismael Juma 2
Joined: 2011-01-22,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: new motivation for applyIfDefined

On Fri, Jan 28, 2011 at 2:56 PM, Paul Phillips wrote:
> I DO know that I too am keen on this idea that one
> could implement any SAM-style interface with case syntax.

Yes, this could be very cool.

Best,
Ismael

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