Skip to content

Commit 8bd5b36

Browse files
committed
Document new changes
1 parent 93ff8f1 commit 8bd5b36

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
---
2+
layout: doc-page
3+
title: "New Method Syntax"
4+
movedTo: https://docs.scala-lang.org/scala3/reference/other-new-features/new-method-syntax.html
5+
---
6+
7+
The inclusion of using clauses is not the only way in which methods have been updated, type parameter clauses are now allowed in any number and at any position.
8+
9+
## Syntax Changes
10+
11+
### In Scala 2
12+
13+
The old syntax only allowed zero or one type parameter clause, followed by any number of term clauses, optionnally followed by an implicit clause:
14+
15+
```scala
16+
def foo[T, U](x: T)(y: U)(z: Int, s:String)(a: Array[T])(implicit List[U])
17+
```
18+
19+
### In Scala 3
20+
21+
The new syntax allows any number of type, term and using clause, in any order, optionnaly followed by an implicit clause:
22+
(do note however that [implicit clause are discouraged, in favor of using clauses](https://docs.scala-lang.org/scala3/reference/contextual/relationship-implicits.html))
23+
24+
```scala
25+
def foo[T, U](x: T)(y: U)[V](z: V, s: String)[A](a: Array[A])(implicit List[U])
26+
```
27+
28+
### Unchanged
29+
30+
Class definitions and type declarations are unnaffected, there can only be up to one type clause, in leading posion.
31+
32+
## Motivation
33+
34+
The new syntax is a powerful but natural extension of the old one, it allows new design patterns while staying intuitive and legible.
35+
36+
### Dependent Type Clauses
37+
38+
As type clauses can come after term clauses, it is now possible to have type parameters depend on term parameters:
39+
40+
```scala
41+
trait Key { type Value }
42+
trait DB {
43+
def get(k: Key): Option[k.Value] // dependent return type
44+
def getOrElse(k: Key)[V >: k.Value](default: V): V // dependent type parameter
45+
}
46+
```
47+
48+
Note that simply replacing `V` by `k.Value` would not be equivalent, the above allows for example, assuming `k.Value` is `Int`:
49+
`getOrElse(k)[Number](0.1)`, which returns a `Number`.
50+
51+
### Partial Inference
52+
53+
It is now possible to only infer some of the type parameters, this reduces boilerplate at the use site:
54+
```scala
55+
trait StaticSizeList[S <: Int & Singleton, T]
56+
def filled[S <: Int & Singleton][T](x: T): StaticSizeList[S,T] = ???
57+
val helloes = filled[4]("Hello!") // S=4, and T is inferred
58+
```
59+
60+
## Details
61+
62+
### Application
63+
64+
Method application is unchanged, in cases where multiple type clauses are expected but not all are passed, the leftmost ones are inferred.
65+
66+
In particular, the following does not type check, even though the argument `Char` is only valid for `C`:
67+
```scala
68+
def triple[A <: Int][B <: String][C <: Char](a: A, b: B, c: C) = ???
69+
triple[Int][Char](0,"",'c') // error: Char does not conform to upperbound String
70+
```
71+
72+
### Extension Methods
73+
74+
Naturally extension methods follow the same syntax, so the following is valid:
75+
```scala
76+
extension [T](l1: List[T])
77+
def zipWith[U](l2: List[U])[V](l3: List[V]): List[(T,U,V)]
78+
```
79+
80+
### Formal syntax
81+
82+
```
83+
DefDcl ::= DefSig ‘:’ Type
84+
DefDef ::= DefSig [‘:’ Type] ‘=’ Expr
85+
DefSig ::= id [DefParamClauses] [DefImplicitClause]
86+
DefParamClauses ::= DefParamClause { DefParamClause }
87+
DefParamClause ::= DefTypeParamClause
88+
| DefTermParamClause
89+
| UsingParamClause
90+
DefTypeParamClause::= [nl] ‘[’ DefTypeParam {‘,’ DefTypeParam} ‘]’
91+
DefTypeParam ::= {Annotation} id [HkTypeParamClause] TypeParamBounds
92+
DefTermParamClause::= [nl] ‘(’ [DefTermParams] ‘)’
93+
UsingParamClause ::= [nl] ‘(’ ‘using’ (DefTermParams | FunArgTypes) ‘)’
94+
DefImplicitClause ::= [nl] ‘(’ ‘implicit’ DefTermParams ‘)’
95+
DefTermParams ::= DefTermParam {‘,’ DefTermParam}
96+
DefTermParam ::= {Annotation} [‘inline’] Param
97+
Param ::= id ‘:’ ParamType [‘=’ Expr]
98+
```
99+
100+
## TODO
101+
102+
The only thing missing for this to be merged is to fix the scaladoc, the steps that need to be taken are the following:
103+
* merge/rebase on top of [Semi-Fix scaladoc of extensions methods](https://github.com/lampepfl/dotty/pull/14321)
104+
* it fixes extension methods
105+
* it gives easier backbone to work with
106+
* fix `ClassLikeSupport.scala`
107+
* refactor `MemberInfo` to take multiple type clauses, can be done through updating `ParameterList`
108+
* update `unwrapMemberInfo` to take those changes into account
109+
* update `parseMethod` to handle multiple type clauses
110+
* potentially fix wherever `ClassLikeSupport.scala` is used

0 commit comments

Comments
 (0)