|
| 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