Skip to content

Commit e38ca6d

Browse files
committed
First draft of SIP to allow referring to other arguments in default parameters
1 parent b726731 commit e38ca6d

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
layout: sip
3+
disqus: true
4+
title: SIP-NN - SIP Title
5+
---
6+
7+
**By: Pathikrit Bhowmick**
8+
9+
## History
10+
11+
| Date | Version |
12+
|---------------|---------------|
13+
| Jan 11th 2017 | Initial Draft |
14+
15+
## Introduction
16+
Currently there is no way to refer to other arguments in the default parameters list:
17+
18+
Does not compile:
19+
```scala
20+
def substring(s: String, start: Int = 0, end: Int = s.length): String
21+
```
22+
23+
The workaround to achieve this is by using a curried-function:
24+
```scala
25+
def substring(s: String, start: Int = 0)(end: Int = s.length): String
26+
```
27+
28+
However, the above workaround is not always suitable in certain situations.
29+
30+
### Proposal
31+
Allow to refer to ***any*** parameters in the same (or left) curried parameter list:
32+
```scala
33+
def substring(s: String, start: Int = 0, end: Int = s.length) // Legal
34+
def substring(start: Int = 0, end: Int = s.length, s: String) // Legal !!!
35+
def substring(s: String, start: Int = 0)(end: Int = s.length) // Legal (works currently)
36+
def substring(start: Int = 0, end: Int = s.length)(s: String) // Illegal
37+
```
38+
39+
The same applies for class arguments:
40+
```scala
41+
class Substring(s: String, start: Int = 0, end: Int = s.length) // Legal
42+
class Substring(start: Int = 0, end: Int = s.length, s: String) // Legal
43+
class Substring(s: String, start: Int = 0)(end: Int = s.length) // Legal
44+
class Substring(start: Int = 0, end: Int = s.length)(s: String) // Illegal
45+
```
46+
47+
We should also be able to refer to ***multiple*** paramaeters:
48+
```scala
49+
def binarySearch(start: Int, end: Int, middle: Int = (start + end)/2) // Legal
50+
```
51+
52+
## Interactions with other syntax
53+
54+
#### Partially Applied Functions:
55+
It must be required to specify the default arguments if the default argument's reference is unapplied:
56+
```scala
57+
def substring(s: String, start: Int = 0, end: Int = s.length)
58+
59+
substring(_, start = 0, end = 5) // Legal
60+
substring(_, end = 5) // Legal (start = 0)
61+
substring(_, start = 0) // Illegal (need to declare end)
62+
```
63+
64+
#### Multiple Implicit Parameters
65+
[Multiple implicit parameters](https://github.com/scala/scala.github.com/pull/520) should also be allowed to refer to one another (left to right):
66+
```scala
67+
def codec[A](data: A)(implicit encoder: Encoder[A])(implicit decoder: Decoder[A] = encoder.reverse) // Legal
68+
```
69+
70+
#### Referring to type members:
71+
The default parameters should be able to refer to type members of other arguments e.g.:
72+
```scala
73+
trait Codec {
74+
type Input
75+
type Output
76+
}
77+
78+
def codec(codec: Codec, in: codec.Input, out: codec.Output) // Legal !!!
79+
```
80+
81+
### Other languages
82+
The following languages allow referring to previously declared arguments in the function signature:
83+
* [CoffeeScript](http://coffeescript.org/)
84+
* [Kotlin](http://kotlinlang.org)
85+
* [TypeScript](https://www.typescriptlang.org/)
86+
87+
AFAIK, there are no major languages where referring to parameters declared to the ***right*** is allowed.
88+
89+
### Discussions
90+
[Scala Lang Forum](https://contributors.scala-lang.org/t/refer-to-previous-argument-in-default-argument-list/215/6)

0 commit comments

Comments
 (0)