From d73424b031f32f5247a7acebfb233b72c99dcf69 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Thu, 25 Oct 2018 18:27:24 +0200 Subject: [PATCH] More details on named type arguments --- docs/docs/reference/named-typeargs-spec.md | 38 ++++++++++++++++++++++ docs/docs/reference/named-typeargs.md | 23 +++++++------ tests/neg/namedTypeParams.scala | 4 +++ tests/pos/namedTypeParams.scala | 6 ++++ 4 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 docs/docs/reference/named-typeargs-spec.md diff --git a/docs/docs/reference/named-typeargs-spec.md b/docs/docs/reference/named-typeargs-spec.md new file mode 100644 index 000000000000..404f96852aca --- /dev/null +++ b/docs/docs/reference/named-typeargs-spec.md @@ -0,0 +1,38 @@ +--- +layout: doc-page +title: "Named Type Arguments - More Details" +--- + +## Syntax + +The addition to the grammar is: + +``` +SimpleExpr1 ::= ... + | SimpleExpr (TypeArgs | NamedTypeArgs) +NamedTypeArgs ::= ‘[’ NamedTypeArg {‘,’ NamedTypeArg} ‘]’ +NamedTypeArg ::= id ‘=’ Type +``` + +Note in particular that named arguments cannot be passed to type constructors: + +``` scala +class C[T] + +val x: C[T = Int] = // error + new C[T = Int] // error + +class E extends C[T = Int] // error +``` + +## Compatibility considerations + +Named type arguments do not have an impact on binary compatibility, but they +have an impact on source compatibility: if the name of a method type parameter +is changed, any existing named reference to this parameter will break. This +means that the names of method type parameters are now part of the public API +of a library. + +(Unimplemented proposal: to mitigate this, +[`scala.deprecatedName`](https://www.scala-lang.org/api/current/scala/deprecatedName.html) +could be extended to also be applicable on method type parameters.) diff --git a/docs/docs/reference/named-typeargs.md b/docs/docs/reference/named-typeargs.md index 431b78bb52e2..46e48eac2909 100644 --- a/docs/docs/reference/named-typeargs.md +++ b/docs/docs/reference/named-typeargs.md @@ -5,21 +5,24 @@ title: "Named Type Arguments" Type arguments of methods can now be named, as well as by position. Example: +``` scala +def construct[Elem, Coll[_]](xs: Elem*): Coll[Elem] = ??? - def construct[Elem, Coll[_]](xs: Elem*): Coll[Elem] = ??? - - val xs2 = construct[Coll = List, Elem = Int](1, 2, 3) - val xs3 = construct[Coll = List](1, 2, 3) +val xs1 = construct[Coll = List, Elem = Int](1, 2, 3) +val xs2 = construct[Coll = List](1, 2, 3) +``` Similar to a named value argument `(x = e)`, a named type argument `[X = T]` instantiates the type parameter `X` to the type `T`. Type arguments must be all named or un-named, mixtures of named and positional type arguments are not supported. -The main benefit of named type arguments is that they allow some -arguments to be omitted. Indeed, if type arguments are named, some -arguments may be left out. An example is the definition of `xs3` -above. A missing type argument is inferred as usual by local type -inference. The same is not true for positional arguments, which must always -be provided for all type parameters. +## Motivation + +The main benefit of named type arguments is that unlike positional arguments, +you are allowed to omit passing arguments for some parameters, like in the +definition of `xs2` above. A missing type argument is inferred as usual by +local type inference. This is particularly useful in situations where some type +arguments can be easily inferred from others. +[More details](./named-typeargs-spec.html) diff --git a/tests/neg/namedTypeParams.scala b/tests/neg/namedTypeParams.scala index 75bb1cd7e203..d01d2062b170 100644 --- a/tests/neg/namedTypeParams.scala +++ b/tests/neg/namedTypeParams.scala @@ -9,4 +9,8 @@ object Test { class E extends C[T = Int] // error: ']' expected, but `=` found // error class F extends C[T = Int]() // error: ']' expected, but `=` found // error + def f[X, Y](x: X, y: Y): Int = ??? + + f[X = Int, String](1, "") // error + f[X = Int][X = Int][Y = String](1, "") // error } diff --git a/tests/pos/namedTypeParams.scala b/tests/pos/namedTypeParams.scala index 0717d8475a6d..2938b6dbd29b 100644 --- a/tests/pos/namedTypeParams.scala +++ b/tests/pos/namedTypeParams.scala @@ -6,4 +6,10 @@ object Test { f[X = Int, Y = String](1, "") f[X = Int](1, "") f[Y = String](1, "") + + f[X = Int][Y = String](1, "") + f[X = Int][String](1, "") + + f[Y = String][X = Int](1, "") + f[Y = String][Int](1, "") }