Skip to content

Commit ad64529

Browse files
authored
Merge pull request #6010 from dotty-staging/add-classification
Add classification of language features to docs
2 parents 45af82c + a9c4991 commit ad64529

File tree

3 files changed

+205
-1
lines changed

3 files changed

+205
-1
lines changed

docs/docs/reference/dropped-features/auto-apply.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
layout: doc-page
3-
title: "Auto-Application"
3+
title: "Dropped: Auto-Application"
44
---
55

66
Previously an empty argument list `()` was implicitly inserted when
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
---
2+
layout: doc-page
3+
title: A Classification of Proposed Language Features
4+
date: February 28, 2019
5+
author: Martin Odersky
6+
---
7+
8+
This document provides an overview of the features proposed for Scala 3 with the aim to facilitate the discussion what to include and when to include it. It classifies features into seven groups: Essential foundations, simplifications, restrictions, dropped features, changed features, new features, and features oriented towards meta-programming with the aim to replace existing macros.
9+
10+
Each feature group contains sections classifying the status (i.e. relative importance to be a part of Scala 3, and relative urgency when to decide this) and the migration cost
11+
of the features in it.
12+
13+
The current document reflects the state of things as of end of February, 2019. It will be updated to reflect any future changes in that status.
14+
15+
## Essential Foundations
16+
17+
These new features directly model core features of DOT, higher-kinded types, and the [SI calculus for implicit resolution](https://infoscience.epfl.ch/record/229878/files/simplicitly_1.pdf).
18+
19+
- [Intersection types](https://dotty.epfl.ch/docs/reference/new-types/intersection-types.html), replacing compound types,
20+
- [Union types](https://dotty.epfl.ch/docs/reference/new-types/union-types.html),
21+
- [Type lambdas](https://dotty.epfl.ch/docs/reference/new-types/type-lambdas.html),
22+
replacing encodings using structural types and type projection.
23+
- [Context Queries](https://dotty.epfl.ch/docs/reference/contextual/query-types.html)
24+
(aka implicit function types) offering abstraction over inferable parameters.
25+
26+
**Status: essential**
27+
28+
These are essential core features of Scala 3. Without them, Scala 3 would be a completely different language, with different foundations.
29+
30+
**Migration cost: none to low**
31+
32+
Since these are additions, there's generally no migration cost for old code. An exception are intersection types which replace compound types with slightly cleaned-up semantics. But few programs would be affected by this change.
33+
34+
## Simplifications
35+
36+
These features replace existing constructs with the aim of making the language safer and simpler to use, and to promote uniformity in code style.
37+
38+
- [Trait Parameters](https://dotty.epfl.ch/docs/reference/other-new-features/trait-parameters.html) replace [early initializers](https://dotty.epfl.ch/docs/reference/dropped-features/early-initializers.html) with a more generally useful construct,
39+
- [Implied Instances](https://dotty.epfl.ch/docs/reference/contextual/instance-defs.html)
40+
replace implicit objects and defs, focussing on intent over mechanism,
41+
- [Inferable parameters](https://dotty.epfl.ch/docs/reference/contextual/inferable-params.html) replace implicit parameters, avoiding their ambiguities,
42+
- [Extension Methods](https://dotty.epfl.ch/docs/reference/contextual/extension-methods.html) replace implicit classes with a clearer and simpler mechanism,
43+
- [Opaque Type Aliases](https://dotty.epfl.ch/docs/reference/other-new-features/opaques.html) replace most uses
44+
of value classes while guaranteeing absence of boxing,
45+
- [Toplevel definitions](https://dotty.epfl.ch/docs/reference/dropped-features/package-objects.html) replace package objects, dropping syntactic boilerplate,
46+
- [Vararg patterns](https://dotty.epfl.ch/docs/reference/changed-features/vararg-patterns.html) now use the form `: _*` instead of `@ _*`, mirroring vararg expressions,
47+
- [Synthesized creation methods](https://contributors.scala-lang.org/t/expunging-new-from-scala-3/2868/81)
48+
replace `new` expressions (under discussion, not implemented),
49+
- [@infix and @alpha](https://github.com/lampepfl/dotty/pull/5975)
50+
replace unrestricted infix operations and symbolic names (proposed, not implemented).
51+
52+
With the exception of early initializers and old-style vararg patterns, all superseded features continue to be available in Scala 3.0. The plan is to deprecate and phase them out later.
53+
54+
Value classes (superseded by opaque type aliases) are a special case. There are currently no deprecation plans for value classes, since we might want to bring them back in a more general form if they are supported natively by the JVM as is planned by project Valhalla.
55+
56+
**Status: bimodal: now or never / can delay**
57+
58+
These are essential simplifications. If we decide to adopt them, we should do it for 3.0. Otherwise we are faced with the awkward situation that the Scala 3 documentation has to describe an old feature that will be replaced or superseded by a simpler one in the future.
59+
60+
On the other hand, we need to decide now only about the new features in this list. The decision to drop the superseded features can be delayed. Of course, adopting a new feature without deciding to drop the superseded feature will make the language larger.
61+
62+
**Migration cost: moderate**
63+
64+
For the next several versions, old features will remain available and deprecation and rewrite techniques can make any migration effort low and gradual.
65+
66+
67+
## Restrictions
68+
69+
These features are restricted to make the language safer.
70+
71+
- [Implicit Conversions](https://dotty.epfl.ch/docs/reference/contextual/conversions.html): there is only one way to define implicit conversions instead of many, and potentially surprising implicit conversions require a language import.
72+
- [Implied Imports](https://dotty.epfl.ch/docs/reference/contextual/import-implied.html): implicits now require a special form of import, to make the import clearly visible.
73+
- [Type Projection](https://dotty.epfl.ch/docs/reference/dropped-features/type-projection.html): only classes can be used as prefix `C` of a type projection `C#A`. Type projection on abstract types is no longer supported since it is unsound.
74+
- [Multiversal Equality](https://dotty.epfl.ch/docs/reference/contextual/multiversal-equality.html) implements an "opt-in" scheme to rule out nonsensical comparisons with `==` and `!=`.
75+
76+
Unrestricted implicit conversions continue to be available in Scala 3.0, but will be deprecated and removed later. Unrestricted versions of the other features in the list above are available only under `-language:Scala2`.
77+
78+
**Status: now or never**
79+
80+
These are essential restrictions. If we decide to adopt them, we should do it for 3.0. Otherwise we are faced with the awkward situation that the Scala 3 documentation has to describe a feature that will be restricted in the future.
81+
82+
**Migration cost: low to high**
83+
84+
- _low_: multiversal equality rules out code that is nonsensical, so any rewrites required by its adoption should be classified as bug fixes.
85+
- _moderate_: Restrictions to implicits can be accommodated by straightforward rewriting.
86+
- _high_: Unrestricted type projection cannot always rewritten directly since it is unsound in general.
87+
88+
## Dropped Features
89+
90+
These features are proposed to be dropped without a new feature replacing them. The motivation for dropping these features is to simplify the language and its implementation.
91+
92+
- [DelayedInit](https://dotty.epfl.ch/docs/reference/dropped-features/delayed-init.html),
93+
- [Existential types](https://dotty.epfl.ch/docs/reference/dropped-features/existential-types.html),
94+
- [Procedure syntax](https://dotty.epfl.ch/docs/reference/dropped-features/procedure-syntax.html),
95+
- [Class shadowing](https://dotty.epfl.ch/docs/reference/dropped-features/class-shadowing.html),
96+
- [XML literals](https://dotty.epfl.ch/docs/reference/dropped-features/xml.html),
97+
- [Symbol literals](https://dotty.epfl.ch/docs/reference/dropped-features/symlits.html),
98+
- [Auto application](https://dotty.epfl.ch/docs/reference/dropped-features/auto-apply.html),
99+
- [Weak conformance](https://dotty.epfl.ch/docs/reference/dropped-features/weak-conformance.html),
100+
- [Compound types](https://dotty.epfl.ch/docs/reference/new-types/intersection-types.html),
101+
- [Auto tupling](https://github.com/lampepfl/dotty/pull/4311) (implemented, but not merged).
102+
103+
The date when these features are dropped varies. The current status is:
104+
105+
- Not implemented at all:
106+
- DelayedInit, existential types, weak conformance.
107+
- Supported under `-language:Scala2`:
108+
- procedure syntax, class shadowing, symbol literals, auto application, auto tupling in a restricted form.
109+
- Supported in 3.0, to be deprecated and phased out later:
110+
- XML literals, compound types.
111+
112+
**Status: mixed**
113+
114+
Currently unimplemented features would require considerable implementation effort which would in most cases make the compiler more buggy and fragile and harder to understand. If we do not decide to drop them, they will probably show up as "not yet implemented" in the Scala 3.0 release.
115+
116+
Currently implemented features could stay around indefinitely. Updated docs may simply ignore them, in the expectation that they might go away eventually. So the decision about their removal can be delayed.
117+
118+
**Migration cost: moderate to high**
119+
120+
Dropped features require rewrites to avoid their use in programs. These rewrites can sometimes be automatic (e.g. for procedure syntax, symbol literals, auto application)
121+
and sometimes need to be manual (e.g. class shadowing, auto tupling). Sometimes the rewrites would have to be non-local, affecting use sites as well as definition sites (e.g., in the case of DelayedInit, unless we find a solution).
122+
123+
## Changes
124+
125+
These features have undergone changes in Scala 3 to make them more regular and useful.
126+
127+
- [Structural Types](https://dotty.epfl.ch/docs/reference/changed-features/structural-types.html): They now allow pluggable implementations, which greatly increases their usefulness. Some usage patterns are restricted compared to the status quo.
128+
- [Name-based pattern matching](https://dotty.epfl.ch/docs/reference/changed-features/pattern-matching.html): The existing undocumented Scala 2 implementation has been codified in a slightly simplified form.
129+
- [Eta expansion](https://dotty.epfl.ch/docs/reference/changed-features/eta-expansion.html) is now performed universally also in the absence of an expected type. The postfix `_` operator is thus made redundant. It will be deprecated and dropped after Scala 3.0.
130+
- [Implicit Resolution](https://dotty.epfl.ch/docs/reference/changed-features/implicit-resolution.html): The implicit resolution rules have been cleaned up to make them more useful and less surprising. Implicit scope is restricted to no longer include package prefixes.
131+
132+
Most aspects of old-style implicit resolution are still available under `-language:Scala2`. The other changes in this list are applied unconditionally.
133+
134+
**Status: strongly advisable**
135+
136+
The features have been implemented in their new form in Scala 3.0's compiler. They provide clear improvements in simplicity and functionality compared to the status quo. Going back would require significant implementation effort for a net loss of functionality.
137+
138+
**Migration cost: low to high**
139+
140+
Only a few programs should require changes, but some necessary changes might be non-local (as in the case of restrictions to implicit scope).
141+
142+
## New Features
143+
144+
These are additions to the language that make it more powerful or pleasant to use.
145+
146+
- [Enums](https://dotty.epfl.ch/docs/reference/enums/enums.html) provide concise syntax for enumerations and [algebraic data types](https://dotty.epfl.ch/docs/reference/enums/adts.html).
147+
- [Auto Parameter Tupling](https://dotty.epfl.ch/docs/reference/other-new-features/auto-parameter-tupling.html) avoid having to use `case` for tupled parameter destructuring.
148+
- [Named Type Arguments](https://dotty.epfl.ch/docs/reference/other-new-features/named-typeargs.html) generalize named parameters, providing the ability to define
149+
a partial list of type arguments.
150+
- [Dependent Function Types](https://dotty.epfl.ch/docs/reference/new-types/dependent-function-types.html) generalize dependent methods to dependent function values and types.
151+
- [Polymorphic Function Types](https://github.com/lampepfl/dotty/pull/4672) generalize polymorphic methods to dependent function values and types (proposed, not fully implemented).
152+
- [Kind Polymorphism](https://dotty.epfl.ch/docs/reference/other-new-features/kind-polymorphism.html) allows the definition of operators working equally on types and type constructors.
153+
154+
**Status: mixed**
155+
156+
Enums offer an essential simplification of core features, so they should be adopted for Scala 3.0. Auto-parameter tupling is a very small change that removes some awkwardness, so it might as well be adopted now. The other features constitute more specialized functionality which could be introduced in later versions. On the other hand, except for polymorphic function types they are all fully implemented, so if the Scala 3.0 spec does not include them, they might be still made available under a language flag.
157+
158+
**Migration cost: none**
159+
160+
Being new features, existing code migrates without changes. To be sure, sometimes it would be attractive to rewrite code to make use of the new features in order to increase clarity and conciseness.
161+
162+
## Meta Programming
163+
164+
The following features together try to put meta programming in Scala on a new basis. So far, meta programming was achieved by a combination of macros and libraries such as Shapeless that were in turn based on some key macros. Current Scala 2 macro mechanisms are a thin veneer on top the current Scala 2 compiler, which makes them fragile and in many cases impossible to port to Scala 3.
165+
166+
It's worth noting that macros were never included in the Scala 2 language specification and were so far made available only under an `-experimental` flag. This has not prevented their widespread usage.
167+
168+
To enable porting most uses of macros, we propose the advanced language features listed below. These designs are more provisional than the rest of the proposed language features for Scala 3.0. There might still be some changes until the final release. Stabilizing the feature set needed for meta programming is our first priority.
169+
170+
- [Match Types](https://dotty.epfl.ch/docs/reference/new-types/match-types.html) allow computation on types.
171+
- [Typeclass derivation](https://dotty.epfl.ch/docs/reference/contextual/derivation.html) provides an in-language implementation of the `Gen` macro in Shapeless and other foundational libraries. The new implementation is more robust, efficient and easier to use than the macro.
172+
- [Inferable by-name parameters](https://dotty.epfl.ch/docs/reference/contextual/inferable-by-name-parameters.html) provide a more robust in-language implementation of the `Lazy` macro in Shapeless.
173+
- [Inline](https://dotty.epfl.ch/docs/reference/other-new-features/inline.html) provides
174+
by itself a straightforward implementation of some simple macros and is at the same time an essential building block for the implementation of complex macros.
175+
- [Quotes and Splices](https://dotty.epfl.ch/docs/reference/other-new-features/principled-meta-programming.html) provide a principled way to express macros and staging with a unified set of abstractions.
176+
- [Erased Terms](https://dotty.epfl.ch/docs/reference/other-new-features/erased-terms.html) provide a general mechanism for compile-time-only computations.
177+
178+
**Status: not yet settled**
179+
180+
We know we need a practical replacement for current macros. The features listed above are very promising in that respect, but we need more complete implementations and more use cases to reach a final verdict.
181+
182+
**Migration cost: very high**
183+
184+
Existing macro libraries will have to be rewritten from the ground up. In many cases the rewritten libraries will turn out to be simpler and more robust than the old ones, but that does not relieve one of the cost of the rewrites. It's currently unclear to what degree users of macro libraries will be affected. We aim to provide sufficient functionality so that core macros can be re-implemented fully, but given the vast feature set of the various macro extensions to Scala 2 it is difficult to arrive at a workable limitation of scope.
185+
186+
## Changes to Type Checking and Inference
187+
188+
The Scala 3 compiler uses a new algorithm for type inference, which relies on
189+
a general subtype constraint solver. The new algorithm often
190+
[works better than the old](https://contributors.scala-lang.org/t/better-type-inference-for-scala-send-us-your-problematic-cases/2410), but there are inevitably situations where the results of both algorithms differ, leading to errors diagnosed by Scala 3 for programs that the Scala 2 compiler accepts.
191+
192+
**Status: essential**
193+
194+
The new type-checking and inference algorithms are the essential core of the new compiler. They cannot be reverted without dropping the whole implementation of Scala 3.
195+
196+
**Migration cost: high**
197+
198+
Some existing programs will break and, given the complex nature of type inference, it will not always be clear what change caused the breakage and how to fix it.
199+
200+
In our experience, macros and changes in type and implicit argument inference together cause the large majority of problems encountered when porting existing code to Scala 3. The latter source of problems could be addressed systematically by a tool that added all inferred types and implicit arguments to a Scala 2 source code file. Most likely such a tool would be implemented as a Scala 2 compiler plugin. The resulting code would have a greatly increased likelihood to compile under Scala 3, but would often be bulky to the point of being unreadable. A second part of the rewriting tool should then selectively and iteratively remove type and implicit annotations that were synthesized by the first part as long as they compile under Scala 3. This second part could be implemented as a program that invokes the Scala 3 compiler `dotc` programmatically.
201+
202+
Several people have proposed such a tool for some time now. I believe it is time we find the will and the resources to actually implement it.

docs/docs/reference/overview.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,5 @@ The primary goal of the language constructs in this section is to enable high-le
141141
will be generated for them. Typical candidates for erased parameters are type
142142
constraints such as `=:=` and `<:<` that are expressed through implicits.
143143
Erased parameters improve both run times (since no argument has to be constructed) and compile times (since potentially large arguments can be eliminated early).
144+
145+
See also: [A classification of proposed language features](./features-classification.html)

0 commit comments

Comments
 (0)