wiki:Languages/Scala

Scala

Perhaps, the third (after Scheme and Haskell) programming language worth learning.

Expressions

In a right language everything is an expression.

Values

Every expression evaluates (could be reduced to) a value.

(define x 2)
def x = 2

evaluated when called

Types

Each value has a type.

Bindings

Lexically scoped local binding

(let ((x 2))
...
)

Once bound (with val) symbols cannot be rebound

val x = 2

evaluated at compile-time

Blocks

(begin
  (+ 1 2) 
  (+ 2 3)
)
{
1 + 2
2 + 3
}

lambdas

(lambda (x) (+ x 1))
{ (x: Int) => x + 1 }

Thunks

Defining a thunk (a lazy value)

(delay 2)
lazy val x = 2

evaluated on-demand

Procedures

(lambda (x) (+ 1 x))
(x: Int) => x + 1

Binding

(define inc (lambda (x) (+ 1 x)))
val inc = (x: Int) => x + 1

Applicative Order - the argument will be evaluated before procedure application (call by value)

def square(x: Double)

Normal Order - the argument will be evaluated inside of the function (call by name)

def square(x: => Double)

Variable number of arguments

(define sum (lambda xs ...))
def sum(xs: Int*) = { ??? }

Higher order procedures

Nesting

import scala.annotation.tailrec

def factorial(x: Int) = {
    @tailrec
    def recur(acc: Int, x: Int): Int =
        if (x == 0) 
            acc
        else
            recur(acc * x, x - 1)
    recur(1, x)
}

Composition

type R = Double // a type alias

def compose(f: R=>R, g: R=>R) = (x: R) => f(g(x)) 

use (anonymous function of arity 1 literals with underscore _ argument syntactic sugar)

val f = compose({_*2}, {_-1})

Currying

(lambda (x) (lambda (y) (+ x y)))
def f(x: Int)(y: Int) = x + y

Infix syntactic sugar

1 + 2 is a syntactic sugar for

1.+(2)
(1 to 5) map (_*2)

Reductions

(define sum (lambda xs (reduce + 0 xs)))
def sum(args: Int*) = args.reduceLeft(_+_)

Types

Objects

Objects are values which has a structure and its own type, usually defined as a Class.

Classes

Classes are Blueprints which define a structure of corresponding objects. They introduce a new type.

Traits

Traits are Interfaces - a named sets of method signatures. They can be extended (inherited) but cannot be instantiated (like a class).

a Trait define what it takes to be a.... If an object implements a trait is could be substituted and used whenever this trait is required.

Something, which has a head and a tail

trait L[+T] {
  def head: T
  def tail: L[T]
}

a container for that

class C[+T](val head: T, val tail: L[T]) extends L[T]

a NIL (denotation for emptiness)

object N extends L[Nothing] {
  def head = ???
  def tail = ???
}

the simplest Container - a wrapper or a Thunk

case class Thunk[+A](value: A)
Last modified 11 months ago Last modified on Aug 31, 2018, 8:33:36 AM