283x Filetype PDF File size 2.38 MB Source: homepage.cs.uiowa.edu
Symbolics Operators Import
-> Returns a two-element Map( 1 -> "A", 2 -> "B") +, -, *, /, % Arithmetics import java.awt._ // All classes under java.awt
tuple containing the key >, < ,<=, >=, ==, != Relational import java.io.File
and value (1).->(“A”) import java.io.File._ // Import all Fileʼ static methods
_ A placeholder, used in import com.xtech._ &&, ||, ! Logical import java.util.{Map, HashMap} // only the 2 classes
imports, function literals, case _ => value.toString &, |, ^, ~ Bitwise Narrow import:
etc. numbers.filter(_ < 0) (and, or, xor, inv) def doIt() = {
: Separator between def add(i: Int): Int = ... <<, >>, >>> Bitwise shift import java.math.BigDecimal.{ONE}
identifiers and type (left, right, unsigned right) println(ONE)
annotations. The operator “==” check the value equality on }
= Assignment. val one = “1” reference AND primitive type. Rename import:
import java.math.BigDecimal.{
=> Used in function literals numbers.filter(x => x < 0) ONE => _, ## // Exclude ONE
to separate the argument Rich Operation ZERO => JAVAZERO # // Rename it
! list from the function Scala provides “rich wrapper” around basic types via implicit }
body. conversions. println(JAVAZERO)
<- Used in for for (arg <- args) import statements are relative, not absolute. To
" comprehensions in Code Result create an absolute path, start with _root_
generator expressions. 0 max 5 5
<: Upper bounds (a subtype def apply[T <: U](x: T) 0 min 5 0 import _root_.scala.collectionsjcl._
of)Used in parameterized -2.7 abs 2.7 Packages
and abstract type
declarations to constrain -2.7 round -3L File names don’t have to match the type names,
the allowed types. 1.5 isInfinity false the package structure does not have to match the
<% View bounds( apply def m [A <% B](args): R (1.0 / 0) isInfinity true directory structure. So, you can define packages in
implicit convertion).Used = ... files independent of their “physical” location.
in parameterized and 4 to 6 Range(4,5,6) Traditional:
abstract type declarations "nick" capitalize “Nick”
to convert the type using package com.xtech.scala
view. "nicolas" drop 2 “colas” Nested:
>: Lower bounds (supertype def append[U >: T](x: U) Literals package com{
of)Used in parameterized = package scala { class A }
and abstract type Integer
declarations to constrain package util { class B } }
the allowed types. val dec = 31 Decimal Integer Tuples
# Refer to a type val ic: MyClass#myType val hex = 0XFF Hexa Integer
declaration nested in = ... val long = 31L Long (“l” or “L”) Are immutable and can contain different types of elements.
another type val nena = (99, "Luftballons",”1983”)
@ Marks an annotation. @deprecated def bad() = val little: Short = 367 Short println(nena._1)
ʻ Symbol val s = 'aSymbol val littler: Byte = 38 Byte println(nena._2) .... println(nena(0)) (not same Type in list)
def doIt(r: Symbol) Floating point
doIt(s); print(s.name) val double = 1.2345 Double _ Usage Summary
If a method takes 0 or one parameter you can drop val e = 1.234e4 Double (“e” or “E”) Curried functions
the dot and parentheses when calling the function. val float = 1.234F Float (“f” or “F”) def twice(op: Double => Double) (x: Double) = op(op(x))
Character and String twice(_ + 1) (5)
Variables val aChar = ʻDʼ Char res8: Double = 7.0
twice(x => x + 1)(5) // More verbose
Immutable (Final) val unicode = ʼ\u0043ʼ Unicode Char Existential types
val msg = "Hello, world!" val string = “string” String Labeling something that is unknown:
val msg: String = "Hello, world!" val s = “”” itʼs “you” “”” Raw String ( It’s “you” ) class Marshaller[T] { def marshall(t:T) = {println(t)} }
val big = new java.math.BigInteger("12345") new Marshaller[String]
Mutable Special character res1: Marshaller[String] = Marshaller@7896b1b8
var greets = "Hello, world!" Literal Meaning res1.isInstanceOf[Marshaller[_]]
var greets: String = "Hello, world!" \n line feed (\u000A) res4: Boolean = true
Lazy initialization \b backspace (\u0008) same as:
(only on Immutable) .isInstanceOf[T forSome {type T <: Marshaller[String]}]
object Demo { \t tab (\u0009) Function literals
lazy val x = { println("initializing x"); "done" } \f form feed (\u000C) someNumbers.filter(_ > 0)
} \r carriage return (\u000D)
Basic Types \” double quote (\u0022) Partially applied functions
\’ single quote (\u0027) def sum(a: Int, b: Int, c: Int) = a + b + c
Value Type Range val a = sum _
Byte 8-bit signed two’s complement integer \\ backslash (\u005C) a: (Int, Int, Int) => Int =
(-27 to 27 - 1, inclusive) val b = sum(1, _: Int, 3)
Short 16-bit signed two’s complement integer Boolean b: (Int) => Int =
15 15 val bool = true Boolean (true | false)
(-2 to 2 - 1, inclusive) b(2)
Int 32-bit signed two’s complement integer Check res10: Int = 6
31 31
(-2 to 2 - 1, inclusive) “abc”.isInstanceOf[String] Import statements
Long 64-bit signed two’s complement integer re0: Boolean = true import com.xtech.cf._
63 63
(-2 to 2 - 1, inclusive) Cast
Char 16-bit unsigned Unicode character Match expressions
16
(0 to 2 - 1, inclusive) 3.asInstanceOf[Double] case _ => “default value” // Default case value
String a sequence of Chars res0: Double = 3.0 Initialization
Float 32-bit IEEE 754 single-precision float Runtime Representation var age: Int = _ // age initialized to 0
Double 64-bit IEEE 754 double-precision float classOf[String]
Boolean true or false res7: java.lang.Class[String] = class java.lang.String Setter
Redefined a setter method:
def age_ = (a: Int) { if(girl) age = a - 5 else age = a }
nicolas.jorand@crossing-tech.com!!!!!!1/ 6!! ! ! ! ! ! v. 1.1
Class Hierachy Variance Actors
Covariance: Ability to accept sub-classes. import scala.actors._
Any “T <: Pet” or “+T” : (as T extends Pet) object SimpleActor extends Actor {
Equivalent to def act() {
java.long.Object Contra-variance: Ability to accept base classes for (i <- 1 to 5) {
“T >: Cat” or “-T” : (as T is superType of Cat) println("Do it!")
AnyVal AnyRef Traits Thread.sleep(1000)
A traits is like a java interface at the difference that it’s }
Unit Double ScalaObject possible to implements methods and fields on it. Traits can }
be reused into classes by mixing the trait to the class or by }
All java.* All scala.* extending it. To Start it:
Boolean Float ref. types ref. types Definition SimpleActor.start()
trait Saxo { To start a thread immediately use the utility method actor:
def play() { import scala.actors._
println("Nice sound!") val seriousActor2 = actor {
} for (i <- 1 to 5)
Helper for type Null } println("Do it!.")
inference Extends }
Nothing class Alto extends Saxo { Send message to Actor;
override def toString = "Alto" import scala.actors._
Definition } val echoActor = actor {
Simple class: class Instrument With while (true) {
class ChecksumAccumulator { receive {
private var sum = 0 class Baryton extends Instrument { case msg => println("received message: "+ msg)
def add(b: Byte): Unit = sum += b override def toString = "Baryton" }
} }
def checksum(): Int = ~(sum & 0xFF) + 1 val baryton = new Baryton() with Saxo }
} Ordered Traits To send a message:
Constructor echoActor ! “Hello”
The Ordered trait defines <, >, <=, and >= just by received message: hi there
The default constructor (primary constructor) is defined by implementing one method, compare.
the body class and parameters are listed after the class class Rational(n: Int, d: Int) extends Ordered[Rational]{ To use the current thread use self:
name. Other constructors (auxiliary constructor) are defined // ... self ! "hello"
by the function definition “this()”: def compare(that: Rational) = self.receive { case x => x }
class Rational(n: Int, d: Int) { (this.numer * that.denom) - (that.numer * this.denom) res6: Any = hello
require(d != 0) } self.receiveWithin(1000) { case x => x }
val numer: Int = n Mixing res7: Any = TIMEOUT
val denom: Int = d Change Scheduler:
def this(n: Int) = this(n, 1) // auxiliary constructor Once a trait is mixed into a class, you can alternatively call it Run it on the main Thread
} a mixin.Traits are a way to inherit from multiple class-like trait SingleThread extends Actor{
constructs, but they differ in important ways from the
To hide the constructor make it private: multiple inheritance present in many languages. With traits, override protected def scheduler() =
class Rational private(n: Int, d: Int) the method called is determined by a linearization of the ## new SingleThreadScheduler
Getter / Setter classes and traits that are mixed into a class. }
Linearization algorithm Run all actors in the Main thread:
Once a val or var is defined within a class the corresponding 1 Put the actual type of the instance as the first element. Scheduler.impl = new SingleThreadScheduler
accessor methods are generated. The generated methods
use the same privilege as the field. Thread reuse
Only the getter is generated in case of val. 2 Starting with the right most parent type and working
The methods don’t follow the JavaBean nomenclature. left,compute the linearization of each type, appending Writing an actor to use react instead of receive is
To generate JavaBean getter and setter add the annotation: its linearization to the cumulative linearization. (Ignore challenging, but pays off in performance. Because react
@scala.reflect.BeanProperty var level: Int = _ ScalaObject, AnyRef, and Any for now.) does not return, the calling actor’s call stack can be
discarded, freeing up the thread’s resources for a different
Abstract 3 Working from left to right, remove any type if it actor. At the extreme, if all of the actors of a program use
abstract class Document { appears again to the right of the current position. react, then they can be implemented on a single thread.
def footNotes: Array[String] // abstract method 4 Append ScalaObject, AnyRef, and Any. As empiric rule:
var nbOfPages : Int // abstract Field - Actors that are message-heavy are better implemented
class C1 {def m = List("C1")} with “while(true)/receive” (Hogging a thread).
type paper# // abstract type trait T1 extends C1 {override def m ={ "T1" :: super.m}} - Actors with non trivial work are better implemented with
} trait T2 extends C1 {override def m ={ "T2" :: super.m}} “loop/react”.
trait T3 extends C1 {override def m ={ "T3" :: super.m}} object NameResolver extends Actor {
Inheritance class C2 extends T2 {override def m ={ "C2" :: super.m}} import java.net.{InetAddress, UnknownHostException}
class A extends B class C extends C2 with T1 with T2 with T3{ def act() {
Call super constructor override def m ={ "C" :: super.m} react {
class A(param: String) extends B(param: String) } case (name: String, actor: Actor) =>
## actor ! getIp(name)
# Linearization Description ## act()
Singleton / Static 1 C + type of the instance. case "EXIT" => println("Exiting.") // quit
2 C, T3, C1, + farthest on the right (T3) case msg => println("Unhandled message: "+ msg)
Singleton objects are objects with only on instance 3 C, T3, C1, T2, C1 + T2 ## act()
in the whole JVM. 4 C, T3, C1, T2, C1, T1, C1 + T1 }
There is no static in Scala, instead use the companion 5 C, T3, C1, T2, C1, T1, C1, + C2 }
object to support class-level operation and properties. A C2, T2, C1 def getIp(name: String): Option[InetAddress] = {
companion is a singleton 6 C, T3, T2, T1, C2, T2, C1 - duplicates C1 but last try {
class Book private (title: String) 7 C, T3, T1, C2, T2, C1 - duplicates T2 but last Some(InetAddress.getByName(name))
object Book { 8 C, T3, T1, C2, T2, C1, done.
val favorites= """"Java Puzzlers", "Design Patterns"""" ScalaObject, AnyRef, Any }catch {
SelfType case _:UnknownHostException => None
def apply(title: String) = { }
Redefines the type of this. Must be a subclass of all the self }
println("Book construction ...");new Book(title) type of all its base class. }
} class Animal {this: Dog with Friend => ... }
def main(args: Array[String]){ ... }
}
printf("My favorites are : %s\n", Book.favorites)
My favorites are : "Java Puzzlers", "Design Patterns"
Book("Digital Fortress")
Book construction ...
res1: Book = Book@2012a961
nicolas.jorand@crossing-tech.com !! ! ! ! 2/ 6!! ! ! ! ! ! ! v 1.1
Collection TreeSet / TreeMap Lists sample
val ts = TreeSet(9, 3, 1, 8, 0, 2, 7, 4, 6, 5) val truth = "Fly" :: "is" :: "fun" :: Nil
Traversable scala.collection.immutable.SortedSet[Int] = FFrorom m TTraraveversarsabbllee ttraraiitt::
! Set(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) truth.foreach(print) Flyisfun
Iterable var tm = TreeMap(3 -> 'x', 1 -> 'x', 4 -> 'x') truth.head Fly
scala.collection.immutable.SortedMap[Int,Char] = truth.isEmpty false
! Map(1 -> x, 3 -> x, 4 -> x)
Map Set Seq List.unzip(zippedTruth) (List(0, 1, 2),
Enumeration List(Fly, is, fun))
SortedMap SortedSet BitSet Buffer Vector LinearSeq object Color extends Enumeration { List.flatten( List(f, l, y, .)
val Red, Green, Blue = Value List(List('f','l'),List('y'), List('.')))
} truth.count(s => s.length == 3) 2
The main trait is traversable, which is the supertrait of both Enumeration with value: truth.drop(2) List(fun)
mutable and immutable variations of sequences (Seq), sets, object Direction extends Enumeration { truth.exists(s => s == "is") true
and maps. Sequences are ordered collections, such as val Up = Value("goUp")
arrays and lists. Sets contain at most one of each object, as truth.filter(s => s.length == 3) List(Fly, fun)
determined by the == method. Maps contain a collection of val Down = Value("goDown") truth.forall(s => s.endsWith("y")) false
keys mapped to values. } truth.tail List(is, fun)
First try with immutable and switch to mutable only if Direction.Up.id truth.init List(Fly, is)
needed. res0: Int = 0 truth.last fun
JAVA <-> Scala Conversion Direction(1) truth.length 3
import scala.collection.JavaConversions._ res1: Direction.Value = goDown truth.map(s => s + "!") List(Fly!, is!, fun!)
Sets and Maps Lists truth.mkString(",") Fly,is,fun
Immutable Set (default if no explicit import): Class List provides fast access to the head of the list, but truth.remove(s => s.length == 3) List(is)
var jetSet = Set("Boeing", "Airbus") not the end. Thus, when you need to build a list by truth.reverse List(fun, is, Fly)
jetSet += "Lear" appending to the end, you should consider building the list truth.sort((s,t) List(fun, Fly, is)
backwards by prepending elements to the front, then when => s.charAt(0).toLowerCase
println(jetSet.contains("Cessna")) you’re done, calling reverse to get the elements in the order
Mutable Set: you need. < t.charAt(0).toLowerCase)
import scala.collection.mutable.Set Another alternative, which avoids the reverse operation, is truth.indices List(0, 1, 2)
val movieSet = Set("Hitch", "Poltergeist") to use a ListBuffer (see next section) truth.toArray Array(Fly, is, fun)
movieSet += "Shrek" Creation: truth flatMap (_.toList) List(F, l, y, i, s, f, u, n)
println(movieSet) val oneTwo = List(1, 2) truth partition (_.length == 2) ((List(is),List(Fly, fun))
Immutable Map (default if no explicit import): val threeFour = List(3, 4) truth find (_.charAt(0) == 'a') None
import scala.collection.immutable.HashMap val oneTwoThree = "one" :: "two" :: "three" :: Nil truth takeWhile List(Fly)
var hashMap = HashMap(1 -> "one", 2 -> "two") Concatenation (“:::”): (_.charAt(0).toLowerCase != 'i')
println(hashMap.get(1)) val oneTwoThreeFour = oneTwo ::: threeFour truth dropWhile List(is, fun)
Mutable Map: (_.charAt(0).toLowerCase != 'i')
import scala.collection.mutable.Map Prepends (“::” pronounced “cons”): truth forall (_.length > 2) false
val treasureMap = Map[Int, String]() val twoThreeFour = 2 :: threeFour truth exists (_.charAt(0) == 'i') true
treasureMap += (1 -> "Go to island.") Operation on List: truth.foldRight("!")(_ + _) Flyisfun!
treasureMap += (2 -> "Find big X on ground.") Basics: truth.reduceRight (_ + _) Flyisfun
treasureMap += (3 -> "Dig.") val nums = Set(1, 2, 3) truth.foldRight(List[String]()) List(, , )
println(treasureMap(2)) nums + 5 Set(1, 2, 3, 5) {(x, list) => ("<"+x+">") :: list}
Conversion immutable to mutable nums - 3 Set(1, 2) truth.foldLeft("Yes,")(_ + _) Yes,Flyisfun
import scala.collection.mutable nums ++ List(5, 6) Set(1, 2, 3, 5, 6) List(1,2,3) reduceLeft(_ + _) 6
var mutaSet = mutable.Set.empty ++ immutableSet nums -- List(1, 2) Set(3) List.range(9, 1, -3) List[Int] = List(9, 6, 3)
Conversion mutable to immutable nums & Set(1, 3, 5, 7) Set(1, 3) List.make(5, 'a') List(a, a, a, a, a)
val immu = Map.empty ++ muta nums.size 3 List.concat( List(b, c)
Map sample nums.contains(2) TRUE List(), List('b'), List('c'))
FFrorom m IItteerarabbllee ttraraiitts:s:
Immutable truth.dropRight(2) List(Fly)
val nums = Map("i" -> 1, "ii" -> 2) import scala.collection.mutable truth.takeRight(2) List(is, fun)
nums + ("vi" -> 6) Map(i -> 1, ii -> 2, vi -> 6) val words = mutable.Set.empty[String] truth.zipWithIndex List( (Fly,0), (is,1),
nums - "ii" Map(i -> 1) words += "thx" Set(thx) (fun,2) )
nums ++ Map(i -> 1, ii -> 2, iii -> 3, v -> 5) truth.indices zip truth List( (0,Fly), (1,is),
List("iii" -> 3, "v" -> 5) words -= "thx" Set() (2,fun) )
nums -- List("i", "ii") Map() words ++= List("α", "β", "γ") Set(!, ", #) truth.grouped(2) Iterator: List(Fly, is),
nums.size 2 words --= List("α", "β") Set(!) List(fun)
nums.contains("ii") true words.clear Set() truth.sliding(2) Iterator: List(Fly, is),
nums("ii") 2 List(is, fun)
ListBuffer truth.sameElements( true
nums.keys Iterator over the strings "i" and "ii" List("Fly", "is", "fun") )
nums.keySet Set(i, ii) List used to append values in an optimized way (see
nums.values Iterator over the integers 1 and 2 general remark of Lists) and to avoid stack overflow.
nums.isEmpty false val buf = new ListBuffer[Int]
buf += 1
Mutable buf += 2
val wd = scala.collection.mutable.Map.empty[String, Int] 3 +: buf
wd += ("one" -> 1) Map(one -> 1) buf.toList
wd -= "one" Map() List[Int] = List(3, 1, 2)
wd ++= Map(one -> 1, two -> 2, three -> 3)
List("one" -> 1,
"two" -> 2,
"three" -> 3)
wd --= Map(three -> 3)
List("one", "two")
wd.getOrElseUpdate return the value for the key ‘k’. If
(k, v) doesn’t exists update wd with the
mapping k->v and return v.
wd.transform( Map(one -> 2)
(s,i) => i + 1)
nicolas.jorand@crossing-tech.com!! ! ! ! ! 3/ 6!! ! ! ! ! ! v. 1.1
Queues Control Structures
Mutable and immutable first-in-first-out sequence. The only control structure are:
Immutable if, while, for, try, match
import scala.collection.immutable.Queue IF
val empty = new Queue[Int] println(if (!args.isEmpty) args(0) else "default.txt")
val has1 = empty.enqueue(1) while (imperative Style)
val has123 = has1.enqueue(List(2, 3)) var i = 0
val (element, has23) = has123.dequeue while (i < args.length) {
element: Int = 1 has23: scala.collection.immutable.Queue println(args(i))
[Int] = Queue(2,3) i += 1
Mutable }
import scala.collection.mutable.Queue FOR
val queue = new Queue[String] for (arg <- args) println(arg)
queue += "a" for (i <- 0 to 5) print(i) 012345
queue ++= List("b", "c") for (i <- 0 until 5) print(i) 01234
queue FILTERING
scala.collection.mutable.Queue[String] = Queue(a, b, c) for ( file <- filesHere
queue.dequeue if file.isFile;
res0: String = a if file.getName.endsWith(".scala")
queue ) println(file)
res1: scala.collection.mutable.Queue[String] = Queue(b, c)
Stacks If you add more than one filter on a generator, the
Mutable and immutable last-in-first-out sequence. filter’s if clauses must be separated by semicolons.
This is why there’s a semicolon after the
Mutable “if file.isFile”
import scala.collection.mutable.Stack NESTED
val stack = new Stack[Int] def fileLines(file: java.io.File) =
stack.push(1) scala.io.Source.fromFile(file).getLines.toList
stack.push(2) def grep(pattern: String) =
stack.top for (
res0: Int = 2 file <- filesHere
stack if file.getName.endsWith(".scala"); // <-- semi-colon
res1: scala.collection.mutable.Stack[Int] = Stack(1, 2) line <- fileLines(file)
stack.pop trimmed = line.trim // Mid-stream variable bindings
res2: Int = 2 if trimmed.matches(pattern)
stack ) println(file +": "+ trimmed)
res3: scala.collection.mutable.Stack[Int] = Stack(1) grep(".*gcd.*")
Arrays Return new collection:
Creation: for clauses yield body
val greetStrings: Array[String] = new Array[String](3) Generates a collection with elements of each iteration.
val greetStrings = new Array[String](3) var validUsers = for {
val greetStrings = Array("Hello",”,”,” world!\n”) user ## <- newUserProfiles
Access: userName # <- user get "userName"
greets(0) = "Hello" or greets.update(0, "Hello") name # <- user get "name"
greets(1) = ", " email## <- user get "email"
greets(2) = "world!\n" bio## <- user get "bio"
for (i <- 0 to 2) print(greets(i)) } yield new User(userName, name, email, bio)
explode array try { TRY
def max(values: Int*) = values.foreach(print) val f = new FileReader("input.txt") // Use and close file
max(Array(1,2,3,4,5): _*) // ʻ:_*ʼ tell compiler to pass } catch {
12345 each elements case ex: FileNotFoundException => // missing file
ArrayBuffer case ex: IOException => // Handle other I/O error
}
An ArrayBuffer is like an array, except that you can FINALLY
additionally add and remove elements from the beginning
and end of the sequence. Used only to close opened resources.
import scala.collection.mutable.ArrayBuffer val file = new FileReader("input.txt")
val buf = new ArrayBuffer[Int]() try {
buf += 1 // Use the file
buf += 2 } finally {
file.close() // Be sure to close the file
}
firstArg match { MATCH
case "salt" # => println("pepper")
case "chips" # => println("salsa")
case "eggs" # => println("bacon")
case _ # => println("huh?")
}
FOREACH
(functional Style to print Main Args):
args.foreach((arg: String) => println(arg))
args.foreach(arg => println(arg))
args.foreach(println)
nicolas.jorand@crossing-tech.com !!!!! 4/ 6!! ! ! ! ! ! v 1.1
no reviews yet
Please Login to review.