Try/auto tupling #51

Closed
wants to merge 2 commits into
from

Conversation

Projects
None yet
3 participants
Contributor

odersky commented Mar 8, 2014

Tests are represented by the dotty codebase itself, where previously modified occurrences of auto-tupling are re-instantiated.

odersky added some commits Mar 7, 2014

@odersky odersky Added auto-tupling.
Auto-tupling should satisfy the following spec.

1. An application `f(args)` where `f` is a non-overloaded method which has a single, non-repeated parameter as its
first parameter list and where args consists of two or more arguments is expanded to `f((args))`.

2. A constructor pattern `C(args)` where `C.unapply` is a non-overloaded method which has a single, non-repeated parameter as its first parameter list and where args consists of two or more arguments is expanded to `C((args))`.
a18e645
@odersky odersky Removed explicit tuplings from dotc codebase.
Eliminated all "Dotty deviations" which were due to lack of auto-tupling.
a7deafa
Contributor

odersky commented Mar 8, 2014

Review by @adriaanm @sjrd

Contributor

adriaanm commented Mar 8, 2014

I would much rather not have auto-tupling at all. It is to arity checking of method application/pattern matching as dynamic typing is to Scala. This is why ()-parameter-list-insertion is deprecated in 2.11.

Owner

sjrd commented Mar 8, 2014

I don't understand. Wasn't auto-tupling supposed to disappear? Wasn't it judged as being more harmful than not?

Contributor

adriaanm commented Mar 8, 2014

The scala bug regarding starting with deprecating () insertion: https://issues.scala-lang.org/browse/SI-8035

Contributor

odersky commented Mar 8, 2014

Note that compared to Scala 2.11, auto-tupling is more restricted. In particular, the new auto-tupling does not do () insertion. Also, it does not apply if the function in question is overloaded. This avoids problems like accidentally picking an overloaded variant taking an Object parameter when some other variant is intended but the right number of parameters is not passed.

Other advantages: There is a simple spec (given in the first commit).

I would like to complement this with auto-detupling for lambdas. Specifically, if we have a lambda

(x, y) => expr

and the expected type is of the form A => B, then expand the lambda to

{ case (x, y) => expr }

I believe if we do this in addition to restricted auto-tupling we can avoid much of the confusion surrounding tupled vs n-ary functions.

Contributor

adriaanm commented Mar 8, 2014

Ok, I'll mull this over a bit. (Same with other PR.)

Contributor

adriaanm commented Mar 10, 2014

My initial concerns are:

  • when someone adds an overload, they'll be surprised to learn that they have to (manually) tuple again if they were relying on auto-tupling
  • would they expect the converse to work? supplying one n-tuple to an n-ary method?
  • the experience with similar implementation mechanisms in scalac has been pretty bad (tryTwice comes to mind)
Contributor

adriaanm commented Mar 10, 2014

On a related (brainstorming) note: how about supporting patterns in argument definitions (so the conversion would be opt-in, but more general)?

def takesThree((a, b, c): (Int, String, Boolean)) = ...

becomes:

def takesThree(x: (Int, String, Boolean)) = x match { case (a, b, c) => .... }

Also, would be nice to be able to abstract over Tuple arity using HList.

Contributor

adriaanm commented Mar 10, 2014

This also suggests an alternative interpretation for auto-tupling along the same lines as bridge methods. A method that opts in to auto-tupling, could have a "bridge" method auto-generated that unpacks the n-tuple and forwards to the n-ary overload.

Contributor

odersky commented Mar 12, 2014

Regarding the initial concerns:

when someone adds an overload, they'll be surprised to learn that they have to (manually) tuple > again if they were relying on auto-tupling

Yes, but this is nothing new. Other things stop working as well. E.g. adding an overload means that a closure argument needs explicit parameter types.

would they expect the converse to work? supplying one n-tuple to an n-ary method?

I hope not. The aim of auto-tupling is just to avoid weird looking ((a, b, c)) syntax. Nothing more general is desired.

the experience with similar implementation mechanisms in scalac has been pretty bad (tryTwice comes to mind)

Agreed up to the point that every conversion is risky. But note that the proposed conversion is much better behaved than tryTwice: There's one specific point, and a specific set of conditions where it is applied, and there's no backtracking involved.

Contributor

odersky commented Mar 12, 2014

Pattern in argument definitions could be neat, but require much more thought, I guess.

To come to a conclusion here, I propose to put the conversion or its absence under a language import. The default of that import is whatever Scala 2.x is to make migration easier.

So initially it would be

import language.noAutoBoxing

to change the default. We can easily flip the default later if desired, so that the import would become

import language.autoBoxing

Contributor

adriaanm commented Mar 12, 2014

I'm okay with putting this under a flag, though I'd suggest autoTupling rather than autoBoxing.

Contributor

adriaanm commented Mar 12, 2014

Yes, but this is nothing new.

I know, but that's not a very strong argument for introducing another surprise. I guess I'm dubious about the benefit vs cost ratio on this one.

Contributor

odersky commented Mar 12, 2014

Yes, of course. autoTupling it is.

Contributor

odersky commented Mar 16, 2014

Subsumed by #75

odersky closed this Mar 16, 2014

scabug referenced this pull request in scala/bug Apr 7, 2017

Open

Spec doesn't mention automatic tupling #3583

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment