Rust, Swift, Scala

grammar and invocation | variables and expressions | arithmetic and logic | strings | dates and time | fixed-length arrays | resizable arrays | lists | tuples | dictionaries | functions | execution control | exceptions | concurrency | file handles | files | directories | processes and environment | libraries and namespaces | user-defined types | objects | inheritance and polymorphism | unit tests | debugging and profiling | repl

rust swift scala
version used
 
1.13 2.1 2.11
show version
 
$ rustc --version $ swift --version $ scala -version
implicit prologue none import Foundation none; but these libraries always available:

  java.lang
  scala

as are methods in Predef
grammar and invocation
rust swift scala
interpreter
 
none none $ echo 'println("hello")' > Hello.scala

$ scala hello.scala
compiler $ cat hello.rs
fn main() {
  println!("Hello, world!");
}

$ rustc hello.rs

$ ./hello
Hello, world!
$ cat hello.swift
print("Hello, World!")

$ swift hello.swift

$ ./hello
Hello, World!
$ cat hello.scala
object Hello {
  def main(args: Array[String]) {
    println("Hello, World!")
  }
}

$ scalac Hello.scala
$ scala Hello
statement terminator ;

Newlines are not statement terminators; they are permitted wherever spaces or tabs are permitted to separate tokens.
; or sometimes newline

A newline does not terminate a statement when:
  (1) inside [ ] of an array literal,
  (2) inside of ( ) parens,
  (3) after a binary operator,
  (4) other situations?
; or sometimes newline

A newline does not terminate a statement:
  (1) inside ( ) or [ ],
  (2) if the preceding line is not a complete statement,
  (3) if following token not legal at start of a statement.
block delimiters
 
{ } { } { }
end-of-line comment
 
// comment // comment // comment
multiple line comment
 
/* comment line
/* nested comment */
*/
/* comment line
/* nested comment */
*/
/* comment line
/* nested comment */
*/
variables and expressions
rust swift scala
write-once variable
 
let pi: f64 = 3.14; let Pi = 3.14 // evaluates 1 + p immediately:
val n = 1 + p

// evaluated first time n is accessed:
lazy val n = 1 + p
modifiable variable let mut n: i32 = 3;
n += 1;
var n = 3
n += 1
var n = 3
n += 1

// evaluates 1 + 2 each time n is used:
def n = 1 + 2
assignment let mut i: i32 = 0;

// compiler warns if assignment value not used
i = 3;
var i = 0

i = 3
parallel assignment // only in variable definition:
let (m, n) = (3, 7);
var (m, n) = (3, 7) val (m, n) = (3, 7)
swap let tmp;
tmp = x;
x = y;
y = tmp;
(x, y) = (y, x)
compound assignment arithmetic:
+= -= *= /= %=

string:
+=
arithmetic:
+= -= *= /= %=

string:
+=

bit:
<<= >>= &= |= ^=
arithmetic:
+= -= *= /= %=

string:
none

bit:
<<= >>= &= |= ^=
unit type and value ()
()
Void
()
Unit
()
conditional expression if x > 0 { x } else { -x } x > 0 ? x : -x val n = -3
if (n < 0) -n else n
branch type mismatch // does not compile:
if true { "hello" } else { 3 }
// syntax error:
true ? "hello" : 3
// expression has type Any:
if (true) { "hello" } else { 3 }
null
 
// Option types only:
None
// option types only:
nil
null
nullable type let a: Vec<Option<i32>> =
  vec![Some(3_i32), None, Some(-4_i32)];
val a = List(Some(3), null, Some(-4))
null test let a = vec![Some(1_i32), None];

match a[0] {
  None => println!("a[0] is none"),
  Some(i) => println!("a[0]: {}", i),
}

// simple comparison also works:
if a[1] == None {
  println!("a[1] is none");
}
coalesce let a = vec![Some(1_i32), None];
let i: i32 = a[1].unwrap_or(0_i32);
nullif
expression type declaration 1: Double
arithmetic and logic
rust swift scala
boolean type
 
bool Bool Boolean
true and false
 
true false true false true false
falsehoods false false false
logical operators && || !

&& and || are short-circuit operators.
&& || ! && || !
relational operators == != < > <= >= == != < > <= >= == != < > <= >=
min and max math.min 1 2
math.max 1 2
integer type i8
i16
i32
i64
Int8
Int16
Int32 (Int)
Int64
type of integer literals:
Int
other modular types:
Byte Short Long
arbitrary precision type:
BigInt
unsigned integer type u8
u16
u32
u64
UInt8
UInt16
UInt32
UInt64 (UInt)
integer literal -4

// specify size:
-4_i32
-4
float type f32
f64
Float
Double
type of float literals:
Double
other types:
Float
arithmetic operators + - * / % + - * / % + - * / %
add integer and float let n: i32 = 3;
let x = n as f64;
let y = x + 0.5;
3 + 7.0
integer division
and remainder
7 / 3
7 % 3
7 / 3
7 % 3
7 / 3
7 % 3
integer division by zero runtime error process sent a SIGILL signal java.lang.ArithmeticException
float division
 
7_f64 / 3_f64 Double(7) / 3 (7: Double) / 3
float division by zero // these are float values but not literals:
inf, Nan, or -inf
// these are float values but not literals:
+Inf, NaN, or -Inf
evaluates to Infinity, NaN, or -Infinity, values which do not have literals
power let n = 2_i64.pow(32_u32);
let x1 = 3.14_f64.powi(32_i32);
let x2 = 3.14_f64.powf(3.5_f64);
pow(2.0, 32.0) math.pow(2, 32)
sqrt
 
let x = 2_f64.sqrt(); sqrt(2.0) math.sqrt(2)
sqrt -1 let x = (-1_f64).sqrt();

// No negative literals and unary negation has lower
// precedence that a method, so this is -1:

let y = -1_f64.sqrt();
// NaN:
sqrt(-1)
math.sqrt(-1) evaluates to NaN, a value which has no literal
transcendental functions let x = 0.5_f64;

x.exp() x.ln() x.log2() x.log10()
x.sin() x.cos() x.tan()
x.asin() x.acos() x.atan()
x.atan2(3.1_f64)
exp log log2 log10
sin cos tan
asin acos atan
atan2
math.exp math.log
math.sin math.cos math.tan
math.asin math.acos math.atan math.atan2
transcendental constants std::f64::consts::PI
std::f64::consts::E
math.Pi
math.E
float truncation 3.77_f64.trunc()
3.77_f64.round()
3.77_f64.floor()
3.77_f64.ceil()
Int(3.77)
Int(round(3.77))
Int(floor(3.77))
Int(ceil(3.77))
??
3.14.round
3.14.floor returns Double
3.14.ceil returns Double
absolute value
and signum
-7_i32.abs()
-7.1_f64.abs()
-7_i32.signum()
-7.1_f64.signum()
abs(-7)
fabs(-7.77)
math.abs(-7)
math.signum(-7)
integer overflow panic modular arithmetic for all types except BigInt
float overflow evaluates to std::f32::INFINITY or std::f64::INFINITY evaluates to Infinity, a value which has no literal
arbitrary length integer val n = BigInt(7)
val m = BigInt(12)
arbitrary length integer operators n + m
n - m
n * m
n / m
n % m

n == m
n < m
n < m
n <= m
n >= m
random number
uniform int, uniform float, normal float
use std::rand;

let n = rand::random::<uint>() % 100u;
let x = rand::random::<f64>();
??
let i = rand()
??
import scala.util.Random

val rnd = Random

rnd.nextInt(100)
rnd.nextDouble
rnd.nextGaussian
random seed
set, get, restore
srand(17) import scala.util.Random

val rnd = Random

rnd.setSeed(17)
none
none
bit operators << >> & | ^ ! << >> & | ^ ~ 1 << 4
1 >> 4
1 & 3
1 | 3
1 ^ 3
~ 1
binary, octal, and hex literals 0b101010
0o52
0x21
none
052
0x2a
radix Integer.toString(42, 7)
Integer.parseInt("60", 7)
strings
rust swift scala
string type
 
String

string reference:
&str
String java.lang.String
string literal
 
let s: &str = "don't say \"no\"";
let s2: String = "don't say \"no\"".to_string();
"hello" "Hello, World!"

"""Hello, World!"""
newline in literal let s: &str = "first line
second line";

// foobar:
let s2: &str = "foo\
  bar";
no in triple quote literal only
literal escapes \0 \\ \t \n \r \" \\
\xhh \uhhhh \Uhhhhhhhh
\0 \\ \t \n \r \" \'
\xhh \uhhhh \Uhhhhhhhh
\b \f \n \r \t \" \'
\uhhhh \o \oo \ooo
format string let s = format!("foo {} {} {}", "bar", 7, 3.14_f32); let n = 3, m = 5
let msg = "\(n) + \(m) is \(n + m)"
"foo %s %d %.2f".format("bar", 7, 3.1415)

val n = 3
val m = 5
val msg = s"$n + $m is ${n + m}"
concatenate
 
let s1: String = "hello".to_string();
let s2: &str = " world";
let s: String = s1 + s2;
"hello" + " world" "Hello" + ", " + "World!"
replicate
 
let ch: Character = "-"
let hbar = String(count: 80, repeatedValue: ch)
val hbar = "-" * 80
translate case
to upper, to lower
s.to_uppercase()
s.to_lowercase()
let s = "hello"
let s2 = s.uppercaseString

let s3 = "HELLO"
let s4 = s3.lowercaseString
"hello".toUpperCase
"HELLO".toLowerCase
capitalize
 
"hello".capitalize
trim
both sides, left, right
" hello ".trim
pad
on left, on right
??
"hello".padTo(10, " ").mkString
number to string let n = String(17)
let x = String(17.3)
"two: " + 2.toString
"pi: " + 3.14.toString
string to number let n = "12".parse::<i32>().unwrap();
let x = ".037".parse::<f64>().unwrap();

// parse() returns an Option type.
// unrwap() panics if parse() returns None.
"17".toInt()

// evaluates to nil:
"17foo".toInt()

// convert to float?
7 + "12".toInt
73.9 + ".037".toFloat
raises NumberFormatException if string doesn't completely parse
join
 
List("do", "re", "mi").mkString(" ")
split
 
"do re mi".split(" ")
character type
 
Character Char
character literal 'h'
length
 
countElements("hello") "hello".length
index of substring "hello".indexOf("hell")
extract substring "hello".substring(0, 4)
extract character "hello"(0)
chr and ord 'a'.toInt
97.toChar
dates and time
rust swift scala
date and time types extern crate chrono;

chrono::DateTime
java.util.Date
current date and time extern crate chrono;

let dt = Local::now();
let dt_utc = UTC::now();
import java.util.Date

val dt = new Date()
current unix epoch extern crate chrono;

let dt = UTC::now();
let t = dt.timestamp();
dt.getTime / 1000
to unix epoch, from unix epoch extern crate chrono;

let t = dt.timestamp();
let dt2 = chrono::NaiveDateTime::from_timestamp(t, 0);
dt.getTime / 1000

val dt2 = new Date(1451600610 * 1000)
format date dt.format("%Y-%m-%d %H:%M:%S") import java.text.SimpleDateFormat

val fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val s = fmt.format(dt)
parse date import java.text.SimpleDateFormat

val fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val dt = fmt.parse("2011-05-03 17:00:00")
date subtraction // difference in milliseconds as Long:
dt2.getTime - dt.getTime
add duration // add one day:
val dt2 = new Date(dt.getTime + 86400 * 1000)
date parts import java.util.Date
import java.util.Calendar
import java.util.GregorianCalendar

al cal = new GregorianCalendar
cal.setTime(new Date)

cal.get(Calendar.YEAR)
cal.get(Calendar.MONTH) + 1
cal.get(Calendar.DAY_OF_MONTH)
time parts import java.util.Date
import java.util.Calendar
import java.util.GregorianCalendar

al cal = new GregorianCalendar
cal.setTime(new Date)

cal.get(Calendar.HOUR_OF_DAY)
cal.get(Calendar.MINUTE)
cal.get(Calendar.SECOND)
build broken-down datetime import java.util.GregorianCalendar

val cal = new GregorianCalendar(2015, 12, 31, 23, 59, 59)
val dt = cal.getTime
fixed-length arrays
rust swift scala
literal let nums = [1i32, 2i32, 3i32]; val a = Array(1, 2, 3)
size a.size
lookup nums[0] val n = a(0)
update let mut nums = [1i32, 2i32, 3i32];

a[2] = 4;
a(2) = 4
out-of-bounds compilation error raises java.lang.ArrayIndexOutOfBounds
resizable arrays
rust swift scala
declare let mut a = Vec::new();
let mut a2: Vec<i32> = Vec::new();
let a: Array<Int> = []
let a2: Int[] = []
literal let mut a = vec![1, 2, 3]; // array is mutable; variable is not:
let a = [1, 2, 3]
import scala.collection.mutable.ArrayBuffer

val a = ArrayBuffer(1, 2, 3)
size a.len() a.count a.length
lookup a[0] a[0] a(0)
update a[0] = 4; a[0] = 4 a(0) = 4
out-of-bounds let mut a = vec![1, 2, 3];

// thread panics:
let n = a[7];

// returns None:
let n = a.get(7);
raises SIGILL raises java.lang.ArrayIndexOutOfBoundsException
element index a.indexOf(3)
slice var a = ["a", "b", "c", "d", "e"]

// ["c", "d"]:
a[2...3]
a[2..4]
val a = ArrayBuffer("a", "b", "c", "d", "e")

// ArrayBuffer("c", "d"):
a.slice(2, 4)
slice to end // ArrayBuffer("c", "d", "e"):
a.drop(2)
manipulate back let mut a: Vec<i32> = vec![1, 2, 3];
a.push(4);
let n = a.pop();
let a = [1, 2, 3]
a.append(4)
// sets num to 4:
let num = a.removeLast()
// two ways to append:
a.append(4)
a += 4

// inspect last item:
val x = a.last

// pop last item:
val y = a.remove(a.length - 1)
manipulate front let a = [1, 2, 3]
a.insert(0, atIndex: 0)
// sets num to 0:
let num = a.removeAtIndex(0)
val a = ArrayBuffer(7, 8, 9)

a.insert(0, 6)

// inspect first element:
val x = a.first

// pop first element:
val y = a.remove(0)
concatenate let a = [1, 2, 3]
a += [4, 5, 6]

let a3 = [1, 2, 3] + [4, 5, 6]
val a1 = ArrayBuffer(1, 2, 3)
val a2 = ArrayBuffer(4, 5, 6)

// new ArrayBuffer:
val a2 = a1 ++ a2

// add elements to a1:
a1 ++= a2
copy let a: Vec<i32> = vec![1, 2, 3];
let mut a2 = a.clone();
// a[0] does not change:
a2[0] = 4;
let a = [1, 2, 3]

let a2 = a
// also modifies a[0]:
a2[0] = 4

a3 = Array(a)
// a[0] remains 4:
a3[0] = 5
val a = ArrayBuffer(1, 2, 3)
val a2 = ArrayBuffer[Int]()
a2 ++= a
iterate over elements let a: Vec<i32> = vec![1, 2, 3];
for i in a {
  println!("i: {}", i);
}
for (n <- a)
  println(n)
iterate over indices and elements for ((n, i) <- a.zipWithIndex) {
  println(s"item: $n is at: $i")
}
reverse let mut a: Vec<i32> = vec![1, 2, 3];
a.reverse();
let a = [1, 2, 3]
let a2 = a.reverse()
val a2 = a.reverse
sort let mut a: Vec<i32> = vec![3, 1, 4, 2];
a.sort();
let a = [1, 3, 2, 4]

// modifies a in-place and returns it:
sort(a)
val a = ArrayBuffer(3, 1, 4, 2)
val a2 = a.sortWith(_ < _)
dedupe ArrayBuffer(1, 2, 3, 3).distinct

// scala.collection.immutable.Set[Int]:
val set = a.toSet
membership if a.contains(&7) {
  println!("contains 7");
}
ArrayBuffer(1, 2, 3).contains(7)
intersection val a1 = ArrayBuffer(1, 2)
val a2 = ArrayBuffer(2, 3, 4)
// multiset intersection:
a1.intersect(a2)
union val a1 = ArrayBuffer(1, 2)
val a2 = ArrayBuffer(2, 3, 4)
// multiset union:
a1.union(a2)
relative complement val a1 = ArrayBuffer(1, 2)
val a2 = ArrayBuffer(2, 3, 4)
// multiset difference:
a1.diff(a2)
map a.map(x => x * x)
filter a.filter(_ > 2)
fold left // -6:
ArrayBuffer(1, 2, 3).foldLeft(0)(_ - _)
fold right // -2:
ArrayBuffer(1, 2, 3).foldRight(0)(_ - _)
shuffle val rand = scala.util.Random
val a = rand.shuffle(ArrayBuffer(1, 2, 3, 4))
flatten val a = ArrayBuffer(ArrayBuffer(1, 2), ArrayBuffer(3, 4))
val a2 = a.flatten
zip ArrayBuffer(1, 2, 3).zip(ArrayBuffer("a", "b", "c"))
lists
rust swift scala
literal // none; use constructor:
List(1, 2, 3)
empty list
 
Nil
List()
empty list test val list = List(1, 2, 3)

list == Nil
list.isEmpty
cons
 
1 :: List(2, 3)
head
 
List(1, 2, 3).head
tail
 
List(1, 2, 3).tail
head and tail of empty list // NoSuchElementException:
Nil.head

// UnsupportedOperationException:
Nil.tail
length
 
List(1, 2, 3).length
nth element
 
List(1, 2, 3)(0)
element index // evaluates to 1:
List(7, 8, 9).indexOf(8)

// evaluates to -1:
List(7, 8, 9).indexOf(10)
update // evaluates to List(1, 4, 3):
List(1, 2, 3).updated(1, 4)
concatenate
two lists, list of lists
List(1, 2) ::: List(3, 4)
List(1, 2) ++ List(3, 4)

List(List(1, 2), List(3, 4)).flatten
last
and butlast
List(1, 2, 3).last
List(1, 2, 3).init
take
 
List(1, 2, 3).take(2)
drop
 
List(1, 2, 3).drop(2)
iterate List(1, 2, 3).foreach(i => println(i))

for (i <- List.range(1, 11).reverse)
  println(i)
reverse
 
List(1, 2, 3).reverse
sort List(1, 3, 2, 4).sortWith((x, y) => x < y)
List(1, 3, 2, 4).sortWith(_ < _)
List(1, 3, 2, 4).sortWith((x, y) => x > y)
List(1, 3, 2, 4).sortWith(_ > _)
map List(1, 2, 3).map(x => 2 * x)
List(1, 2, 3).map(2 * _)
filter
 
List(1, 2, 3).filter(x => x > 2)
fold from left List(1, 2, 3).foldLeft(0)(_ + _)
List(1, 2, 3).foldLeft(0)((x, y) => x + y)
fold from right
 
List(1, 2, 3).foldRight(0)(_ - _)
membership
 
List(1, 2, 3).contains(3)
universal test
 
List(1, 2, 3).forall(_ > 2)
existential test
 
List(1, 2, 3).exists(_ > 2)
zip lists List(1, 2, 3).zip(List("a", "b", "c"))
tuples
rust swift scala
literal
 
(1, "hello", true) (1, "hello", true) (1, "hello", true)
type
 
let tup: (i32, &str, bool) = (1, "hello", true); let tup: (Int, String, Bool) = (1, "hello", true) val tup: (Int, String, Boolean) = (7, "foo", true)
lookup let tup = (1, "hello", true);
let n: i32 = tup.0
let tup = (1, "hello", true)
let n: Int = tup.0
val tup = (1, "hello", true)
val n: Int = tup._1
deconstruct let tup = (1, "hello", true);
let (n, s, b) = tup;

// use underscores for unneeded elements:
let (n, _, _) = tup;
let tup = (1, "hello", true)
let (n, s, b) = tup

// use underscores for unneeded elements:
let (n, _, _) = tup
val tup = (1, "hello", true)
tup match {
  case (_, s, _) => println(s)
  case _ => throw new Exception("bad tuple")
}
dictionaries
rust swift scala
declare let mut dict = std::collections::HashMap::new(); let dict = Dictionary<String, Int>() import scala.collection.mutable

val dict = mutable.Map.empty[String, Int]
literal // no dict literal
let mut dict = std::collections::HashMap::new();
dict.insert("t", 1);
dict.insert("f", 0);
let dict = ["t": 1, "f": 0] // scala.collection.immutable.Map[String,Int]:
val dict = Map("t" -> 1, "f" -> 0)
size
 
dict.len() dict.count dict.size
lookup dict["t"] dict("f")

// returns Option[Int]:
dict.get("f")
update dict["t"] = 2 // mutable.Map only:
dict("t") = 2
out-of-bounds behavior
 
returns nil raises java.util.NoSuchElementException
is key present if dict["y"] {
  println("key found")
} else {
  println("no such key")
}
dict.exists(kv => kv._1 == "t")
delete dict.removeValueForKey("t") // mutable.Map only:
dict.delete("t")
iterate for (k, v) in dict {
  println("\(k): \(v)")
}
for (kv <- dict) {
  println(kv._1)
  println(kv._2)
}
keys and values as arrays // dict.keys and dict.values are iterable:
Array(dict.keys)
Array(dict.values)
// Iterable[String]:
dict.keys
// Array[String]:
dict.keys.toArray
dict.values
dict.values.toArray
functions
rust swift scala
define function fn add(x: f64, y: f64) -> f64 {
  x + y
}
func add(n: Int, m: Int) -> Int {
  return n + m
}
// argument types must be declared:
def average(a: Double, b: Double)
  = (a + b) / 2.0

// return value type must be declared if
// function is recursive:

def factorial(n: Int): Int =
  if (n < 1)
    1
  else
    n * factorial(n - 1)
invoke function add(3.7, 2.8) add(3, 7) // 3.0:
average(1, 2 + 3)

// 4.5:
average(1, 2) + 3

// parens can be omitted when a function
// takes no arguments; by convention parens
// are omitted when the function has no
// side effects
define function with block body // braces must be used if body
// not an expression:

def print_numbers() = {
  println("one")
  println("two")
}
nest function fn add_one(x: f64) -> f64 {

  fn add(x1: f64, y1: f64) -> f64 {
    x1 + y1
  }

  add(x, 1.0)
}
func add_one(n: Int) -> Int {
  func add(a: Int, b: Int) -> Int {
    return a + b
  }
  return add(1, n)
}
named parameter func my_log(#exp: Double, #base: Double) -> Double {
  return log(exp) / log(base)
}

// expose different parameter names:
func my_log(exp e: Double, base b: Double) -> Double {
  return log(e) / log(b)
}

my_log(exp: 8, base: 2)
def subtract(m: Int, s: Int) = m - s

subtract(s = 3, m = 7)
named parameter default value func incr(n: Int, amount: Int = 1) -> Int {
  return n + amount
}

// 4:
incr(3)

// 5:
incr(3, amount: 2)
def logarithm(x: Double,
              base: Double = math.exp(1)) =
  math.log(x) / math.log(base)

logarithm(2.718)
logarithm(10, base = 2)
variable number of arguments func concat(strings: String...) -> String {
  var retval = ""
  for string in strings {
    retval += string
  }
  return retval
}
overload function func add(a: String, b: String) -> String {
  return a + b
}
return value return arg; otherwise last expression evaluated and not followed by semicolon; otherwise unit () return arg if function body is preceded by = // the return value is the// return arg or last expression evaluated.

If function body not preceded by = the return value is Unit.
multiple return values func divmod(dividend: Int, divisor: Int) -> (Int, Int) {
  return (dividend / divisor, dividend % divisor)
}
recursive function def range(a:Int, b:Int): List[Int] =
  if (a > b)
    List()
  else
    a :: range(a + 1, b)
anonymous function let add_one = {(n: Int) -> Int in n + 1} (x: Double, y: Double) => (x + y) / 2.0
invoke anonymous function add_one(2)
function as value func add(n: Int, m: Int) -> Int {
  return n + m
}

let f = add
infix operator in prefix position none
function in infix position unary methods can be used as binary operators
currying def plus(x: Int)(y: Int) = x + y
plus(3)(7)
def plus2 = plus(2)
plus2(7)
lazy evaluation def arg1(x: => Int, y: => Int): Int = x

arg1(7, 1 / 0)
execution control
rust swift scala
if let signum: i32;

if i > 0 {
  signum = 1
} else if i == 0 {
  signum = 0
} else {
  signum = -1
}
var signum: Int

if i > 0 {
  signum = 1
} else if i == 0 {
  signum = 0
} else {
  signum = -1
}
if (x > 0)
  println("pos")
else if (x < 0)
  println("neg")
else
  println("zero")
while let mut i: i32 = 0;

while i < 10 {
  i += 1
}
var i = 0

while i < 10 {
  i += 1
}
var i = 0
while (i<10) {
  printf("%d\n", i)
  i = i+1
}
for let mut n: i32 = 1;

for i in range(1i, 11i) {
  n *= i;
}
var n = 1

for var i = 1; i <= 10; i++ {
  n *= i
}
for (i <- 1 to 10)
  println(i)
infinite loop loop {

}
while (true) {

}
break and continue
 
break continue import scala.util.control.Breaks.break

for (i <- 1 to 10)
  if (i > 5)
    break
  else
    println(i)

// there is no continue statement
exceptions
rust swift scala
raise error panic!("bam!"); throw new Exception("bam!")
handle error // does not catch all panics:
let result = std::panic::catch_unwind(|| {
  panic!("bam!");
});

if result.is_ok() {
  println!("no panic");
}
import java.lang._
 
val x = try {
  1 / 0
}
catch {
  case e: ArithmeticException => 0
}
standard exceptions defined in java.lang:

Throwable
  Error
  Exception
    IOException
      EOFException
      FileNotFoundException
      MalformedURLException
      UnknownHostException
    ClassNotFoundException
    CloneNotSupportedException
    RuntimeException
      ArithmeticException
      ClassCastException
      IllegalArgumentException
      IllegalStateException
      IndexOutOfBoundsException
      NoSuchElementException
      NullPointerException

Error, RuntimeException, and subclasses theoreof are normally unrecoverable
assert assert!(1 == 0); assert(1 == 0)
concurrency
rust swift scala
file handles
rust swift scala
standard file handles use std::io;

io::stdin
io::stdout
io::stderr
let stdin =
  NSFileHandle.fileHandleWithStandardInput()
let stdout =
  NSFileHandle.fileHandleWithStandardOutput()
let stderr
  NSFileHandle.fileHandleWithStandardError()
System.in
System.out
System.err
read line from stdin use std::io;

let s = io::stdin().read_line().ok().expect("Failed to read line");
none import scala.io.StdIn.readLine

// newline is removed:
val s = readLine()
write line to stdout println!("Hello, World!");

// argument of println! must be a literal.
// To print a variable:

let s = "Hello, World!";
println!("{}", s);
print("Hello, World!") println("lorem ipsum")
write formatted string to stdout let s = "Spain"
let i = 17
let x = 3.1415
let fmtx = NSString(format: "%.2f", x)

print("\(s) \(i) \(fmtx)")
printf("%s %d %.2f", "Spain", 17, 3.1415)
open file for reading import scala.io.Source

val path = "/etc/hosts"
val f = Source.fromFile(path)
import scala.io.Source

val path = "/etc/hosts"
val f = Source.fromFile(path)
open file for writing let path = "/tmp/test"
NSFileManager().copyItemAtPath(
  "/dev/null",
  toPath: path,
  error: nil)
let f = NSFileHandle(
  forWritingAtPath: path)
open file for appending let f = NSFileHandle(
  forWritingAtPath: "/tmp/err.log")
f.seekToEndOfFile()
close file f.closeFile() import scala.io.Source

f.close
close file implicitly class Defer {
  var fun: ()->()
  init(fun: ()->()) {
    self.fun = fun
  }
  deinit {
    fun()
  }
}
var defer = Defer({()->() in f.closeFile()})
read line none import scala.io.Source
val src = Source.fromFile("/etc/passwd")
for (line <- src.getLines)
  print(line)
iterate over file by line none
read file into array of strings none
read file into string let data = f.readDataToEndOfFile()
let s = NSString(
  data: data,
  encoding: NSUTF8StringEncoding)
write string f.writeData("Hello, World!".dataUsingEncoding(
  NSUTF8StringEncoding))
write line f.writeData("Hello, World!\n".dataUsingEncoding(
  NSUTF8StringEncoding))
val out = new java.io.FileWriter("/tmp/test-scala")
out.write("hello out\n")
out.close
flush file handle f.synchronizeFile()
get and set filehandle position let pos = f.offsetInFile
f.seekToFileOffset(0)
files
rust swift scala
file test, regular file test import java.io.File

val f = new File("/etc/hosts")
f.exists
f.isFile
file size import java.io.File

val f = new File("/etc/hosts")
f.length
is file readable, writable, executable import java.io.File

val f = new File("/etc/hosts")
f.canRead
f.canWrite
f.canExecute
set file permissions mport java.io.File

val f = new File("/tmp/foo")

// sets owner perms; to turn perms off
// set arg to false:

f.setReadable(true)
f.setWritable(true)
f.setExecutable(true)

// if 2nd arg is false, perms are
// for owner, group, and other:

f.setReadable(true, false)
f.setWritable(true, false)
f.setExecutable(true, false)
copy file, remove file, rename file import java.nio.file.Files
import java.nio.file.Paths

val path = Paths.get("/tmp/foo")
// possible java.nio.file.FileAlreadyExistsException:
Files.copy(path, Paths.get("/tmp/bar"))

Files.deleteIfExists(path)
// possible java.nio.file.NoSuchFileException:
Files.delete(path)

Files.move(Paths.get("/tmp/bar", path)
create symlink, symlink test, readlink import java.nio.file.Files
import java.nio.file.Paths

val target = Paths.get("/etc/hosts")
val path = Paths.get("/tmp/hosts")
// Possible java.nio.file.FileAlreadyExistsException:
Files.createSymbolicLink(path, target)
Files.isSymbolicLink(path)
Files.readSymbolicLink(path)
generate unused file name import java.nio.file.Files

val path = Files.createTempFile("foo", ".txt")
directories
rust swift scala
build pathname import java.io.File

val root = File.listRoots()(0)
val hosts = new File(new File(root, "etc"), "hosts")
val path = hosts.getPath
dirname and basename import java.io.File

val f = new File("/etc/hosts")
val dirn = f.getParent
val basen = f.getName
iterate over directory by file import java.io.File

val dir = new File("/etc")

// Array[String]:
dir.list

// Array[java.io.File]:
dir.listFiles
make directory import java.io.File

val dir = new File("/tmp/foo/dir")
dir.mkdirs
remove empty directory import java.io.File

val dir = new File("/tmp/foodir")
dir.delete
remove directory and contents // libraryDependencies += "commons-io" % "commons-io" % "2.4"
import org.apache.commons.io.FileUtils
import java.io.File

FileUtils.deleteDirectory(new File("/tmp/foo"))
directory test import java.io.File

val f = new File("/etc")
f.isDirectory
temporary directory import java.nio.file.Files

val dir = Files.createTempDirectory(null)
// path as string:
dir.toString

// arrange for directory to be deleted:
dir.toFile.deleteOnExit
processes and environment
rust swift scala
command line arguments object Test {
  def main(args: Array[String]) {
    for (arg <- args)
      println(arg)
  }
}
program name
 
A scala program is run as

  scala CLASS [ARG …]

The VM then searches CLASSPATH for CLASS. CLASS is the nearest analog to the program name and can be determined statically.
getopt // built.sbt:
//
//   libraryDependencies += "com.github.scopt" %% "scopt" % "3.3.0"


case class Config(
  foo: Int = 0,
  bar: String = ""
)

val parser = new scopt.OptionParser[Config]("scopt") {
  opt[Int]('f', "foo") action { (x, c) =>
    c.copy(foo = x) } text("foo is integer")
  opt[String]('b', "bar") action{ (x, c) =>
    c.copy(bar = x) } text("bar is string")
}

parser.parse(args, Config()) match {
  case Some(config) =>
    println(config.foo)
    println(config.bar)
  case None =>
    // bad args; usage was displayed
}
get and set environment variable
 
// java.util.NoSuchElementException if not defined:
sys.env("HOME")

// returns Option[String]:
sys.env.get("HOME")

// Environment variables are read only, but new values can be
// set when creating child processes.
get pid, parent pid
 
// no portable technique
get user id and name System.getProperty("user.name")

// no property for uid
exit
 
System.exit(1)
set signal handler
 
import sun.misc._

Signal.handle(new Signal("INT"), new SignalHandler() {
  val start = System.nanoTime()
  def handle(sig: Signal) {
    val end = System.nanoTime()
    println(s"\n${(end - start) / 1e9f} seconds")
    System.exit(0)
  }
})
external command
 
import scala.sys.process._

val exitCode = "ls /tmp".!
escaped external command
 
import scala.sys.process._
import java.io.File

// if args contain spaces, use List():
val exitCode = List("touch", "/tmp/some file").!

// there are operators for shell &&, ||, and |:
(( "ls /tmp" #&& "ls /etc") #| "grep ssh").!

// redirection example:
("ls" #> new File("/tmp/ls.out")).!
backticks
 
import scala.sys.process._

val s = "ls".!!
libraries and namespaces
rust swift scala
define namespace package foo {
  class A
  class B
}

// Alternate syntax; must be first statement in file;
// declares entire file to be in namespace

package foo
define child namespace package foo.bar {
  class A
}

// Alternate nested syntax:
package foo {
  package bar {
    class A
  }
}

// Alternate syntax; must be first statement in file:
package foo.bar
reference identifier in another file // no import needed if identifier is fully qualified:
val a = new foo.bar.A
import definitions import foo.A

val a = new A

// imports A and B:
import foo.{A, B}

// Import statements can appear after or inside class definitions,
// or inside methods.
import all definitions in namespace import foo._

val a = new A
val b = new B
import namespace import foo.bar

val a = new bar.A
val b = new bar.B
shadow avoidance import foo.bar.{A => LetterA}

val a = new LetterA
library path environment variable $ cat src/foo/bar/A.scala
package foo.bar

object A {
  def main(args: Array[String]) {
    println("Hello, World!")
  }
}

$ scalac src/foo/bar/A.scala

$ dir=$(pwd)

$ cd /

$ CLASSPATH=$dir scala foo.bar.A

The default CLASSPATH is the current directory. Directories are separated by colons : on Unix and semicolons ; on Windows. Jar files can also be put in the CLASSPATH.
create package $ cat src/foo/bar/A.scala
package foo.bar

object A {
  def main(args: Array[String]) {
    println("Hello, World!")
  }
}

$ mkdir target

$ scalac -d target src/foo/bar/A.scala

$ find target -name '*.class' | xargs jar cf App.jar

$ CLASSPATH=App.jar scala foo.bar.A
inspect package $ jar tf App.jar
install package $ cat Cargo.toml
[package]
name = "main"
version = "0.1.0"
authors = ["Bob <bob@foo.com>"]
[dependencies]
chrono = "0.2.25"

$ cat src/main.rs
extern crate chrono;
fn main() {
  let t = chrono::UTC::now();
  println!("t: {}", t.format("%Y-%m-%d"));
}

$ cargo build
$ cat build.sbt
libraryDependencies += "commons-io" % "commons-io" % "2.4"

$ sbt package
list installed packages $ find ~/.ivy2/cache -name '*.jar'
user-defined types
rust swift scala
typealias CustomerId = Int
var customer_id: CustomerId = 3
type Name = String
sum type enum DayOfWeek {
  Mon, Tue, Wed, Thu, Fri, Sat, Sun
}

let dow: DayOfWeek = Mon;
enum DayOfWeek {
  case Mon, Tue, Wed, Thu, Fri, Sat, Sun
}
let dow = DayOfWeek.Tue
abstract class Color

case object Red extends Color
case object Blue extends Color
case object Green extends Color

val col = Red

// this won't compile:
col < Green
tuple product type with one field class SpecialInt(x: Int)

val n = new SpecialInt(7)
tuple product type with two fields class IntPair(a: Int, b: Int)

val p = new IntPair(7, 11)
record product type struct MedalCount {
  var country: String
  var gold: Int,
  silver: Int,
  bronze: Int
}
case class Customer(
  id: Int,
  name: String,
  address: String
)
record product type literal var spain = MedalCount(
  country: "Spain",
  gold: 3,
  silver: 2,
  bronze: 1
)
Customer(7,"John","Topeka, KS")

Customer(id=7, name="John", address="Topeka, KS")
product type member access let france_total = france.gold + france.silver + france.bronze
product type member assignment var france: MedalCount
france.country = "France"
france.gold = 7
france.silver = 6
france.bronze = 5
generic type class Twosome[A, B](a: A, b: B)

val p = new Twosome("pi", 3.14)
recursive type abstract class BinaryTree
case class Tree(left: BinaryTree, right: BinaryTree) extends BinaryTree
case class Leaf(x: Int) extends BinaryTree
pattern match sum type let msg = match col {
  Red => "red",
  Blue => "blue",
  Green => "green",
};
val c:Color = Red;
c match { case Red => "red"; case Green => "green"; case Blue => "blue" }
pattern match product type
pattern match guard match { case i: Int if i < 0 => - i; case i: Int => i }
pattern match catchall let msg = match col {
  Red => "red",
  _ => "not red",
};
val c : Color = Green
c match { case Red => "red"; case _ => "not red" }
objects
rust swift scala
define class // Constructor takes optional param of type Int.
//
// Precede param name by val or var
// to implicitly define an instance variable

class Counter(n: Int = 0) {
  // Executes when object is created.
  //
  // java.lang.IllegalArgumentException if false.

  require(n >= 0)

  // Instance variables public by default
  private var _n = n

  // Getter:
  def value = _n

  // Setter:
  def value_=(n: Int) { _n = n }

  // Object-mutating method:
  def incr { _n += 1 }
}
create object val c = new Counter
val c2 = new Counter(1)
invoke method c.incr()
c.value = c.value + 1
define class variable and method // Define singleton object outside of class body:
object Counter {
  // Class variables can be declared private; Counter constructor
  // and instance methods stil have access:

  var instances = 0

  def incrInstances { instances += 1 }
}
invoke class method Counter.incrInstances
inheritance and polymorphism
rust swift scala
subclass class Base {
  println("instantiating Base")
  
  def name = { "Base" }
}

class Derived extends Base {
  println("instantiating Derived after Base")
  
  // Compilation error if override omitted or
  // if method with same name not defined in base class.

  override def name = { "Derived" }
}
abstract base class abstract class Base {
  // compilation error if derived class does not define name:
  def name: String
}
mixin
unit test
rust swift scala
test class import org.scalatest.FunSuite

class FooSuite extends FunSuite {
  test("a simple test") {
    assert(0 == 0, "zero not equal to itself")
  }
}
run all tests, run test suite $ cat build.sbt
libraryDependencies +=
  "org.scalatest" %% "scalatest" % "3.0.0-SNAP13"

$ sbt test

$ sbt
> testOnly FooSuite
exception assertion intercept[IndexOutOfBoundsException] {
  "val a = List(1, 2, 3)
  "val n = a(4)
}
setup import org.scalatest.FunSuite
import org.scalatest.BeforeAndAfter

class FooSuite extends FunSuite with BeforeAndAfter {
  before {
    print("before called\n")
  }

  test("zero equals self") {
    assert(0 == 0)
  }
}
teardown import org.scalatest.FunSuite
import org.scalatest.BeforeAndAfter

class FooSuite extends FunSuite with BeforeAndAfter {
  test("zero equals self") {
    assert(0 == 0)
  }

  after {
    print("after called\n");
  }
}
debugging and profiling
rust swift scala
lint $ brew install scalastyle
$ scalastyle Hello.scala
run debugger Scala IDE for Eclipse has a debugger
profile code Runs app under a sampling profiler. Profiling info is written to stdout. HotSpot VM only.
$ JAVA_OPTS=-Xprof scala SomeApp
memory tool $ JAVA_OPTS=-XX:+PrintGCDetails scala SomeApp
repl
rust swift scala
invoke repl $ swift $ scala
previous values $R0, $R1, … res0, res1, …
help :help :help
quit :quit :quit
inspect type repl displays the type of any expression entered
________________________________________________________________ _________________________________________________________________ _________________________________________________________________

version used

The version used for examples in this sheet.

show version

How to get the installed version.

implicit prologue

Boilerplate which is assumed to be present by examples in this sheet.

Grammar and Invocation

interpreter

How to run the interpreter on a file of source code.

scala:

Scala can be run "Perl style" like this:

scala foo.scala

or "Java style" like this:

scala Foo

When the code is run "Java style", the code to be executed must be in the main method of an object with the same name as the file. When the code is run "Perl style" the statements o be executed should be at the top level outside of any object, class, or method.

To use scala as a shebang, it is necessary to terminate the shell script portion of the script with !#

#!/bin/sh
exec scala $0 $@
!#
println("hello world")

compiler

How to run the compiler.

statement terminator

scala:

Scala infers the existence of a semicolon at the end of a newline terminated line if none of the following conditions hold:

  • the line ends with a infix operator, including a period
  • the following line begins with a word that is not legal at the start of a statement
  • the line ends inside parens or square brackets, neither of which can contain multiple statements

block delimiters

How blocks of statements are delimited.

end-of-line comment

The syntax for a comment which goes to the end of the line.

multiple line comment

The syntax for a comment which beginning and ending delimiters which can span multiple lines.

Variables and Expressions

let ... in ...

How to define local variables.

scala:

Blocks can be used in Scala exclusively to define scope. Furthermore blocks are expressions and evaluate to their last statement.

Arithmetic and Logic

integer types

The most commonly used numeric types.

scala:

Arithmetic operators can be used on values of type Char, which then behaves as a 16 bit unsigned integer. Integer literals are of type Int unless suffixed with L:

scala> 9223372036854775807L
res24: Long = 9223372036854775807

scala> 9223372036854775807 
<console>:1: error: integer number too large

integer overflow

What happens when expression evaluates to an integer that is larger than what can be stored.

scala:

The largest integers are available in the constants Int.MaxValue and Long.MaxValue.

random number

How to generate a uniformly distributed random integer; how to generate a uniformly distributed float; how to generate a normally distributed float.

scala:

One can also use java.util.Random, which does not have to be imported.

random seed

How to set a random seed. How to get and restore the state of a random number generator.

scala:

It looks like Scala 2.10 has modified the Random constructor so that it will accept an Int or Long as a seed argument.

Strings

string type

The types for strings and characters.

string literal

The syntax for a string literal.

newline in literal

literal escapes

scala:

Unicode escapes might not work when scala is installed on a Mac because the encoding is set by default to MacRoman:

scala> System.getProperty("file.encoding")
res0: java.lang.String = MacRoman

This can be fixed by passing the following flag to java in the scala shell script:

-Dfile.encoding=UTF-8

format string

concatenate

How to concatenate strings.

replicate

translate case

How to convert a string to uppercase; how to convert a string to lowercase; how to capitalize the first character.

capitalize

trim

pad

number to string

string to number

How to parse numeric types from string; how to convert numeric types to strings.

scala:

The + operator will convert a numeric type to a string if the other operand is a string. Hence the following works:

"value: " + 8

join

split

character type

character literal

length

How to get the length of a string.

index of substring

How to get the index of a substring.

extract substring

How to extract a substring.

extract character

How to get the character at a specified index of a string.

The syntax for a character literal.

chr and ord

How to convert a character to its ASCII code or Unicode point; how to convert an ASCII code or Unicode point to a character.

Dates and Time

Fixed-Length Arrays

Resizable Arrays

Lists

list literal

list element element

list head

list-tail

Supports List.tl (with a warning) to be compatible with OCaml.

Tuples

literal

The syntax for a tuple literal.

type

How to declare a variable with a tuple type.

lookup

How to lookup an element in a tuple.

deconstruct

How to extract all the elements in a tuple.

Dictionaries

Functions

function

How to define a function.

scala

Recursive functions must have their return type declared because the Scala compiler cannot infer it.

lambda

How to define an anonymous function.

piecewise defined function

How to define a function with multiple equations and matching on the arguments.

recursive function

How to define a recursive function.

mutually recursive functions

How to define two functions which call each other. Mutual recursion can be eliminated by inlining the second function inside the first function. The first function is then recursive and can be defined independently of the second function.

named parameter

How to define and invoke a function with named parameters.

named parameter default value

How to make named parameters optional by providing a default value in the definition.

infix operator in prefix position

How to invoke an infix operator in prefix position.

function in infix position

How to invoke a function in infix position.

currying

How to create a curried function by providing values for some of the arguments of a function.

scala:

Functions can only be curried if they are defined with special syntax. Functions defined with this syntax must be invoked with a pair of parens for each argument.

function composition operator

An operator which takes two functions as arguments and returns a function constructed from them by composition.

lazy evaluation

How to evaluate the arguments to a function in a lazy manner.

Lazy evaluation is also called call-by-name.

scala:

Functions can be defined to evaluate their arguments lazily by putting a => operator between the colon and the type of the parameter in the function signature.

We can define arg1 so that the first argument is strict and the second argument is lazy:

def arg1(x: Int, y: => Int): Int = x

arg1(7, 1 / 0)

strict evaluation

How to evaluate arguments before they are passed to a function.

Strict evaluation is also called call by-value.

Execution Control

if

The if statement.

while

The while loop.

for

infinite loop

An infinite loop.

break and continue

Statements for exiting a loop or ending an iteration of a loop.

Exceptions

raise error

How to raise an error.

handle error

How to handle an error.

Concurrency

Filehandles

Files

Directories

Processes and Environment

Libraries and Namespaces

namespace example

namespaces

file name restrictions

import

namespace creation

namespace alias

namespace separator

subnamespace

inspect namespace

User-Defined Types

type synonym

sum type

generic type

recursive type

Objects

Inheritance and Polymorphism

REPL

repl

repl limitations

repl last value

help

inspect type

load source file

search path

set search path on command line

Rust

The Rust Reference
The Rust Standard Library

Scala

The Scala Language Specification: Version 2.9 (pdf)
Scala API Docs

Swift

As of June 2014, to use Swift one must download and install a beta version of Xcode 6, then:

$ sudo xcode-select -s /Applications/Xcode6-Beta.app/Contents/Developer/

$ xcrun swift
issue tracker | content of this page licensed under creative commons attribution-sharealike 3.0