Stuff about programming
Scala quick reference.
Bookmark and Share

I've finally put together a quick summary of Scala's features to aid my own learning. I hope you find this useful too. The explanations are brief and links are given to online references to provide more detail when it is needed. I think there are already enough Scala code examples on the web that explain advanced features so I'll refrain from writing my own examples for now. This page will grow as I learn more exciting stuff about Scala!

Semicolons.

Semicolons are optional. So watch out for gotchas!

var and val.

A variable that is declared as a val is like a final variable in Java, that can be assigned to once and only once. A var can be assigned to any number of times.

Exceptions.

All exceptions are unchecked.

Case classes.

A case class can be used in pattern matching and so necessarily exposes the fields declared by its constructor. Often used just for this purpose.

Apply.

If an object o has an implementation of an apply method then it can be invoked with the syntax o(...) instead of o.apply(...). (It is a shame Java 8 didn't do this!)

Unapply.

An object that has an unapply function defines an extractor for pattern matching!

Companion object.

A class C can have a companion object with the same name C, which is a singleton, for defining static fields. (Since Scala doesn't have a static modifier like Java). Companion objects often implement a factory method with apply(...).

Call by name arguments.

The syntax for lazily evaluated arguments is: f (x : => T) ...

Right associative methods.

Normally a method is invoked with an argument on an object like this: o.m(a) In Scala, however, one can write o m a but when m is a symbolic name that ends with a colon, one can even write this: a m o See symbolic foldRight /: and Fibonacci example in Stream.class API docs.

Self types.

A trait or class that has self types is necessarily abstract and must be composed with instances of its self types to be instantiated. Self types are like a dependency list. See cake pattern, dependency injection in Scala. trait A { a : T1 with T2 with C => ... }

Implicits.

Implicits allow retroactive extension of libraries without changing their source code. The so called 'Pimp my library' pattern. Implicits also support OO type classes. See type classes. The implicit modifier can apply to objects, vals and defs. When the type of an implicit is a function type A => B then it defines a converter for an implicit conversion. An implicit conversion c : A => B converts a: A to c(a): B. If A doesn't have m but c(a).m is well-typed then a.m will resolve to c(a).m. An implicit parameter v:T that is not supplied by the caller, is automatically assigned to by Scala through searching the current implicit scope based on its type T. The implicit scope is simply the implicit definitions that are defined within the current scope through implicit declarations e.g. either imports, the current local scope or companion objects. implicitly[T] is equivalent to calling ? where, def ?[T](implicit v : T) = v That is, it retrieves the implicit value of type T from the current scope. An implicit parameter can also be an implicit converter (by convention of its type, a function type): def getIndex[T, CC](seq: CC, value: T)(implicit conv: CC => Seq[T]) = seq.indexOf(value) is equivalent to the 'view bound': def getIndex[T, CC <% Seq[T]](seq: CC, value: T) = seq.indexOf(value)

Context bound.

A type variable declared as [A:C] is the type of values a : A for which there exists a value c : C[A]. e.g. c contains a. This is useful, for example, to unify a type across different objects. See sessions example in 1.

Type members.

Type members are an alternative to type parameters. Dependent-path types access type members.

Dependent-path types.

If B is a type member of A and a: B then a.B is dependent on its enclosing instance a. Each dependent-path type is a singleton type. Each reference o has a conceptual type, that is a singleton type, o.type, through which a dependent-path type is accessed. i.e. a.B is really a.type.B. Useful for implementing e.g. families of objects or fine-grained access control. See 2 and 3.

Type projection

A type projection A#B is like the opposite of a dependent-path type selection a.B. i.e. an instance of B belonging to any instance of A and not necessarily this A.

Type classes.

In Haskell, a type class is a set of named functions that have generic types but which do not have implementations. (Kind of like a Java interface.) An instance of a type class provides the implementations of the function names, at specific types. When there are several instances then this is a form of overloading or 'adhoc polymorphism'. Scala type classes are implemented using implicits and type members. A simple example of a type class is a monoid with instances for addition and multiplication. Type classes allow 'type-level computation'. For example, Scala's type system can check duality between session types, in which the implicit witness is built on demand. See 1.

Higher kinds.

Higher kinded generics allows genericity over constructor types. For example, the generic type Container[X] in which Container is a type variable. Abstraction over the constructors leads to less code duplication. The collections API was refactored with these generics. e.g. CanBuildFrom. See 6 and 7.

Covariance and contravariance.

A type parameter A on a class declaration, C[A] can be prefixed with + or - as in C[+A] or C[-A] to indicate covariance or contravariance with respect to extensions of C. Covariant types can appear only in covariant positions i.e. as return types and contravariant types can appear only in contravariant positions e.g. as parameters. See 8

References.

1 Type Classes as Objects and Implicits. Bruno C. d. S. Oliveira, Adriaan Moors, Martin Odersky. 2010. 2 Foundations of Path-dependent types. Nada Amin, Tiark Rompf, Martin Odersky. 3 Family Polymorphism. Erik Ernst. 2001 4 Associated Type Synonyms, Manuel M. T. Chakravarty Gabriele Keller, Simon Peyton Jones. 2005. 5 Independently Extensible Solutions to the Expression Problem. Matthias Zenger, Martin Odersky. 2004. 6 Fighting Bit Rot with Types (Experience Report: Scala Collections) M. Odersky, A. Moors. 2009. 7 Generics of a Higher Kind. Adriaan Moors, Frank Piessens, K.U.Leuven, Martin Odersky. 2008 8 Remembering when to use covariant and contravariant types. Nicholas Nguyen

blog comments powered by Disqus
Website created by Nicholas Nguyen.