diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..ca35be08d4 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +_site diff --git a/_layouts/default.html b/_layouts/default.html index 96327ef0eb..aebc1663f4 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -52,12 +52,12 @@

{{ site.title }}

{% if page.title %}

{{ page.title }}

{% endif %} -
+
{{ content }} - {% if page.disqus == true %}#DISQUS!!#{% include disqus.txt %}{% endif %} + {% if page.disqus == true %}{% include disqus.txt %}{% endif %}
{% if page.type == 'sip' %} -
+
{% include allsids.txt %}
{% endif %} diff --git a/sips/draft/_posts/2011-10-12-implicit-classes.md b/sips/draft/_posts/2011-10-12-implicit-classes.md deleted file mode 100644 index 1b34e91b6f..0000000000 --- a/sips/draft/_posts/2011-10-12-implicit-classes.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -layout: default -type: sip -disqus: true -title: Implicit classes ---- - -This SIP is an embedded google document. - - diff --git a/sips/draft/_posts/2011-10-12-inline-classes.md b/sips/draft/_posts/2011-10-12-inline-classes.md deleted file mode 100644 index 83d6f0996e..0000000000 --- a/sips/draft/_posts/2011-10-12-inline-classes.md +++ /dev/null @@ -1,162 +0,0 @@ ---- -layout: default -type: sip -disqus: true -title: Inline classes ---- - -Note: Derived from [this google document](https://docs.google.com/document/d/1k-aGAGmbrDB-2pJ3uDPpHVKno6p-XbnkVHDc07zPrzQ/edit?hl=en_US) - -## Abstract ## - -A minimal language construct is proposed that allows for more concise use of the common "type trait" and "extension method" patterns in Scala. 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 extension method patter, sometimes called the Pimp My Library pattern is used in Scala to extend pre-existing classes with new methods, fields, and interfaces. -There is also another common ‘extension’ use case known as type traits or type classes (see `scala.math.Numeric`). Type classes offer an alternative to pure inheritance hierarchies that is very similar to the extension method pattern. - -The main drawback to both of these techniques is that they suffer the creation of an extra object at every invocation to gain the convenient syntax. This makes these useful patterns 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. - -This proposal outlines inline semantic changes - -## Description ## - -The compiler shall be adapted to be able to inline the instantiation and usage of methods of a class in an expression if an instance of the class does not escape the expression. This analysis occurs after all method inline expansion occurs. That is, if a method returns an instance of the class, but is marked for inlining and the class itself is marked for inlining, then the entire instantation can still be inlined if the class does not escape the expanded expression. - -For example, given the following class and object pairing: - -{% highlight scala %} -@inline -class Foo(x: Int) { - def plus(y: Int) = x + y - override def toString = "Foo("+x+")" -} -object Foo { - @inline final def apply(x: Int): Foo = new Foo(x) -} -{% endhighlight %} - -The following expressions could be inlined: - -{% highlight scala %} -new Foo(1) plus 2 -new Foo(1) toString -new Foo(3) plus (_: Int) -Foo(1) plus 2 -Foo(1).toString -Foo(3) plus (_: Int) -{% endhighlight %} - -And the following expressions would not be inlined: - -{% highlight scala %} -new Foo(1) -(x: Int) => new Foo(x) -Foo(_:Int) -{% endhighlight %} - -In the example : - -{% highlight scala %} -foo(1).toString -{% endhighlight %} - -the inliner would first expand the Foo.apply method call, making the expression: - -{% highlight scala %} -new Foo(1).toString -{% endhighlight %} - -Then during the inline class pass, the instance of Foo created is seen to not escape the the expression, and the entire call is inlined into equivalent code for: - -{% highlight scala %} -"Foo(" + 1 + ")" -{% endhighlight %} - -The suggested implementation is for the compiler to generate static methods for the Foo class and delegate to them on inlining, unless they are themselves inlined. This expression would actually be: - -{% highlight scala %} -Foo.methods$.toString(1) -{% endhighlight %} - -The goal of inling class is to remove the object instantiation, not necessarily remove the method call. However, an inlined class my also have its methods marked inline. In this case, an optional third pass of the inliner could attempt to remove any method calls after class inlining has been acheived. This allows expressions involving inlined classes to inline all code relating to a method, as opposed to delegating to static methods for the class. - -So given this class: - -{% highlight scala %} -@inline -class Foo(x: Int) { - @inline def plus(y: Int) = x + y -} -{% endhighlight %} - -and the expression: - -{% highlight scala %} -new Foo(1) plus 2 -{% endhighlight %} - -The compiler would eventually inline this into: - -{% highlight scala %} -1 + 2 -{% endhighlight %} - -Most likely, this third pass is uneeded for targetting the JVM and other backends. It is noted in the proposal in case the need does arrive. - -In addition to the new inlining optimisations, the `@inline` annotations will be modified to accept an error behavior in its constructor of `WARN`, `FAIL` or `SILENT` with the default being `WARN`. - -If a class or method marked `@inline` is unable to be inlined by the compiler, the compiler will take the following actions: -* If the error behavior is `WARN`, than a warning is issued at the point where inlining could not occur. Compilation proceeds. -* If the error behavior is `FAIL`, then an error is issued at the point where inlining could not occur. Compilation is halted. -* If the error behavior is `SILENT`, then no action is taken, and the class is treated normally. - -## Specification ## - -No known spec changes are required. The `@inline` annotation is considered an implementation optimisation. - -## Consequences ## - -The details of opimtizations are left to the compiler implementer, but some suggestions are envisioned to help achieve a common optimization strategy across the features in this proposal. Inlined classes could be implemented as follows: - -{% highlight scala %} -@inline final class Bar(x: Int, y: String) { - def foo(z: Double) = y + x + "-" + z -} -{% endhighlight %} - -would compile as follows: - -{% highlight scala %} -final class Bar(x: Int, y: String) { - def foo(z: Double) = Bar.methods$.foo(x,y,z) -} -object Bar { - object methods$ { - final def foo($t1: Int, $t2: String, $p1: Double) = - $t2 + $t1 + "-" + $p1 - } -} -{% endhighlight %} - -And the expression: - -{% highlight scala %} -new Bar(5, "Time-").foo(1.0) -{% endhighlight %} - -would compile to: - -{% highlight scala %} -Bar.methods$.foo(5, "Time-", 1.0) -{% endhighlight %} - -Allowing the JVM inliner to continue inlining the foo method. Since this optimisations are at the compiler’s disgresison, arbitrary constraints may be made on classes that can participate in inlining. The above suggestion of embedding ‘static’ methods for inlined classes rather than directly inlining is meant to strike a balance between generated code size and efficiency. It is the hope tha tthe JVM inliner will inline these static methods where it makes sense, but profiling alternatives will lead to a much better decision. - -### Requirements for inlined classes ### - -As a possible first implementation of inlined classes, the following requirements will be in place: -* classes may only have other `@inline` annotated classes for parents -* classes may only define methods, the exception being constructor arguments. diff --git a/sips/pending/_posts/2011-10-12-implicit-classes.md b/sips/pending/_posts/2011-10-12-implicit-classes.md new file mode 100644 index 0000000000..67bfbd790b --- /dev/null +++ b/sips/pending/_posts/2011-10-12-implicit-classes.md @@ -0,0 +1,83 @@ +--- +layout: default +type: sip +title: SIP-13 - Implicit classes +--- + +This SIP is based on [this pre-draft](https://docs.google.com/document/d/1k-aGAGmbrDB-2pJ3uDPpHVKno6p-XbnkVHDc07zPrzQ/edit?hl=en_US). + +Material adapted from [http://jorgeortiz85.github.com/ImplicitClassSIP.xhtml](http://jorgeortiz85.github.com/ImplicitClassSIP.xhtml) which is Copyright © 2009, Jorge Ortiz and David Hall + +## Abstract ## + +A new language construct is proposed to simplify the creation of classes which provide _extension methods_ to another type. + +## Description ## + +The `implicit` keyword will now be allowed as an annotation on classes. Classes annotated with the `implicit` keyword are refered to as _implicit classes_. + +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. An implicit class must be defined in a scope where method definitions are allowed (not at the top level). An implicit class is desugared into a class and implicit method pairing, where the implciit method mimics the constructor of the class. + +The generated implicit method will have the same name as the implicit class. This allows importing the implicit conversion using the name of the class, as one expects from other implicit definitions. +For example, a definition of the form: + +{% highlight scala %} +implicit class RichInt(n: Int) extends Ordered[Int] { + def min(m: Int): Int = if (n <= m) n else m + ... +} +{% endhighlight %} + +will be transformed by the compiler as follows: + +{% highlight scala %} +class RichInt(n: Int) extends Ordered[Int] { + def min(m: Int): Int = if (n <= m) n else m + ... +} +implicit final def RichInt(n: Int): RichInt = new RichInt(n) +{% endhighlight %} + +Annotations on `implicit` classes default to attaching to the generated class *and* the method. For example, + +{% highlight scala %} +@bar +implicit class Foo(n: Int) +{% endhighlight %} + +will desugar into: + +{% highlight scala %} +@bar implicit def Foo(n: Int): Foo = new Foo(n) +@bar class Foo(n:Int) +{% endhighlight %} + +The `annotation.target` annotations will be expanded to include a `genClass` and `method` annotation. This can be used to target annotations at just the generated class or the generated method of an implicit class. For example: + +{% highlight scala %} +@(bar @genClass) implicit class Foo(n: Int) +{% endhighlight %} + +will desugar into + +{% highlight scala %} +implicit def Foo(n: Int): Foo = new Foo(n) +@bar class Foo(n: Int) +{% endhighlight %} + + +## Specification ## + +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 + +The language specification (SLS 7.1) would be modified to allow the use of the implicit modifier for classes. A new section on Implicit Classes would describe the behavior of the construct. + +## Consequences ## + +The new syntax should not break existing code, and so remain source compatible with existing techniques. + + diff --git a/sips/pending/_posts/2011-10-13-uncluttering-control.md b/sips/pending/_posts/2011-10-13-uncluttering-control.md index cb4ca92c3c..12a6861e05 100644 --- a/sips/pending/_posts/2011-10-13-uncluttering-control.md +++ b/sips/pending/_posts/2011-10-13-uncluttering-control.md @@ -5,9 +5,16 @@ disqus: true title: SIP-12 Uncluttering Scala’s syntax for control structures. --- -__Motivation__: The more Scala code I write the more I get tripped up by the need to write conditions in if-then-else expressions and other control constructs in parentheses. I normally would not advocate syntax changes at this level, except that this has been the single syntax decision that feels worse for me the longer I use it. +__Martin Odersky__ -## Part 1: `if` ## +__first submitted 13 October 2011__ + + +## Motivation ## + +The more Scala code I write the more I get tripped up by the need to write conditions in if-then-else expressions and other control constructs in parentheses. I normally would not advocate syntax changes at this level, except that this has been the single syntax decision that feels worse for me the longer I use it. + +## Part 1: if ## Having to write parentheses is an unfortunate inheritance from C via Java. It makes code more cluttered than it could be. In C/C++/Java this was no big deal, but because Scala is much cleaner syntactically than these languages it starts to stick out like a sore thumb. This in particular because only one form of `if` comes with parentheses; if you use an if as a filter in a for expression or as a guard in a pattern, no parentheses are required. @@ -28,7 +35,7 @@ So, here is the proposal (for Scala 2.10): Once we have dealt with if, we should do the same thing with while, do-while and for. -## Part 2: `do-while` ## +## Part 2: do-while ## do-while is easy. Simply do the following: @@ -40,7 +47,7 @@ do-while is easy. Simply do the following: While loops and for loops are more tricky. -## Part 3: `while` ## +## Part 3: while ## For while loops: @@ -72,7 +79,7 @@ For while loops: 4. In Scala 2.12: Drop the restriction introduced in 2.10. Conditions in a `while-do` can now be arbitrary expressions including with parentheses at the outside. -## Part 4: `for` ## +## Part 4: for ## For-loops and for expressions can be handled similarly: @@ -117,3 +124,4 @@ The new syntax removes more cases than it introduces. It also removes several ha + diff --git a/sips/sip-list.md b/sips/sip-list.md index e5a0e6ff3c..e3cc2a995f 100644 --- a/sips/sip-list.md +++ b/sips/sip-list.md @@ -4,13 +4,6 @@ type: sip title: List of SIPs --- -### Draft SIPs ### -
    - {% for post in site.categories.draft %} -
  • {{ post.title }} ( {{ post.date | date: "%b %Y" }} )
  • - {% endfor %} -
- ### Completed SIPs ###
    {% for post in site.categories.completed %}