-
Notifications
You must be signed in to change notification settings - Fork 2
/
ImplicitClassSIP.txt
46 lines (27 loc) · 3.13 KB
/
ImplicitClassSIP.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Abstract
A minimal language construct is proposed that allows for more concise use of the common "Pimp My Library" pattern. This construct permits the compiler to eliminate object creation so long as the transformation preserves the semantics of the original program. In addition, an annotation is proposed for the standard library that verifies such an optimization was performed.
Motivation
The popular Pimp My Library (http://www.artima.com/weblogs/viewpost.jsp?thread=179766) pattern is used in Scala to extend pre-existing classes with new methods, fields, and interfaces.
The main drawback it suffers is that every invocation of the implicit conversion involves object creation. This makes the pattern unsuitable for use in performance-critical code. In these situations it is common to remove use of the pattern and resort to using an object with static helper methods. In many cases, this is a simple mechanical transformation that could be performed by an optimizing compiler.
A secondary drawback is that the pattern is fairly verbose. It requires both a class definition and an implicit method definition. These definitions can occur separately, possibly causing confusion about the location of an extension class's conversion method or vice versa. In addition, both definitions must be documented.
Description
An "implicit class" must have a primary constructor with exactly one argument in its first parameter list. It may also include an additional implicit parameter list. Like case classes, an implicit class definition will add methods to its companion class, and define it if it hasn't already been defined. Only one method, "apply", is added to the companion object, in the same way as "apply" is added to a case class's companion object. Unlike with case classes, this "apply" method is declared implicit. This method will be referred to as the implicit conversion.
For example, a definition of the form:
implicit class RichString(s: String) extends Ordered[String] with RandomAccessSeq[Char] {
def r: java.util.Regex = ...
}
will be transformed by the compiler as follows:
class RichString(s: String) extends Ordered[String] with RandomAccessSeq[Char] {
def r: java.util.Regex = ...
}
object RichString extends Function1[String, RichString] {
implicit def apply(s: String): RichString = new RichString(s)
}
With implicit class definitions, the compiler may transform code that uses the implicit conversion in order to eliminate object creation, so long as the transformation preserves the semantics of the original program.
In addition, a class annotation "sreplace" (for "scalar replacement") would be added as part of the standard library. If an implicit class is annotated with @sreplace, the compiler must eliminate object creation as part of the implicit conversion or else emit an error. Nothing other than implicit classes may be annotated with @sreplace.
Specification
Syntax
No changes are required to Scala's syntax specification, as the relevant production rules already allow for implicit classes.
LocalModifier ::= ‘implicit’
BlockStat ::= {LocalModifier} TmplDef
TmplDef ::= [‘case’] ‘class’ ClassDef