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

Re: Re: fun with function specialization

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

On Tue, Dec 13, 2011 at 9:13 AM, Paul Phillips wrote:
> Oh, you mean at all? It's because (as far as I know) otherwise you
> couldn't pass anything but T => Unit methods to foreach.

...that said, now that I think about performance a lot, I think we
should absolutely find some other way to deal with it, because it's
just way harder to make things fast when they are polymorphic. The
meaningful user-level benefit of polymorphism here is zero. People
just want to be able to pass Function1s to foreach, they have no
interest in a type parameter.

Iulian Dragos
Joined: 2008-12-18,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: fun with function specialization


On Tue, Dec 13, 2011 at 6:23 PM, Paul Phillips <paulp [at] improving [dot] org> wrote:
On Tue, Dec 13, 2011 at 9:13 AM, Paul Phillips <paulp [at] improving [dot] org> wrote:
> Oh, you mean at all? It's because (as far as I know) otherwise you
> couldn't pass anything but T => Unit methods to foreach.

...that said, now that I think about performance a lot, I think we
should absolutely find some other way to deal with it, because it's
just way harder to make things fast when they are polymorphic.  The
meaningful user-level benefit of polymorphism here is zero.  People
just want to be able to pass Function1s to foreach, they have no
interest in a type parameter.

Absolutely.


--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Re: fun with function specialization

Oh, the other thing is that I just made up that explanation as to why
foreach has a type parameter. I have it handy because at some time in
the distant past I had the same question and that was the only thing I
could come up with. So it is possible there is some reason I don't
know. But I think it's more likely chosen based on having somewhat
higher theoretical purity, and the practical consequences were largely
unforeseen.

I don't see any reason either of these wouldn't work. Seamless
transition would probably be tricky.

def foreach1(f: T => _): Unit
def foreach2(f: T => Any): Unit

The second is much preferred because the compiler would work hard to
figure out those existentials, and all for naught.

d_m
Joined: 2010-11-11,
User offline. Last seen 35 weeks 2 days ago.
Re: Re: fun with function specialization

On Tue, Dec 13, 2011 at 11:35:36AM -0800, Paul Phillips wrote:
> I don't see any reason either of these wouldn't work. Seamless
> transition would probably be tricky.
>
> def foreach1(f: T => _): Unit
> def foreach2(f: T => Any): Unit
>
> The second is much preferred because the compiler would work hard to
> figure out those existentials, and all for naught.

I think the second version might make specializing NumericRange a bit
more feasible too. At least, that U type parameter was giving me a lot
of trouble the last time I looked at it.

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Re: fun with function specialization

On Tue, Dec 13, 2011 at 11:46 AM, Erik Osheim wrote:
> I think the second version might make specializing NumericRange a bit
> more feasible too. At least, that U type parameter was giving me a lot
> of trouble the last time I looked at it.

Second version is implemented here:

https://github.com/paulp/scala/tree/monomorphic-foreach

I encountered no obstacles, so at present I know of no reason not to
ship it except the usual backward compatibility nightmare.

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: Re: fun with function specialization

On Thu, Dec 15, 2011 at 7:22 AM, Paul Phillips wrote:
> On Tue, Dec 13, 2011 at 11:46 AM, Erik Osheim wrote:
>> I think the second version might make specializing NumericRange a bit
>> more feasible too. At least, that U type parameter was giving me a lot
>> of trouble the last time I looked at it.
>
> Second version is implemented here:
>
>  https://github.com/paulp/scala/tree/monomorphic-foreach
>
> I encountered no obstacles, so at present I know of no reason not to
> ship it except the usual backward compatibility nightmare.

Doesn't the second version cause a boxing of the function result?
Agreed it's just a singleton object, but still...

I do not think we have sufficient data or reason yet to change the
signatures of the collections library. Any change is a nightmare for
backwards compatibility. And, like I said earlier, the whole thing
will be rethought anyway with macros, so in that sense everything done
now is premature optimization.

Cheers

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Re: fun with function specialization

On Thu, Dec 15, 2011 at 12:03 AM, martin odersky wrote:
> Doesn't the second version cause a boxing of the function result?
> Agreed it's just a singleton object, but still...

So does the generic version except for those foreaches which
specialize the type parameter on Unit (only Range as far as I know)
since the U erases to Object. We could make the argument to foreach T
=> Unit for that matter, we'd just have to overcome this:

scala> def f(g: Int => Unit): Unit = ()
f: (g: Int => Unit)Unit

scala> f((x: Int) => x + 1)

scala> val g: Int => Int = _ + 1
g: Int => Int =

scala> f(g)
:10: error: type mismatch;
found : Int => Int
required: Int => Unit
f(g)
^

> I do not think we have sufficient data or reason yet to change the
> signatures of the collections library. Any change is a nightmare for
> backwards compatibility. And, like I said earlier, the whole thing
> will be rethought anyway with macros, so in that sense everything done
> now is premature optimization.

That's fine, but can we establish if there is some upside being
overlooked to giving foreach a type parameter? If we were rolling out
foreach today, is there some reason we'd consider it?

I'm not sure macros are going to help with foreach, if the problem is
what and how hotspot chooses to optimize. I realize they can help
with Range, but it's the "everywhere" case we'd be potentially helping
with a non-generic foreach.

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: Re: fun with function specialization

On Thu, Dec 15, 2011 at 5:50 PM, Paul Phillips wrote:
> On Thu, Dec 15, 2011 at 12:03 AM, martin odersky wrote:
>> Doesn't the second version cause a boxing of the function result?
>> Agreed it's just a singleton object, but still...
>
> So does the generic version except for those foreaches which
> specialize the type parameter on Unit (only Range as far as I know)
> since the U erases to Object.  We could make the argument to foreach T
> => Unit for that matter, we'd just have to overcome this:
>
> scala> def f(g: Int => Unit): Unit = ()
> f: (g: Int => Unit)Unit
>
> scala> f((x: Int) => x + 1)
>
> scala> val g: Int => Int = _ + 1
> g: Int => Int =
>
> scala> f(g)
> :10: error: type mismatch;
>  found   : Int => Int
>  required: Int => Unit
>              f(g)
>                ^
>
>> I do not think we have sufficient data or reason yet to change the
>> signatures of the collections library. Any change is a nightmare for
>> backwards compatibility. And, like I said earlier, the whole thing
>> will be rethought anyway with macros, so in that sense everything done
>> now is premature optimization.
>
> That's fine, but can we establish if there is some upside being
> overlooked to giving foreach a type parameter? If we were rolling out
> foreach today, is there some reason we'd consider it?
>
The only reason I see is that the type param can be specialized
whereas Any will always return an object. But that's a minor detail.
So, no, no strong reason.

> I'm not sure macros are going to help with foreach, if the problem is
> what and how hotspot chooses to optimize.  I realize they can help
> with Range, but it's the "everywhere" case we'd be potentially helping
> with a non-generic foreach.

I have not yet understood how non-generic foreach would help. Can you explain?

Thanks

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