Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add generalized tupled functions abstraction #6568

Merged
merged 14 commits into from
May 29, 2019

Conversation

nicolasstucki
Copy link
Contributor

@nicolasstucki nicolasstucki commented May 27, 2019

This introduces the type class

trait TupledFunction[F, G] {
  def tupled(f: F): G
  def untupled(g: G): F
}

which the compiler only instantiates if:

  • F is a function type of arity N
  • G is a function with a single tuple argument of size N and it's types are equal to the arguments of F
  • The return type of F is equal to the return type of G
  • F and G are the same kind of function (both are (...) => R or both are given (...) => R)
  • If only one of F or G is instantiated the second one is inferred

This abstraction allows to abstract over function arities:

  • Adds the ability to write extension methods on functions of any arity
  • It trivially introduces the tupled method on functions of arity larger than 22
  • Under an import, it allows the application of a function directly to a tuple containing all the arguments (auto function tupling).
  • Use andThen and compose directly on functions returning tuples without the need for a call to tupled (auto function tupling).

@nicolasstucki nicolasstucki force-pushed the add-tupled-functions branch from 757477c to c931c1f Compare May 27, 2019 07:53
Copy link
Contributor

@julienrf julienrf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. However, I would say that we miss an example of a problem that is solved by this feature. None of the tests actually abstract over the arity of the functions.

library/src-3.x/scala/TupledFunction.scala Outdated Show resolved Hide resolved
library/src-3.x/dotty/DottyPredef.scala Outdated Show resolved Hide resolved
tests/run/tupled-function-andThen.scala Outdated Show resolved Hide resolved
@nicolasstucki nicolasstucki force-pushed the add-tupled-functions branch from c931c1f to 15aa152 Compare May 27, 2019 09:00
@nicolasstucki nicolasstucki force-pushed the add-tupled-functions branch from 15aa152 to 24a1d00 Compare May 27, 2019 09:09
@nicolasstucki
Copy link
Contributor Author

The first motivation of this is resumed in part in https://github.com/lampepfl/dotty/blob/24a1d00e0dc0aad01711119ac5b46cf9a85b8a66/tests/run/tupled-function-extension-method.scala which captures the essence of the limitation we have in https://github.com/lampepfl/dotty/blob/master/library/src-3.x/scala/quoted/Expr.scala. There we need to implement the extension method for each of the 22 functions and we cannot scale up to any arbitrary function arity.

Also added support for tupled implicit functions
```
TupledFunction[given (Int, Int) => Int, given ((Int, Int)) => Int]
```
All these operations can and probably should be implemented in a library.
@nicolasstucki nicolasstucki force-pushed the add-tupled-functions branch from 664790c to f6eb444 Compare May 28, 2019 08:03
@nicolasstucki nicolasstucki force-pushed the add-tupled-functions branch from aaafde6 to 3c2005d Compare May 28, 2019 09:01
@nicolasstucki nicolasstucki marked this pull request as ready for review May 28, 2019 10:02
@nicolasstucki nicolasstucki requested a review from milessabin May 28, 2019 10:03
Copy link
Contributor

@milessabin milessabin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM :-)

I think we most likely also want something that goes in the opposite direction (tupled to untupled).

@nicolasstucki
Copy link
Contributor Author

Yes. I already started looking into it :)

@nicolasstucki
Copy link
Contributor Author

nicolasstucki commented May 28, 2019

I think I should add the untupling before merging.

Also improve type inference of TupledFunction[F, G] when F is not yet inferred
@nicolasstucki nicolasstucki force-pushed the add-tupled-functions branch from e40963c to 9f02e64 Compare May 28, 2019 14:32
@nicolasstucki
Copy link
Contributor Author

@milessabin I added untuple and improved type inference in the last two commits

To have the same naming convention as scala.Function.{tupled|untupled}
@nicolasstucki nicolasstucki merged commit 0dc2172 into scala:master May 29, 2019
@nicolasstucki nicolasstucki deleted the add-tupled-functions branch May 29, 2019 14:35
@biboudis biboudis added this to the 0.16 Tech Preview milestone Jun 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants