Dotty: Revert syntax for context closures

Created on 25 Nov 2020  路  10Comments  路  Source: lampepfl/dotty

We were going back and forth between

x ?=> e
(x: T) ?=> e

and

(using x) => e
(using x: T) => e

The using syntax looks initially more familiar, that's why we chose it over ?=>. But it had a fatal flaw (I should have seen that one earlier):

In all other contexts, (using X) means an implicit parameter of _type_ X. But in closures, it means an implicit parameter with name X and an inferred type. I believe that having two fundamentally different interpretations of the same syntax based on context is unacceptable. So I propose to switch back to the ?=> syntax.

Most helpful comment

Isn't this exactly the same with normal lambdas and function types?

  type   T = X => Body  // X and Body are types
  val f: T = x => body  // x and body are terms

  type   T = (using X) => Body  // X and Body are types
  val f: T = (using x) => body  // x and body are terms

  f(t)       // t is a term
  f(using t) // t is a term

  // And when both parameter names and types are provided, the two ways align:

  type   T = (x: X) => Body
  val f: T = (x: X) => body

  type   T = (using x: X) => Body
  val f: T = (using x: X) => body

This seems perfectly cromulent to me :^)

All 10 comments

Actually if we invoke a method with an implicit parameter like this

f(using X)

X is also the name of the parameter, not of the type. Does this mean this syntax also needs to be changed?

why can't (using X) => e where X is a type be a thing?

@prolativ No. Using argument clauses take expressions, I think that's fine.
@bishabosha Because we do want to allow the equivalent of (x) ?=> e, so it would be ambiguous.

I agree that it's probably going to confuse people that in one form of argument list using is followed by a type and in another it has to be followed by a parameter name.

However, looking at the examples in the PR, I think that one advantage of the current syntax is that we immediately know we are defining an implicit (context query?) function, where in the other example we only know it after we read the arrow. Isn't there some other syntax we can use which doesn't have this flaw?

Isn't this exactly the same with normal lambdas and function types?

  type   T = X => Body  // X and Body are types
  val f: T = x => body  // x and body are terms

  type   T = (using X) => Body  // X and Body are types
  val f: T = (using x) => body  // x and body are terms

  f(t)       // t is a term
  f(using t) // t is a term

  // And when both parameter names and types are provided, the two ways align:

  type   T = (x: X) => Body
  val f: T = (x: X) => body

  type   T = (using x: X) => Body
  val f: T = (using x: X) => body

This seems perfectly cromulent to me :^)

I agree with @LPTK, I don't think this is not much of a problem. As I mentioned in the original proposal, I am not a fan of operators. They are difficult to search, read out, and memorize.

I think the problem is that we can write:

def foo(using Context) = ???

but not:

def foo = (using Context) => ???

If I look at the above, it's pretty clear to me that there are definitely going to be people that are going to stumble over this.

@abgruszecki Ah okay, I see. Yes, that's a problem.

How often is (using x) => even used? It seems counter to the rule that contextual values should always be typed when introduced. Could we require (using x: T) => or (using x: _) => instead?

How often is (using x) => even used? It seems counter to the rule that contextual values should always be typed when introduced. Could we require (using x: T) => or (using x: _) => instead?

this definitely important when writing an expression where the expected type is nested ctx function, Ctx1 ?=> Ctx2 ?=> Foo

I also believe that in well-written code it should be hardly used at all. That's kind of the point of context functions that you can leave it out.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

milessabin picture milessabin  路  3Comments

NightMachinary picture NightMachinary  路  3Comments

liufengyun picture liufengyun  路  3Comments

dwijnand picture dwijnand  路  3Comments

Blaisorblade picture Blaisorblade  路  3Comments