Skip to content

Decide on final syntax for given parameters #7151

Closed
@odersky

Description

@odersky

It seems we have implicit consensus on given as the new name for implicit instances. It has a lot more support than its alternative delegate. So, let's take that as a given 😉

given is a good name for instances, but it does have a potential problem that given parameters and given instances are too easily confused. The example that made this painfully clear for me was in #7056, where we find:

given [T1 <: NonEmptyTuple, TZ <: Tuple] as Aux[T1, Head[T1] *: TZ]
given Aux[Tail[T1], TZ] = new Idnt[T1] {
  type Res = Head[T1] *: TZ
  def (t1: T1) idnt: Res = t1.head *: t1.tail.idnt
}

At first, I could make neither heads nor tails of it and thought that the parser was faulty. Then I realized that the second given is a parameter to the first! Sure, it should have been indented but still... The syntax is dangerously misleading.

One way to fix this is to choose different names for introducing parameters and instances. I.e., go back to delegate. Another way to fix it is to put given under parentheses, thereby using the standard way of expressing parameter dependencies. I.e. it would be

def f(x: T)(given Context): T
f(x)(given ctx)

instead of

def f(x: T) given Context: T
f(x) given ctx

This idea, originally proposed by @smarter, is elaborated in #7150 (docs only, no implementation).
One advantage is that it generalizes readily to implicit function types and literals. These would be

(given A) => B
(given x: A) => b

Another advantage is that it makes it possible to have normal parameters after given parameters, something we stopped allowing because the original syntax was so confusing.

A possible downside is in the application of multiple given arguments in one argument list. That would look like

f(given a, b)

instead of

f given (a, b)

The first syntax takes some getting used to, I think.

Another possible option is to keep given for instance definitions, but use something else for implicit parameters. where was suggested by @milessabin. But any solution has to work in all of the following cases:

  • implicit parameters in methods
  • implicit arguments
  • implicit function literals
  • implicit function types

where works OK for the first two, but not for the last two.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions