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
Copy file name to clipboardExpand all lines: docs/docs/reference/other-new-features/creator-applications.md
+25-22Lines changed: 25 additions & 22 deletions
Original file line number
Diff line number
Diff line change
@@ -1,10 +1,11 @@
1
1
---
2
2
layout: doc-page
3
-
title: "Creator Applications"
3
+
title: "Universal Apply Methods"
4
4
---
5
5
6
-
Creator applications allow using simple function call syntax to create instances
7
-
of a class, even if there is no apply method implemented. Example:
6
+
Scala case classes generate apply methods, so that values of case classes can be created using simple function application, without needing to write `new`.
7
+
8
+
Scala 3 generalizes this scheme to all concrete classes. Example:
8
9
```scala
9
10
classStringBuilder(s: String) {
10
11
defthis() =this("")
@@ -13,31 +14,33 @@ class StringBuilder(s: String) {
13
14
StringBuilder("abc") // same as new StringBuilder("abc")
14
15
StringBuilder() // same as new StringBuilder()
15
16
```
16
-
Creator applications generalize a functionality provided so far only for case classes, but the mechanism how this is achieved is different. Instead of generating an apply method, the compiler adds a new possible interpretation to a function call `f(args)`. The previous rules are:
17
-
18
-
Given a function call `f(args)`,
17
+
This works since a companion object with two apply methods
18
+
is generated together with the class. The object looks like this:
The synthetic object `StringBuilder` and its `apply` methods are called _constructor proxies_.
26
+
Constructor proxies are generated even for Java classes and classes coming from Scala 2.
27
+
The precise rules are as follows:
19
28
20
-
- if `f` is a method applicable to `args`, typecheck `f(args)` unchanged,
21
-
- otherwise, if `f` has an `apply` method applicable to `args` as a member, continue with `f.apply(args)`,
22
-
- otherwise, if `f` is of the form `p.m` and there is an implicit conversion `c` applicable to `p` so that `c(p).m` is applicable to `args`, continue with `c(p).m(args)`
29
+
1. A constructor proxy companion object `object C` is created for a concrete class `C`, provided the class does not have already a companion, and there is also no other value or method named `C` defined or inherited in the scope where `C` is defined.
23
30
24
-
There's now a fourth rule following these rules:
31
+
2. Constructor proxy `apply` methods are generated for a concrete class provided
25
32
26
-
- otherwise, if `f` is syntactically a stable identifier, and `new f` where `f` is interpreted as a type identifier is applicable to `args`, continue with `new f(args)`.
33
+
- the class has a companion object (which might have been generated in step 1), and
34
+
- that companion object does not already define a member named `apply`.
27
35
28
-
Analogously, the possible interpretations of a function call with type arguments `f[targs]` are augmented with the following interpretation as a final fallback:
36
+
Each generated `apply` method forwards to one constructor of the class. It has the
37
+
same type and value parameters as the constructor.
29
38
30
-
- if `f` is syntactically a stable identifier, and `new f[targs]` where `f` is interpreted as a type identifier is well-typed, continue with `new f[targs]`.
39
+
Constructor proxy companions cannot be used as values by themselves. A proxy companion object must be selected with `apply` (or be applied to arguments, in which case the `apply` is implicitly inserted).
31
40
41
+
Constructor proxies are also not allowed to shadow normal definitions. That is,
42
+
if an identifier resolves to a constructor proxy, and the same identifier is also
43
+
defined or imported in some other scope, an ambiguity is reported.
32
44
### Motivation
33
45
34
46
Leaving out `new` hides an implementation detail and makes code more pleasant to read. Even though it requires a new rule, it will likely increase the perceived regularity of the language, since case classes already provide function call creation syntax (and are often defined for this reason alone).
35
-
36
-
### Discussion
37
-
38
-
An alternative design would auto-generate `apply` methods for normal classes, in the same way it is done now for case classes. This design was tried but abandoned since it
39
-
caused numerous problems, including
40
-
41
-
- overloading ambiguities
42
-
- overriding errors
43
-
- shadowing of user-defined `apply` methods by more specific auto-generated ones.
0 commit comments