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

Improvements for FunctionN

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

[None of this is checked in yet.]

Yesterday I implemented AbstractionFunction0-22, motivated by this
discussion:

http://old.nabble.com/-scala---half-a-kb-of-bytecode-overhead-per-anonym...

This knocked up to 10% off the size of the library and compiler jars. I
say up to because it seems to depend quite a bit on choice of names, and
I'm still tweaking it. (I also took a side trip where I specialized
Function1, but that's a story for another day.) I think we should
consider re-evaluating the mangling scheme with an eye toward generating
the shortest names we can. Some of these strings are duplicated in
thousands of places.

More interesting to me than the substantial bytecode savings is that
this should mean we can put methods on Function1 and friends without the
current penalty of seeing those methods duplicated thousands of times.
Which brings me to this thread:

http://old.nabble.com/-scala--tupled-untupled-%28and-curried-curry%29-td...

I think all the static methods in Function for tupling and currying
ought to be deprecated, and they should only be defined on the FunctionN
objects. Now that we have type constraints even the untupling ones
should be fully specifiable, although I haven't tried it yet. What do
you think?

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

And I forgot to ask about naming: on the one hand they could go into
scala.runtime.*, but that sends a message they're not for general use.
Which, granted, might be the right message to send at this stage. If I
put them in runtime maybe they should be called AnonFun0-22 or something
along those lines.

Tony Morris 2
Joined: 2009-03-20,
User offline. Last seen 42 years 45 weeks ago.
Re: Improvements for FunctionN

Paul, you're a legend. You have my support. For high-level programming,
these functions are desperately needed.

I recommend the following functions as well as
curry/uncurry/tupled/untupled:

* For Function1[T, R]
def on[C](f: (R, R) => C): (t1: T, t2: T) => C
This function can also go on other Function-arities.

* For Function1[T, R]
def flatMap[C](f: R => Function1[T, C]): Function1[T, C]

* For Function1[T, R]
def map[C](f: R => C): Function1[T, C]
An alias for compose/andThen

* For Function1[T, R]
def s[C](f: Function1[T, R => C]): Function1[T, C]
The S combinator, choose your name (s, <*>, ap come to mind).

* For Function2[T1, T2, R]
def flip: Function2[T2, T1, R]

Let me know if I can help.

Paul Phillips wrote:
> [None of this is checked in yet.]
>
> Yesterday I implemented AbstractionFunction0-22, motivated by this
> discussion:
>
> http://old.nabble.com/-scala---half-a-kb-of-bytecode-overhead-per-anonym...
>
> This knocked up to 10% off the size of the library and compiler jars. I
> say up to because it seems to depend quite a bit on choice of names, and
> I'm still tweaking it. (I also took a side trip where I specialized
> Function1, but that's a story for another day.) I think we should
> consider re-evaluating the mangling scheme with an eye toward generating
> the shortest names we can. Some of these strings are duplicated in
> thousands of places.
>
> More interesting to me than the substantial bytecode savings is that
> this should mean we can put methods on Function1 and friends without the
> current penalty of seeing those methods duplicated thousands of times.
> Which brings me to this thread:
>
> http://old.nabble.com/-scala--tupled-untupled-%28and-curried-curry%29-td...
>
> I think all the static methods in Function for tupling and currying
> ought to be deprecated, and they should only be defined on the FunctionN
> objects. Now that we have type constraints even the untupling ones
> should be fully specifiable, although I haven't tried it yet. What do
> you think?
>
>

Tony Morris 2
Joined: 2009-03-20,
User offline. Last seen 42 years 45 weeks ago.
Re: Improvements for FunctionN

Two more if I may:

* For Function2[T, T, R]
def flatten: Function1[T, R]
Is it possible to play with <:< so this can be added this to
scala.Function2?

* For List[Function1[T, R]]
def sequence: Function1[T, List[R]]
Again use <:< to add to scala.List

Tony Morris wrote:
> Paul, you're a legend. You have my support. For high-level programming,
> these functions are desperately needed.
>
> I recommend the following functions as well as
> curry/uncurry/tupled/untupled:
>
> * For Function1[T, R]
> def on[C](f: (R, R) => C): (t1: T, t2: T) => C
> This function can also go on other Function-arities.
>
> * For Function1[T, R]
> def flatMap[C](f: R => Function1[T, C]): Function1[T, C]
>
> * For Function1[T, R]
> def map[C](f: R => C): Function1[T, C]
> An alias for compose/andThen
>
> * For Function1[T, R]
> def s[C](f: Function1[T, R => C]): Function1[T, C]
> The S combinator, choose your name (s, <*>, ap come to mind).
>
> * For Function2[T1, T2, R]
> def flip: Function2[T2, T1, R]
>
> Let me know if I can help.
>
>
> Paul Phillips wrote:
>
>> [None of this is checked in yet.]
>>
>> Yesterday I implemented AbstractionFunction0-22, motivated by this
>> discussion:
>>
>> http://old.nabble.com/-scala---half-a-kb-of-bytecode-overhead-per-anonym...
>>
>> This knocked up to 10% off the size of the library and compiler jars. I
>> say up to because it seems to depend quite a bit on choice of names, and
>> I'm still tweaking it. (I also took a side trip where I specialized
>> Function1, but that's a story for another day.) I think we should
>> consider re-evaluating the mangling scheme with an eye toward generating
>> the shortest names we can. Some of these strings are duplicated in
>> thousands of places.
>>
>> More interesting to me than the substantial bytecode savings is that
>> this should mean we can put methods on Function1 and friends without the
>> current penalty of seeing those methods duplicated thousands of times.
>> Which brings me to this thread:
>>
>> http://old.nabble.com/-scala--tupled-untupled-%28and-curried-curry%29-td...
>>
>> I think all the static methods in Function for tupling and currying
>> ought to be deprecated, and they should only be defined on the FunctionN
>> objects. Now that we have type constraints even the untupling ones
>> should be fully specifiable, although I haven't tried it yet. What do
>> you think?
>>
>>
>>
>
>

Mark Harrah
Joined: 2008-12-18,
User offline. Last seen 35 weeks 3 days ago.
Re: Improvements for FunctionN

On Saturday 28 November 2009, Paul Phillips wrote:
> [None of this is checked in yet.]
>
> Yesterday I implemented AbstractionFunction0-22, motivated by this
> discussion:
>
> http://old.nabble.com/-scala---half-a-kb-of-bytecode-overhead-per-anonymous
> -function-td20826275.html
>
> This knocked up to 10% off the size of the library and compiler jars. I
> say up to because it seems to depend quite a bit on choice of names, and
> I'm still tweaking it. (I also took a side trip where I specialized
> Function1, but that's a story for another day.) I think we should
> consider re-evaluating the mangling scheme with an eye toward generating
> the shortest names we can. Some of these strings are duplicated in
> thousands of places.
>
> More interesting to me than the substantial bytecode savings is that
> this should mean we can put methods on Function1 and friends without the
> current penalty of seeing those methods duplicated thousands of times.
> Which brings me to this thread:
>
> http://old.nabble.com/-scala--tupled-untupled-%28and-curried-curry%29-td249
> 43141.html
>
> I think all the static methods in Function for tupling and currying
> ought to be deprecated, and they should only be defined on the FunctionN
> objects. Now that we have type constraints even the untupling ones
> should be fully specifiable, although I haven't tried it yet. What do
> you think?

A size reduction often means a related improvement in startup time for me, so
I'm definitely in favor of the AbstractFunctionN classes. I'm also in favor of
moving the methods on the FunctionN objects.

-Mark

Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: Improvements for FunctionN
Unfortunately map/flatMap (under those names) aren't a great idea, because Map extends Function but also inherits those methods from Iterable.

--j

On Sat, Nov 28, 2009 at 12:51 PM, Tony Morris <tonymorris [at] gmail [dot] com> wrote:
Paul, you're a legend. You have my support. For high-level programming,
these functions are desperately needed.

I recommend the following functions as well as
curry/uncurry/tupled/untupled:

* For Function1[T, R]
   def on[C](f: (R, R) => C): (t1: T, t2: T) => C
   This function can also go on other Function-arities.

* For Function1[T, R]
   def flatMap[C](f: R => Function1[T, C]): Function1[T, C]

* For Function1[T, R]
   def map[C](f: R => C): Function1[T, C]
   An alias for compose/andThen

* For Function1[T, R]
   def s[C](f: Function1[T, R => C]): Function1[T, C]
   The S combinator, choose your name (s, <*>, ap come to mind).

* For Function2[T1, T2, R]
   def flip: Function2[T2, T1, R]

Let me know if I can help.


Paul Phillips wrote:
> [None of this is checked in yet.]
>
> Yesterday I implemented AbstractionFunction0-22, motivated by this
> discussion:
>
> http://old.nabble.com/-scala---half-a-kb-of-bytecode-overhead-per-anonymous-function-td20826275.html
>
> This knocked up to 10% off the size of the library and compiler jars.  I
> say up to because it seems to depend quite a bit on choice of names, and
> I'm still tweaking it.  (I also took a side trip where I specialized
> Function1, but that's a story for another day.) I think we should
> consider re-evaluating the mangling scheme with an eye toward generating
> the shortest names we can.  Some of these strings are duplicated in
> thousands of places.
>
> More interesting to me than the substantial bytecode savings is that
> this should mean we can put methods on Function1 and friends without the
> current penalty of seeing those methods duplicated thousands of times.
> Which brings me to this thread:
>
> http://old.nabble.com/-scala--tupled-untupled-%28and-curried-curry%29-td24943141.html
>
> I think all the static methods in Function for tupling and currying
> ought to be deprecated, and they should only be defined on the FunctionN
> objects.  Now that we have type constraints even the untupling ones
> should be fully specifiable, although I haven't tried it yet.  What do
> you think?
>
>

--
Tony Morris
http://tmorris.net/



Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: Improvements for FunctionN
Also, Seq inherits from Function as well :(

--j

On Sun, Nov 29, 2009 at 11:34 AM, Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com> wrote:
Unfortunately map/flatMap (under those names) aren't a great idea, because Map extends Function but also inherits those methods from Iterable.

--j

On Sat, Nov 28, 2009 at 12:51 PM, Tony Morris <tonymorris [at] gmail [dot] com> wrote:
Paul, you're a legend. You have my support. For high-level programming,
these functions are desperately needed.

I recommend the following functions as well as
curry/uncurry/tupled/untupled:

* For Function1[T, R]
   def on[C](f: (R, R) => C): (t1: T, t2: T) => C
   This function can also go on other Function-arities.

* For Function1[T, R]
   def flatMap[C](f: R => Function1[T, C]): Function1[T, C]

* For Function1[T, R]
   def map[C](f: R => C): Function1[T, C]
   An alias for compose/andThen

* For Function1[T, R]
   def s[C](f: Function1[T, R => C]): Function1[T, C]
   The S combinator, choose your name (s, <*>, ap come to mind).

* For Function2[T1, T2, R]
   def flip: Function2[T2, T1, R]

Let me know if I can help.


Paul Phillips wrote:
> [None of this is checked in yet.]
>
> Yesterday I implemented AbstractionFunction0-22, motivated by this
> discussion:
>
> http://old.nabble.com/-scala---half-a-kb-of-bytecode-overhead-per-anonymous-function-td20826275.html
>
> This knocked up to 10% off the size of the library and compiler jars.  I
> say up to because it seems to depend quite a bit on choice of names, and
> I'm still tweaking it.  (I also took a side trip where I specialized
> Function1, but that's a story for another day.) I think we should
> consider re-evaluating the mangling scheme with an eye toward generating
> the shortest names we can.  Some of these strings are duplicated in
> thousands of places.
>
> More interesting to me than the substantial bytecode savings is that
> this should mean we can put methods on Function1 and friends without the
> current penalty of seeing those methods duplicated thousands of times.
> Which brings me to this thread:
>
> http://old.nabble.com/-scala--tupled-untupled-%28and-curried-curry%29-td24943141.html
>
> I think all the static methods in Function for tupling and currying
> ought to be deprecated, and they should only be defined on the FunctionN
> objects.  Now that we have type constraints even the untupling ones
> should be fully specifiable, although I haven't tried it yet.  What do
> you think?
>
>

--
Tony Morris
http://tmorris.net/




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

On Sun, Nov 29, 2009 at 8:37 PM, Jorge Ortiz wrote:
> Also, Seq inherits from Function as well :(
>
Right. We have to tread carefully here. I also think the methods in
the Function can probably go into FunctionN. Not sure about adding
more stuff because of interactions with things inheriting from
Functon, which are quite a few.

Cheers

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

On Sun, Nov 29, 2009 at 09:42:46PM +0100, martin odersky wrote:
> Right. We have to tread carefully here. I also think the methods in
> the Function can probably go into FunctionN. Not sure about adding
> more stuff because of interactions with things inheriting from
> Functon, which are quite a few.

OK, I inferred from this and another email that it was cool if I went
ahead with putting those methods on FunctionN and proceeding with
AbstractFunction. Which I have done. You are right, there is no way we
can add map and flatMap to Function1, non-starter. They could be added
via an implicit.

There is a wrinkle with the currytupleland. The curry and tuple methods
can exist on FunctionN, but uncurry and untuple do not achieve the
necessary type inference. Tony suggested it's because of Function's
contravariance, and although I haven't confirmed it, I think that is it.

So the options for uncurry and untuple are:

* leave them on the Function object
* fake them via implicit conversion (not sure that will work either)
* martin revisits contravariance and whips up some magic

I threw that last one in there because I'd still enjoy waking up one day
and finding we can make Ordering contravariant, and I think these issues
are in the same issuesphere.

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

On Wed, Dec 2, 2009 at 11:51 PM, Paul Phillips wrote:
> On Sun, Nov 29, 2009 at 09:42:46PM +0100, martin odersky wrote:
>> Right. We have to tread carefully here. I also think the methods in
>> the Function can probably go into FunctionN. Not sure about adding
>> more stuff because of interactions with things inheriting from
>> Functon, which are quite a few.
>
> OK, I inferred from this and another email that it was cool if I went
> ahead with putting those methods on FunctionN and proceeding with
> AbstractFunction.  Which I have done.  You are right, there is no way we
> can add map and flatMap to Function1, non-starter.  They could be added
> via an implicit.
>
> There is a wrinkle with the currytupleland.  The curry and tuple methods
> can exist on FunctionN, but uncurry and untuple do not achieve the
> necessary type inference.  Tony suggested it's because of Function's
> contravariance, and although I haven't confirmed it, I think that is it.
>
> So the options for uncurry and untuple are:
>
>  * leave them on the Function object
>  * fake them via implicit conversion (not sure that will work either)
>  * martin revisits contravariance and whips up some magic
>
> I threw that last one in there because I'd still enjoy waking up one day
> and finding we can make Ordering contravariant, and I think these issues
> are in the same issuesphere.
>
Yes, they look like that. That's strictly Scala 3 territory though.
The implicit conversions might work better; this needs to be tried
out. Leave everything in the function object is also OK. Maybe that's
the best stratgey for now. Another aspect is that I'd also like to
unify tupled and n-ary functions (maybe for Scala 2.9? looks like a
roadmap here!). This means that the tupled conversions become
identities. As to curry/uncurry conversions, I have the impression
that currying is used very little in Scala-land, so the conversions
are not heavily used.

Cheers

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