You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Removed author's notes, and Adding them here:
1. Unary types are not crucial as infix type precedence, but good for completeness.
2. For the proposal section, I can copy-paste the specifications from expression and modify them to types, if it so required.
3. Would love some help to complete what happens in different programming languages.
4. I think it is very unlikely that variance annotation will interact with literal types, so the confusion is not that critical.
5. Backward compatibility: I don't know if providing a flag to select the precedence is good or not. IMHO, it is better to create a tool that adds brackets to convert code to the old associativity. @jvican's suggestion to use a tool to analyze libraries and check if they are compatible or not is interesting. Don't know if I have time to make it. It is more useful for me to explore the scala compiler code, and make a PR for this SIP 😄
- Modified the example to `/` instead of `*` because currently dotty has bug and does not allow `*` infix type.
- Removed scala meta section.
- Removed extended proposal alternative:
It is possible to extend this proposal and allow the developer to annotate the expected associativity and precedence per operation.
I personally don't like this, but if such a solution is better for the community, then I will gladly modify this SIP to reflect that.
See the following [Typelevel Scala issue](typelevel/scala#69) for the suggestion.
Copy file name to clipboardExpand all lines: sips/pending/_posts/2017-02-07-make-types-behave-like-expressions.md
+43-53Lines changed: 43 additions & 53 deletions
Original file line number
Diff line number
Diff line change
@@ -8,9 +8,12 @@ title: SIP-NN - Make types behave like expressions
8
8
9
9
## History
10
10
11
-
| Date | Version |
12
-
|---------------|------------------|
13
-
| Feb 7th 2017 | Initial Draft |
11
+
| Date | Version |
12
+
|---------------|--------------------------|
13
+
| Feb 7th 2017 | Initial Draft |
14
+
| Feb 9th 2017 | Updates from feedback |
15
+
16
+
Your feedback is welcome! If you're interested in discussing this proposal, head over to [this](https://contributors.scala-lang.org/t/sip-nn-make-infix-type-alias-precedence-like-expression-operator-precedence/471) Scala Contributors thread and let me know what you think.
14
17
15
18
---
16
19
## Introduction
@@ -19,43 +22,42 @@ Unfortunately, there is a 'surprise' element since the two differ in behaviour:
19
22
20
23
***Infix operator precedence and associativity**:
21
24
Infix types are 'mostly' left-associative,
22
-
while the expression operations are more intuitive with different precedence weights.
25
+
while the expression operation precedence is determined by the operator's first character (e.g., `/` is precedent to `+`).
23
26
Please see [Infix Types](http://scala-lang.org/files/archive/spec/2.12/03-types.html#infix-types) and [Infix Operations](http://scala-lang.org/files/archive/spec/2.12/06-expressions.html#infix-operations) sections of the Scala specifications for more details.
//Result_Surprise expands to Plus[Prod[Plus[N1,N2],N3],N4]
51
-
typeResult_Expected=N1+ (N2*N3) +N4
52
-
//Result_Expected expands to Plus[Plus[N1,Prod[N2,N3]],N4]
43
+
traitPlus[N1, N2]
44
+
traitDiv[N1, N2]
45
+
type+[N1, N2] =Plus[N1, N2]
46
+
type/[N1, N2] =Div[N1, N2]
47
+
traitN1
48
+
traitN2
49
+
traitN3
50
+
traitN4
51
+
//Error!
52
+
//Left expands to Plus[Plus[N1,Div[N2,N3]],N4] (Surprising)
53
+
//Right expands to Plus[Div[Plus[N1,N2],N3],N4]
54
+
implicitly[(N1+N2/N3+N4) =:= (N1+ (N2/N3) +N4)]
53
55
}
54
56
```
55
57
56
58
***Prefix operators bracketless unary use**: While expressions have prefix unary operators, there are none for types. See the [Prefix Operations](http://scala-lang.org/files/archive/spec/2.12/06-expressions.html#prefix-operations) section of the Scala specification.
57
59
This is a lacking feature of the type language Scala offers. See also interactions of this feature with other Scala features, further down this text.
58
-
(Author's note: Not crucial as infix precedence, but good for completeness)
60
+
59
61
60
62
**Example**:
61
63
```scala
@@ -91,19 +93,22 @@ The proposal is split into two; type infix precedence, and prefix unary types. N
91
93
92
94
### Proposal, Part 1: Infix type precedence & associativity
93
95
Make infix types conform to the same precedence and associativity traits as expression operations.
94
-
(Author's note: I can copy-paste the specification and modify it, if it so required)
95
96
### Proposal, Part 2: Prefix unary types
96
97
Add prefix types, exactly as specified for prefix expression.
97
-
(Author's note: I can copy-paste the specification and modify it, if it so required)
98
+
98
99
99
100
---
101
+
## Motivation
102
+
The general motivation is developers expect terms and types to behave equally regarding operation precedence and availability of unary types.
100
103
101
-
## Motivating examples
104
+
###Motivating examples
102
105
#### Dotty infix type similarity
103
-
Dotty infix type associativity and precedence seem to be the same as expressions (Author's note: I have seen no documentation of this, but checked the implementation for a simple example `implicitly[(N1 + (N2 / N3) + N4) =:= (N1 + N2 / N3 + N4)]`).
104
-
Dotty has no prefix types.
106
+
Dotty infix type associativity and precedence seem to act the same as expressions.
107
+
No documentation available to prove this, but the infix example above works perfectly in dotty.
108
+
109
+
Dotty has no prefix types, same as Scalac.
105
110
106
-
#### Singleton-ops library
111
+
#### Singleton-ops library example
107
112
The [singleton-ops library](https://github.com/fthomas/singleton-ops) with [Typelevel Scala](https://github.com/typelevel/scala) (which implemented [SIP-23](http://docs.scala-lang.org/sips/pending/42.type.html)) enables developers to express literal type operations more intuitively.
108
113
For example:
109
114
```scala
@@ -129,18 +134,16 @@ val works : 1 + (2 * 3) + 4 = 11
The following stackoverflow question demonstrate developers are 'surprised' by the difference in infix precedence.
137
+
#### Developer issues example
138
+
The following stackoverflow question demonstrate developers are 'surprised' by the difference in infix precedence, expecting infix type precedence to act the same as expression operations.
Variance annotation uses the `-` and `+` symbols to annotate contravariant and covariant subtyping, respectively. Introducing unary prefix types might lead to some confusion.
146
+
Variance annotation uses the `-` and `+` symbols to annotate contravariant and covariant subtyping, respectively. Introducing unary prefix types may lead to some developer confusion.
144
147
E.g.
145
148
```scala
146
149
traitNegate[A]
@@ -150,7 +153,6 @@ type unary_+[A] = Positive[A]
150
153
traitContravariant[B, -A<:-B] //contravariant A subtype upper-bounded by Negate[B]
151
154
traitCovariant[B, +A<:+B] //covariant A subtype upper-bounded by Positive[B]
152
155
```
153
-
(Author's note: it seem very unlikely that such feature interaction will occur)
154
156
155
157
#### Negative Literal Types
156
158
Negative literal types are annotated using the `-` symbol. This can lead to the following confusion:
@@ -172,26 +174,14 @@ val c : +42 = 42 //error: ';' expected but integer literal found
172
174
```
173
175
This means that if unary prefix types are added, then `+42` will be a type expansion of `unary_+[42]`.
174
176
175
-
#### Scala meta
176
-
Open question how this SIP affects `scala-meta`.
177
-
178
177
---
179
178
180
179
## Backward Compatibility
181
180
Changing infix type associativity and precedence affects code that uses type operations and conforms to the current specification.
182
-
(Author's note: I don't know if providing a flag to select the precedence is good or not. IMHO, it is better to create a tool that adds brackets to convert code to the old associativity.)
183
181
184
182
---
185
183
186
-
### Extended proposal alternative
187
-
It is possible to extend this proposal and allow the developer to annotate the expected associativity and precedence per operation.
188
-
(Author's note: I personally don't like this, but if such a solution is better for the community, then I will gladly modify this SIP to reflect that.)
189
-
See the following [Typelevel Scala issue](https://github.com/typelevel/scala/issues/69) for the suggestion.
190
-
191
-
### Other languages
192
-
Would love some help to complete what happens in different programming languages.
0 commit comments