Terms
A type defined by providing several alternatives, each of which comes with its own constructor. It usually comes with a way to decompose the type through pattern matching. The concept is found in specification languages and functional programming languages. Algebraic data types can be emulated in Scala with case classes.
A branch of a match expression. It has the form “case
pattern => expression.” Another name for alternative is case.
An annotation appears in source code and is attached to some part of the syntax. Annotations are computer processable, so you can use them to effectively add an extension to Scala.
An anonymous class is a synthetic subclass generated by the Scala compiler from a new expression in which the class or trait name is followed by curly braces. The curly braces contains the body of the anonymous subclass, which may be empty. However, if the name following new refers to a trait or class that contains abstract members, these must be made concrete inside the curly braces that define the body of the anonymous subclass.
Another name for function literal.
You can apply a method, function, or closure to arguments, which means you invoke it on those arguments.
When a function is invoked, an argument is passed for each parameter of that function. The parameter is the variable that refers to the argument. The argument is the object passed at invocation time. In addition, applications can take (command line) arguments that show up in the Array[String]
passed to main methods of singleton objects.
You can assign an object to a variable. Afterwards, the variable will refer to the object.
Extra constructors defined inside the curly braces of the class definition, which look like method definitions named this, but with no result type.
One or more expressions and declarations surrounded by curly braces. When the block evaluates, all of its expressions and declarations are processed in order, and then the block returns the value of the last expression as its own value. Blocks are commonly used as the bodies of functions, for expressions, while
loops, and any other place where you want to group a number of statements together. More formally, a block is an encapsulation construct for which you can only see side effects and a result value. The curly braces in which you define a class or object do not, therefore, form a block, because fields and methods (which are defined inside those curly braces) are visible from the out- side. Such curly braces form a template.
A bound variable of an expression is a variable that’s both used and defined inside the expression. For instance, in the function literal expression (x: Int) => (x, y)
, both variables x
and y
are used, but only x
is bound, because it is defined in the expression as an Int
and the sole argument to the function described by the expression.
A parameter that is marked with a =>
in front of the parameter type, e.g., (x: => Int)
. The argument corresponding to a by-name parameter is evaluated not before the method is invoked, but each time the parameter is referenced by name inside the method. If a parameter is not by-name, it is by-value.
A parameter that is not marked with a =>
in front of the parameter type, e.g., (x: Int)
. The argument corresponding to a by-value parameter is evaluated before the method is invoked. By-value parameters contrast with by-name parameters.
Defined with the class
keyword, a class may either be abstract or concrete, and may be parameterized with types and values when instantiated. In new Array[String](2)
, the class being instantiated is Array
and the type of the value that results is Array[String]
. A class that takes type parameters is called a type constructor. A type can be said to have a class as well, as in: the class of type Array[String]
is Array
.
A function object that captures free variables, and is said to be “closed” over the variables visible at the time it is created.
A class that shares the same name with a singleton object defined in the same source file. The class is the singleton object’s companion class.
A singleton object that shares the same name with a class defined in the same source file. Companion objects and classes have access to each other’s private members. In addition, any implicit conversions defined in the companion object will be in scope anywhere the class is used.
A contravariant annotation can be applied to a type parameter of a class or trait by putting a minus sign (-) before the type parameter. The class or trait then subtypes contravariantly with—in the opposite direction as—the type annotated parameter. For example, Function1
is contravariant in its first type parameter, and so Function1[Any, Any]
is a subtype of Function1[String, Any]
.
A covariant annotation can be applied to a type parameter of a class or trait by putting a plus sign (+) before the type parameter. The class or trait then subtypes covariantly with—in the same direction as—the type annotated parameter. For example, List
is covariant in its type parameter, so List[String]
is a subtype of List[Any]
.
A way to write functions with multiple parameter lists. For instance def f(x: Int)(y: Int)
is a curried function with two parameter lists. A curried function is applied by passing several arguments lists, as in: f(3)(4)
. However, it is also possible to write a partial application of a curried function, such as f(3)
.
You can declare an abstract field, method, or type, which gives an entity a name but not an implementation. The key difference between declarations and definitions is that definitions establish an implementation for the named entity, declarations do not.
To define something in a Scala program is to give it a name and an implementation. You can define classes, traits, singleton objects, fields, methods, local functions, local variables, etc. Because definitions always involve some kind of implementation, abstract members are declared not defined.
A class is a direct subclass of its direct superclass.
The class from which a class or trait is immediately derived, the nearest class above it in its inheritance hierarchy. If a class Parent
is mentioned in a class Child
’s optional extends clause, then Parent
is the direct superclass of Child
. If a trait is mentioned in Child
’s extends clause, the trait’s direct superclass is the Child
’s direct superclass. If Child
has no extends clause, then AnyRef
is the direct superclass of Child
. If a class’s direct superclass takes type parameters, for example class Child
extends Parent[String]
, the direct superclass of Child
is still Parent
, not Parent[String]
. On the other hand, Parent[String]
would be the direct supertype of Child
. See supertype for more discussion of the distinction between class and type.
When used without qualification, equality is the relation between values expressed by ==
. See also reference equality.
An existential type includes references to type variables that are unknown. For example, Array[T] forSome { type T }
is an existential type. It is an array of T
, where T
is some completely unknown type. All that is assumed about T
is that it exists at all. This assumption is weak, but it means at least that an Array[T] forSome { type T }
is indeed an array and not a banana.
Any bit of Scala code that yields a result. You can also say that an expression evaluates to a result or results in a value.
An if
followed by a boolean expression in a for expression. In for(i <- 1 to 10; if i % 2 == 0)
, the filter is “if i % 2 == 0
”. The value to the right of the if
is the filter expression. Also known as a guard.
A filter expression is the boolean expression following an if
in a for expression. In for( i <- 1 to 10 ; if i % 2 == 0)
,the filter expression is “i % 2 == 0
”.
Scala supports first-class functions, which means you can express functions in function literal syntax, i.e., (x: Int) => x + 1
, and that functions can be represented by objects, which are called function values.
A for comprehension is a type of for expression that creates a new collection. For each iteration of the for
comprehension, the yield clause defines an element of the new collection. For example, for (i <- (0 until 2); j <- (2 until 4)) yield (i, j)
returns the collection Vector((0,2), (0,3), (1,2), (1,3))
.
A for expression is either a for loop, which iterates over one or more collections, or a for comprehension, which builds a new collection from the elements of one or more collections. A for
expression is built up of generators, filters, variable definitions, and (in the case of for comprehensions) a yield clause.
A for loop is a type of for expression that loops over one or more collections. Since for
loops return unit, they usually produce side-effects. For example, for (i <- 0 until 100) println(i)
prints the numbers 0 through 99.
A free variable of an expression is a variable that’s used inside the expression but not defined inside the expression. For instance, in the function literal expression (x: Int) => (x, y)
, both variables x
and y
are used, but only y
is a free variable, because it is not defined inside the expression.
A function can be invoked with a list of arguments to produce a result. A function has a parameter list, a body, and a result type. Functions that are members of a class, trait, or singleton object are called methods. Functions defined inside other functions are called local functions. Functions with the result type of Unit
are called procedures. Anonymous functions in source code are called function literals. At run time, function literals are instantiated into objects called function values.
A function with no name in Scala source code, specified with function literal syntax. For example, (x: Int, y: Int) => x + y
.
A function object that can be invoked just like any other function. A function value’s class extends one of the FunctionN
traits (e.g., Function0
, Function1
) from package scala
, and is usually expressed in source code via function literal syntax. A function value is “invoked” when its apply method is called. A function value that captures free variables is a closure.
The functional style of programming emphasizes functions and evaluation results and deemphasizes the order in which operations occur. The style is characterized by passing function values into looping methods, immutable data, methods with no side effects. It is the dominant paradigm of languages such as Haskell and Erlang, and contrasts with the imperative style.
A generator defines a named val and assigns to it a series of values in a for expression. For example, in for(i <- 1 to 10)
, the generator is “i <- 1 to 10
”. The value to the right of the <-
is the generator expression.
A generator expression generates a series of values in a for expression. For example, in for(i <- 1 to 10)
, the generator expression is “1 to 10
”.
A class that takes type parameters. For example, because scala.List
takes a type parameter, scala.List
is a generic class.
A trait that takes type parameters. For example, because trait scala.collection.Set
takes a type parameter, it is a generic trait.
See filter.
A function whose purpose is to provide a service to one or more other functions nearby. Helper functions are often implemented as local functions.
A helper function that’s a member of a class. Helper methods are often private.
An object is immutable if its value cannot be changed after it is created in any way visible to clients. Objects may or may not be immutable.
The imperative style of programming emphasizes careful sequencing of operations so that their effects happen in the right order. The style is characterized by iteration with loops, mutating data in place, and methods with side effects. It is the dominant paradigm of languages such as C, C++, C# and Java, and contrasts with the functional style.
When a variable is defined in Scala source code, you must initialize it with an object.
An instance, or class instance, is an object, a concept that exists only at run time.
To instantiate a class is to make a new object from the class, an action that happens only at run time.
Invariant is used in two ways. It can mean a property that always holds true when a data structure is well-formed. For example, it is an invariant of a sorted binary tree that each node is ordered before its right subnode, if it has a right subnode. Invariant is also sometimes used as a synonym for nonvariant: “class Array
is invariant in its type parameter.”
You can invoke a method, function, or closure on arguments, meaning its body will be executed with the specified arguments.
The JVM is the Java Virtual Machine, or runtime, that hosts a running Scala program.
1
, "One
", and (x: Int) => x + 1
are examples of literals. A literal is a shorthand way to describe an object, where the shorthand exactly mirrors the structure of the created object.
A local function is a def
defined inside a block. To contrast, a def
defined as a member of a class, trait, or singleton object is called a method.
A local variable is a val
or var
defined inside a block. Although similar to local variables, parameters to functions are not referred to as local variables, but simply as parameters or “variables” without the “local.”
A member is any named element of the template of a class, trait, or singleton object. A member may be accessed with the name of its owner, a dot, and its simple name. For example, top-level fields and methods defined in a class are members of that class. A trait defined inside a class is a member of its enclosing class. A type defined with the type keyword in a class is a member of that class. A class is a member of the package in which is it defined. By contrast, a local variable or local function is not a member of its surrounding block.
Actors communicate with each other by sending each other messages. Sending a message does not interrupt what the receiver is doing. The receiver can wait until it has finished its current activity and its invariants have been reestablished.
Meta-programming software is software whose input is itself software. Compilers are meta-programs, as are tools like scaladoc
. Meta-programming software is required in order to do anything with an annotation.
A method is a function that is a member of some class, trait, or singleton object.
Mixin is what a trait is called when it is being used in a mixin composition. In other words, in “trait Hat
,” Hat
is just a trait, but in “new Cat extends AnyRef with Hat
,” Hat
can be called a mixin. When used as a verb, “mix in” is two words. For example, you can mix traits _in_to classes or other traits.
The process of mixing traits into classes or other traits. Mixin composition differs from traditional multiple inheritance in that the type of the super reference is not known at the point the trait is defined, but rather is determined anew each time the trait is mixed into a class or other trait.
A keyword that qualifies a class, trait, field, or method definition in some way. For example, the private
modifier indicates that a class, trait, field, or method being defined is private.
The same expression can be assigned in multiple definitions if you use the syntax val v1, v2, v3 = exp
.
A type parameter of a class or trait is by default nonvariant. The class or trait then does not subtype when that parameter changes. For example, because class Array
is nonvariant in its type parameter, Array[String]
is neither a subtype nor a supertype of Array[Any]
.
In Scala, every operation is a method call. Methods may be invoked in operator notation, such as b + 2
, and when in that notation, +
is an operator.
Functions may take zero to many parameters. Each parameter has a name and a type. The distinction between parameters and arguments is that arguments refer to the actual objects passed when a function is invoked. Parameters are the variables that refer to those passed arguments.
A function that takes no parameters, which is de- fined without any empty parentheses. Invocations of parameterless functions may not supply parentheses. This supports the uniform access principle, which enables the def
to be changed into a val
without requiring a change to client code.
A parameterless method is a parameterless function that is a member of a class, trait, or singleton object.
A field defined as a class parameter.
A function that’s used in an expression and that misses some of its arguments. For instance, if function f
has type Int => Int => Int
, then f
and f(1)
are partially applied functions.
A type like swiss.cow.Food
. The swiss.cow
part is a path that forms a reference to an object. The meaning of the type is sensitive to the path you use to access it. The types swiss.cow.Food
and fish.Food
, for example, are different types.
In a match
expression alternative, a pattern follows each case
keyword and precedes either a pattern guard or the =>
symbol.
In a match
expression alternative, a pattern guard can follow a pattern. For example, in “case x if x % 2 == 0 => x + 1
”, the pattern guard is “if x % 2 == 0
”. A case with a pattern guard will only be selected if the pattern matches and the pattern guard yields true.
A predicate is a function with a Boolean
result type.
The main constructor of a class, which invokes a superclass constructor, if necessary, initializes fields to passed values, and executes any top-level code defined between the curly braces of the class. Fields are initialized only for value parameters not passed to the superclass constructor, except for any that are not used in the body of the class and can therefore be optimized away.
A procedure is a function with result type of Unit
, which is therefore executed solely for its side effects.
A variable may or may not be reassignable. A var
is reassignable while a val
is not.
A function is recursive if it calls itself. If the only place the function calls itself is the last expression of the function, then the function is tail recursive.
A reference is the Java abstraction of a pointer, which uniquely identifies an object that resides on the JVM’s heap. Reference type variables hold references to objects, because reference types (instances of AnyRef
) are implemented as Java objects that reside on the JVM’s heap. Value type variables, by contrast, may sometimes hold a reference (to a boxed wrapper type) and sometimes not (when the object is being represented as a primitive value). Speaking generally, a Scala variable refers to an object. The term “refers” is more abstract than “holds a reference.” If a variable of type scala.Int
is currently represented as a primitive Java int
value, then that variable still refers to the Int
object, but no reference is involved.
Reference equality means that two references identify the very same Java object. Reference equality can be determined, for reference types only, by calling eq
in AnyRef
. (In Java programs, reference equality can be determined using ==
on Java reference types.)
A reference type is a subclass of AnyRef
. Instances of reference types always reside on the JVM’s heap at run time.
A property of functions that are independent of temporal context and have no side effects. For a particular input, an invocation of a referentially transparent function can be replaced by its result without changing the program semantics.
A variable in a running Scala program always refers to some object. Even if that variable is assigned to null
, it conceptually refers to the Null
object. At runtime, an object may be implemented by a Java object or a value of a primitive type, but Scala allows programmers to think at a higher level of abstraction about their code as they imagine it running. See also reference.
A type formed by supplying a base type a number of members inside curly braces. The members in the curly braces refine the types that are present in the base type. For example, the type of “animal that eats grass” is Animal { type SuitableFood = Grass }
.
An expression in a Scala program yields a result. The result of every expression in Scala is an object.
A method’s result type is the type of the value that results from calling the method. (In Java, this concept is called the return type.)
A function in a Scala program returns
a value. You can call this value the result of the function. You can also say the function results in the value. The result of every function in Scala is an object.
The Java Virtual Machine, or JVM, that hosts a running Scala program. Runtime encompasses both the virtual machine, as defined by the Java Virtual Machine Specification, and the runtime libraries of the Java API and the standard Scala API. The phrase at run time (with a space between run and time) means when the program is running, and contrasts with compile time.
The type of an object at run time. To contrast, a static type is the type of an expression at compile time. Most runtime types are simply bare classes with no type parameters. For example, the runtime type of "Hi"
is String
, and the runtime type of (x: Int) => x + 1
is Function1
. Runtime types can be tested with isInstanceOf
.
A file containing top level definitions and statements, which can be run directly with scala
without explicitly compiling. A script must end in an expression, not a definition.
The value being matched on in a match
expression. For example, in “s match { case _ => }
”, the selector is s
.
A self type of a trait is the assumed type of this
, the receiver, to be used within the trait. Any concrete class that mixes in the trait must ensure that its type conforms to the trait’s self type. The most common use of self types is for dividing a large class into several traits (as described in Chapter 29 of Programming in Scala.
XML data is semi-structured. It is more structured than a flat binary file or text file, but it does not have the full structure of a programming language’s data structures.
You can serialize an object into a byte stream which can then be saved to files or transmitted over the network. You can later deserialize the byte stream, even on different computer, and obtain an object that is the same as the original serialized object.
A new declaration of a local variable shadows one of the same name in an enclosing scope.
Signature is short for type signature.
An object defined with the object keyword. Each singleton object has one and only one instance. A singleton object that shares its name with a class, and is defined in the same source file as that class, is that class’s companion object. The class is its companion class. A singleton object that doesn’t have a companion class is a standalone object.
A singleton object that has no companion class.
An expression, definition, or import, i.e., things that can go into a template or a block in Scala source code.
See type.
A refinement type where the refinements are for members not in the base type. For example, { def close(): Unit }
is a structural type, because the base type is AnyRef
, and AnyRef
does not have a member named close
.
A class is a subclass of all of its superclasses and supertraits.
A trait is a subtrait of all of its supertraits.
The Scala compiler will allow any of a type’s subtypes to be used as a substitute wherever that type is required. For classes and traits that take no type parameters, the subtype relationship mirrors the subclass relationship. For example, if class Cat
is a subclass of abstract class Animal
, and neither takes type parameters, type Cat
is a subtype of type Animal
. Likewise, if trait Apple
is a subtrait of trait Fruit
, and neither takes type parameters, type Apple
is a subtype of type Fruit
. For classes and traits that take type parameters, however, variance comes into play. For example, because abstract class List
is declared to be covariant in its lone type parameter (i.e., List
is declared List[+A]
), List[Cat]
is a subtype of List[Animal]
, and List[Apple]
a subtype of List[Fruit]
. These subtype relationships exist even though the class of each of these types is List
. By contrast, because Set
is not declared to be covariant in its type parameter (i.e., Set
is declared Set[A]
with no plus sign), Set[Cat]
is not a subtype of Set[Animal]
. A subtype should correctly implement the contracts of its supertypes, so that the Liskov Substitution Principle applies, but the compiler only verifies this property at the level of type checking.
A class’s superclasses include its direct superclass, its direct superclass’s direct superclass, and so on, all the way up to Any
.
A class’s or trait’s supertraits, if any, include all traits directly mixed into the class or trait or any of its superclasses, plus any supertraits of those traits.
A type is a supertype of all of its subtypes.
A synthetic class is generated automatically by the compiler rather than being written by hand by the programmer.
A function is tail recursive if the only place the function calls itself is the last operation of the function.
Target typing is a form of type inference that takes into account the type that’s expected. In nums.filter((x) => x > 0)
, for example, the Scala compiler infers type of x
to be the element type of nums
, because the filter
method invokes the function on each element of nums
.
A template is the body of a class, trait, or singleton object definition. It defines the type signature, behavior and initial state of the class, trait, or object.
A trait, which is defined with the trait
keyword, is like an abstract class that cannot take any value parameters and can be “mixed into” classes or other traits via the process known as mixin composition. When a trait is being mixed into a class or trait, it is called a mixin. A trait may be parameterized with one or more types. When parameterized with types, the trait constructs a type. For example, Set
is a trait that takes a single type parameter, whereas Set[Int]
is a type. Also, Set
is said to be “the trait of” type Set[Int]
.
Every variable and expression in a Scala program has a type that is known at compile time. A type restricts the possible values to which a variable can refer, or an expression can produce, at run time. A variable or expression’s type can also be referred to as a static type if necessary to differentiate it from an object’s runtime type. In other words, “type” by itself means static type. Type is distinct from class because a class that takes type parameters can construct many types. For example, List
is a class, but not a type. List[T]
is a type with a free type parameter. List[Int]
and List[String]
are also types (called ground types because they have no free type parameters). A type can have a “class” or “trait.” For example, the class of type List[Int]
is List
. The trait of type Set[String]
is Set
.
Some annotations are type constraints, meaning that they add additional limits, or constraints, on what values the type includes. For example, @positive
could be a type constraint on the type Int
, limiting the type of 32-bit integers down to those that are positive. Type constraints are not checked by the standard Scala compiler, but must instead be checked by an extra tool or by a compiler plugin.
A class or trait that takes type parameters.
A parameter to a generic class or generic method that must be filled in by a type. For example, class List
is defined as “class List[T] { . . .
”, and method identity
, a member of object Predef
, is defined as “def identity[T](x:T) = x
”. The T
in both cases is a type parameter.
A method’s type signature comprises its name, the number, order, and types of its parameters, if any, and its result type. The type signature of a class, trait, or singleton object comprises its name, the type signatures of all of its members and constructors, and its declared inheritance and mixin relations.
The uniform access principle states that variables and parameterless functions should be accessed using the same syntax. Scala supports this principle by not allowing parentheses to be placed at call sites of parameterless functions. As a result, a parameterless function definition can be changed to a val
, or vice versa, without affecting client code.
At the Scala level, objects can become unreachable, at which point the memory they occupy may be reclaimed by the runtime. Unreachable does not necessarily mean unreferenced. Reference types (instances of AnyRef
) are implemented as objects that reside on the JVM’s heap. When an instance of a reference type becomes unreachable, it indeed becomes unreferenced, and is available for garbage collection. Value types (instances of AnyVal
) are implemented as both primitive type values and as instances of Java wrapper types (such as java.lang.Integer
), which reside on the heap. Value type instances can be boxed (converted from a primitive value to a wrapper object) and unboxed (converted from a wrapper object to a primitive value) throughout the lifetime of the variables that refer to them. If a value type instance currently represented as a wrapper object on the JVM’s heap becomes unreachable, it indeed becomes unreferenced, and is available for garbage collection. But if a value type currently represented as a primitive value becomes unreachable, then it does not become unreferenced, because it does not exist as an object on the JVM’s heap at that point in time. The runtime may reclaim memory occupied by unreachable objects, but if an Int, for example, is implemented at run time by a primitive Java int that occupies some memory in the stack frame of an executing method, then the memory for that object is “reclaimed” when the stack frame is popped as the method completes. Memory for reference types, such as Strings
, may be reclaimed by the JVM’s garbage collector after they become unreachable.
See unreachable.
The result of any computation or expression in Scala is a value, and in Scala, every value is an object. The term value essentially means the image of an object in memory (on the JVM’s heap or stack).
A value type is any subclass of AnyVal
, such as Int
, Double
, or Unit
. This term has meaning at the level of Scala source code. At runtime, instances of value types that correspond to Java primitive types may be implemented in terms of primitive type values or instances of wrapper types, such as java.lang.Integer
. Over the lifetime of a value type instance, the runtime may transform it back and forth be- tween primitive and wrapper types (_i.e._, to box and unbox it).
A named entity that refers to an object. A variable is either a val
or a var
. Both val
s and var
s must be initialized when defined, but only var
s can be later reassigned to refer to a different object.
A type parameter of a class or trait can be marked with a variance annotation, either covariant (+) or contravariant (-). Such variance annotations indicate how subtyping works for a generic class or trait. For example, the generic class List
is covariant in its type parameter, and thus List[String]
is a subtype of List[Any]
. By default, i.e., absent a +
or -
annotation, type parameters are nonvariant.
An expression can yield a result. The yield
keyword designates the result of a for comprehension.