15-0-M - Opening Talk - Martin Odersky

advertisement
Scala
- where are are
- where we plan to go
Martin Odersky
Welcome to ScalaDays!
• 155 attendees, coming from all corners of the planet.
• We are packed. Sadly, many more people could not be
admitted for lack of space.
• This shows the drive and energy of this community!
• The Scala team is looking forward to talk with you and
learn from you during the next two days.
• We are particularly glad to have you here at EPFL, the
place where Scala was born.
History (incomplete)
2001
2003
2004
2005
2006
2007
2008
2009
2010
Scala design begins, as a more practical
successor to Funnel.
First experimental release, first course
taught with it.
Scalable Component Abstractions paper.
Scala 2.0, written in Scala.
Industrial adoption starts.
First Lift release.
First Scala LiftOff, Twitter adopts Scala.
Big increase in adoption, IDEs mature.
First ScalaDays.
The main idea behind Scala
Scala is a Unifier
Agile, with lightweight syntax
Object-Oriented
Scala
Functional
Safe and performant, with strong static typing
The Philosophy behind Scala
Put productivity and creativity back in the hands of
developers.
“Joy is underrated as a metric for a language’s potential
success in a development organization.” a3lx@twitter
- address professional developers
- trust them & value their expertise
- (don’t tell them how they should do their job)
Some users in industry
Open Source Ecosystem
Many great projects, including:
lift
(David P. & friends)
akka
(Jonas B.)
kestrel, cachet, queroulous
(Twitter)
migrations
(Sony)
sbt
(Mark H.)
ScalaTest
(Bill V. & friends)
specs, ScalaCheck, ScalaModules, ScalaQL, ....
( the list goes on, many more tools & projects presented at
this conference )
Scala 2.8
named and default
parameters
copy operation
Now: 2.8
nested annotations
package objects
safer package nesting
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
First release candidate Scala 2.8 RC1 is out!
This is primarily a consolidating release
• Some new language features
• More complete libraries
• Redesigns of a few features that did not
work out well.
• Big improvements in tooling.
• Big improvements in stability.
• Laying the groundwork for the future.
Scala 2.8
Named and Default
Parameters
named and default
parameters
copy operation
nested annotations
package objects
def newTable(size: Int = 100, load: Float = 0.5f) =
safer package nesting
new HashMap[String, String]{
@specialized
new collection API
override val initialSize = size
vectors
override val loadFactor = (load * 1000).toInt
hash tries
new treatment of arrays
and strings
manifests
better implicits
}
}
newTable(50, 0.75f)
better type inference
newTable()
continuations
newTable(load = 0.5f)
packrat parsing
newTable(size = 20, load = 0.5f)
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
Defaults can be arbitrary expressions, not just
constants.
Default evaluation is dynamic.
Scala 2.8
named and default
parameters
copy operation
Copy Operation
nested annotations
package objects
safer package nesting
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
Problem: Case classes are great for pattern matching,
but how do you transform data?
Often need to update (functionally) some specific field(s)
of a date structure defined by case classes.
Solution: Selective copy method.
case class Tree[+T](elem: T,
left: Tree[T],
right: Tree[T])
def incElem(t: Tree[Int]) = t copy (elem = t.elem + 1)
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
Q: How to define “copy”?
Scala 2.8
Defining “copy”
named and default
parameters
copy operation
nested annotations
package objects
safer package nesting
@specialized
Problem: A class with n parameters allows 2n possible
combinations of parameters to copy.
Default parameters to the rescue.
new collection API
vectors
hash tries
new treatment of arrays
and strings
case class Tree[+T](elem: T,
left: Tree[T],
right: Tree[T]) {
// generated automatically:
manifests
def copy[U](elem: U = this.elem,
better implicits
better type inference
left: Tree[U] = this.left,
continuations
right: Tree[U] = this.right) =
packrat parsing
Branch(elem, left, right)
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
}
Scala 2.8
named and default
parameters
Nested Annotations
copy operation
nested annotations
package objects
•
safer package nesting
@specialized
new collection API
•
vectors
hash tries
new treatment of arrays
and strings
manifests
•
•
Scala 2.7 largely followed Java annotation syntax, but
left out some of the more convoluted constructions.
 Nested annotations were not possible.
Scala 2.8 throws out (deprecates) all special annotation
syntax.
Instead uses class constructors, which can have named
parameters.
This greatly simplifies the syntax, and allows all
annotations to be expressed, including nested ones.
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
@JoinTable(
joinColumns = Array(new JoinColumn(name = "a name“)
) var test: String = _
Scala 2.8
named and default
parameters
@specialized
copy operation
nested annotations
@specialized
new collection API
vectors
hash tries
Problem: Generics cause a performance hit because they
require a uniform representation: everything needs to be
boxed.
Example:
trait Function1[-T, +U] { def apply(x: T): U }
new treatment of arrays
and strings
def app(x: Int, fn: Int => Int) = fn(x)
package objects
safer package nesting
manifests
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
Translated
by scalac
2.7 to:
app(7, x => x * x)
trait Function1 {
def apply(x: Object): Object }
class anonfun extends Function1 {
def apply(x: Object): Object =
Int.box(apply(Int.unbox(x)))
def apply(x: Int): Int = x * x
}
new scaladoc
def app(x: Int, fn: Function1) =
Int.unbox(fn(Int.box(x)))
better REPL
app(7, new anonfun)
interactive compiler API
Scala 2.8
named and default
parameters
copy operation
nested annotations
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
package objects
safer package nesting
manifests
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
If Function1 is @specialized ...
trait Function1[@specialized -T, @specialized +U] {
def apply(x: T): U }
def app(x: Int, fn: Int => Int) = fn(x)
app(7, x => x * x)
... scalac 2.8 generates instead:
trait Function1 {
def apply(x: Object): Object
def apply$$II(x: Int): Int =
Int.unbox(apply(Int.box(x)))
// specializations for other primitive types
}
class anonfun extends (Int => Int) {
def apply(x: Object): Object =
Int.box(applyIntInt(Int.unbox(x)))
override def apply$$II(x: Int): Int = x * x
}
interactive compiler API
def app(x: Int, fn: Function1) = fn.apply$II(x)
new scaladoc
app(7, anonfun)
better REPL
Scala 2.8
named and default
parameters
copy operation
Scala Collections
nested annotations
package objects
safer package nesting
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
Collection Properties:
object-oriented
generic: List[T], Map[K, V]
optionally persistent, e.g.
collection.immutable.Seq
higher-order, with methods
such as foreach, map,
filter.
Uniform return type principle:
Operations return
collections of the same
type (constructor) as their
left operand.
scala> val ys = List(1, 2, 3)
ys: List[Int] = List(1, 2, 3)
scala> val xs: Seq[Int] = ys
xs: Seq[Int] = List(1, 2, 3)
scala> xs map (_ + 1)
res0: Seq[Int] = List(2, 3, 4)
scala> ys map (_ + 1)
res1: List[Int] = List(2, 3, 4)
Scala 2.8
named and default
parameters
copy operation
Old Collection Structure
nested annotations
package objects
safer package nesting
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
continuations
packrat parsing
trait Iterable[A] {
def filter(p: A => Boolean): Iterable[A] = ...
def partition(p: A => Boolean) =
(filter(p(_)), filter(!p(_)))
def map[B](f: A => B): Iterable[B] = ...
}
trait Seq[A] extends Iterable[A] {
def filter(p: A => Boolean): Seq[A] = ...
override def partition(p: A => Boolean) =
(filter(p(_)), filter(!p(_)))
def map[B](f: A => B): Seq[B] = ...
}
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
Types force duplication!
Scala 2.8
named and default
parameters
copy operation
New Collection API
nested annotations
package objects
safer package nesting
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
• Avoids type & code duplication through
– uniform framework of traversers and builders.
– supported by: implicits, higher-kinded types
• Uniform package organization reflects mutability:
– scala.collection
– scala.collection.mutable
– scala.collection.immutable
• Richer and more regular set of collection
operations.
• New collection implementations: vectors and hash
tries.
• More info: “Fighting bit rot with types”, FSTTCS09
Scala 2.8
named and default
parameters
Vectors and Hash Tries
copy operation
nested annotations
package objects
safer package nesting
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
•
•
•
•
•
Trees with branch factor of 32.
Persistent data structures with very efficient sequential
and random access.
Invented by Phil Bagwell, then adopted in Clojure.
New: Persistent prepend/append/update in constant
amortized time.
Next: Fast splits and joins for parallel transformations.
Scala 2.8
named and default
parameters
copy operation
Package Objects
nested annotations
package objects
safer package nesting
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
Motivation:
• The new collection design reshuffled a lot of
classes.
• For instance:
scala.List  scala.collection.immutable.List
• How can we keep the old aliases around?
• How can we migrate old to new?
• Easy: put
type List = scala.collection.immutable.List
val List = scala.collection.immutable.List
into the scala package.
• But how to we put a type alias and a val definition
into a package?
Scala 2.8
named and default
parameters
Package Objects
copy operation
nested annotations
package objects
safer package nesting
@specialized
new collection API
Problem: Everything has to live inside an object or class.
=> No top-level value definitions, type aliases,
implicits.
vectors
hash tries
new treatment of arrays
and strings
Package objects make packages more like objects.
They also let you define your own ``Predefs’’.
manifests
better implicits
better type inference
package object scala {
type List[+T] = scala.collection.immutable.List
continuations
packrat parsing
val List = scala.collection.immutable.List
faster actors
...
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
}
Scala 2.8
named and default
parameters
Safer Package Nesting
copy operation
nested annotations
package objects
safer package nesting
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
•
•
•
•
Java knows only absolute packages
But Scala’s packages nest
This can lead to an impedance mismatch.
For instance:
package net.liftweb
java.lang.System.print(“hello”)
• This used to fail if net contains a subpackage java.
• New rules: Intermediate packages only visible in
multiple package clauses.
• To access net.java as java, you’d need to write
package net
package liftweb
...
Scala 2.8
named and default
parameters
copy operation
New Treatment of Arrays
nested annotations
package objects
• Arrays were “magical” up to 2.8
safer package nesting
– sometimes primitive
– sometimes wrapped
– automatic boxing/unboxing conversions based
on static type.
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
•
•
•
•
This could be confusing and slow.
2.8 removes the magic.
Arrays are always Java arrays
Two implicit conversions make sure that
– arrays are compatible with sequences.
– arrays support all sequence operations
• Strings are treated similarly to arrays.
Scala 2.8
named and default
parameters
copy operation
Manifests
nested annotations
package objects
safer package nesting
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
• Question: How to create an Array[T] where T
is a type parameter?
• No magic allowed!
• Solution: supply the run-time type as a type
descriptor called a Manifest or ClassManifest:
def evens[T: ClassManifest](xs: Vector[T]): Array[T] = {
val arr = new Array[T]((xs.length + 1) / 2)
for (i <- 0 until xs.length by 2)
arr(i / 2) = xs(i)
arr
}
The first line is equivalent to:
def evens[T](xs: Vector[T])
(implicit ev: ClassManifest[T]): Array[T]
Scala 2.8
named and default
parameters
copy operation
nested annotations
package objects
safer package nesting
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
Better Implicits
Better Type Inference
• Type inference for implicits has been
refined.
• Previously: Infer type first, search implicit
for inferred type afterwards.
• Now: Implicit search can drive type
inference.
• This makes implicits more powerful.
• Other advance: Type constructors of
higher-kinded types can now be inferred.
Scala 2.8
named and default
parameters
copy operation
Delimited Continuations
nested annotations
package objects
safer package nesting
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
delimited continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
• Continuations capture the return stack as
a data structure.
• Delimited continuations capture only up to
some enclosing scope.
• Lost of advanced control structures can be
built on them, e.g:
–
–
–
–
coroutines
event-based I/O
reactive programming
lightweight actors
• Scala 2.8 supports delimited continuations
in a compiler plugin.
Scala 2.8
named and default
parameters
copy operation
Better IDEs
nested annotations
package objects
safer package nesting
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
• The Scala plugins for Eclipse, IntelliJ,
Netbeans all have matured a lot.
• The Eclipse and Netbeans plugins are
now based on completely redesigned
compiler interfaces for command
completion, semantic highlighting and
incremental building.
• If you have discounted IDEs before for
Scala, maybe now is the time to try again!
Scala 2.8
named and default
parameters
copy operation
Docs for Advanced Types
nested annotations
package objects
safer package nesting
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
Problem: Advanced statically typed APIs pose challenges for
presentation and documentation.
Scala 2.8
named and default
parameters
copy operation
Simpler Type Views
nested annotations
package objects
safer package nesting
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
• How to explain
def map[B, To](f: A => B)
(implicit cbf: CanBuildFrom[Coll, B, To]): To
to a beginner?
• Key observation: We can approximate the type of map.
• For everyone but the most expert user
def map[B](f: A => B): Traversable[B] // in class Traversable
def map[B](f: A => B): Seq[B]
// in class Seq, etc
is detailed enough.
• These types are correct, they are just not as general as
the type that’s actually implemented.
• These are documented in the new ScalaDoc as use
cases.
Scala 2.8
named and default
parameters
copy operation
nested annotations
package objects
safer package nesting
@specialized
new collection API
vectors
hash tries
new treatment of arrays
and strings
manifests
better implicits
better type inference
continuations
packrat parsing
faster actors
improved Swing support
better IDEs
interactive compiler API
new scaladoc
better REPL
New ScalaDoc
Why 2.8, not 3.0?
•
Scala 2.8 is numerically a point release, but feels like a major release.
•
So why did we not name it Scala 3.0?
•
2.8 has been 18 months in the making, and acquired more changes on the
way.
•
Originally, we just wanted to rewrite collections.
•
That took longer than expected.
•
Meanwhile, a lot more additions and changes got included.
•
But 2.8 was already announced, and referred to in books and other
documentation.
•
In light of this, we judged it too confusing to change the version number in
mid-flight.
And now...
...what’s next?
Next: Scala on .NET
• Work started again to have a native Scala compiler on
.NET with Visual Studio integration.
• Funded my Microsoft.
• Stay tuned...
Next: Reliability and Contracts
• Lost of things happening around contracts and
verification.
• Peter Müller: Scala verifier
• Viktor Kuncak: Scala code synthesis from constraints
• Our group: effects
• Common project: ProgLab.NET
Next: Concurrency
• Actor encapsulation
–
–
–
–
How to ensure that actors do not share memory?
Solved by capability-based uniqueness type system.
Implemented in compiler plugin.
Paper in ECOOP 2010.
• Software Transactional Memory
– CCSTM work in this conference
• Open question: What’s a good combination of actors and
transactions?
Next: Parallelism
• PPP Challenge: How to make use of multi-cores,
GPUs, clusters, clouds, to achieve better
performance for normal applications?
• First step in this direction: Parallel collections.
– will be integrated in the new collection API.
– based on persistent data structures with fast splits
and joins.
• Longer-term vision:
Embedded parallel DSLs.
• See keynote by
Kunle Olokutun tomorrow.
Next: The Green House
Great work on Scala is springing up
everywhere, no longer focussed
just at EPFL.
Q: How can we integrate contributions?
Tension: Want to get lots of exciting
new stuff contributed, yet maintain a
stable and reliable distribution.
Planned Solution: three-tiered:
Incubator
Hosts collaborative Scala
projects
Green house A “cutting edge” version of
the distribution with
experimental features.
Trunk
The stable distribution.
Thanks
• To the Scala team at EPFL:
Lukas Rytz, Hubert Plociniczak, Iulian Dragos, Miguel Garcia, Gilles
Dubochet, Philipp Haller, Aleksandar Prokopec, Antonio Cunei, Tiark Rompf,
Donna Malayeri, Phil Bagwell, Adriaan Moors, Ingo Maier.
• To our external committers and frequent contributors:
Paul Phillips, Miles Sabin, Ilya Sergey, Caoyuan Deng, James Matlik, Frank
Teubler, Kevin Wright, Manohar Jonnalagedda, Pedro Furlanetto, Johannes
Rudolph, Jason Zaugg, Seth Tisue, Ismael Juma, Mark Harrah, Colin Howe,
Mirko Stocker, Spiros Tzavellas, Matt Russell, David Taylor
• To the community at large for your support, suggestions,
encouragements.
Download