Tabla de Contenidos

Scala

Herramientas

Uso

sbt

export PATH=/home/alfred/bin/sbt/bin:$PATH

Scala IDE

object test {
  println("Welcome to the Scala worksheet")       //> Welcome to the Scala worksheet
  val x = 4                                       //> x  : Int = 4
  def inc (i: Int) =  i + 1                       //> inc: (i: Int)Int
  inc(x)*5                                        //> res0: Int = 25
}

Conceptos

Conceptos básicos

Vocabulario

El main...

En Scala hay dos formas de indicar un punto de entrada a un programa, aunque siempre será a partir de un objeto…
Puede hacerse extendiendo el objeto de App

object HelloWorld extends App {
  println("Hello, World!")
}

… O añadiendo a un objeto el método def main(args: Array[String]):

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

Sintaxis de código

Definir un valor llamado radious:

def radious = 10

Definir una expresión:

def sumOfSquares(x: Double, y: Double) = square(x) + square(y)

Definir el tipo de retorno de una expresión:

def sumOfSquares(x: Double, y: Double): Double = ...

Para evaluar una exprisión por nombre, en vez de por valor se usa =>:

def constOne(x:Int, y: => Int) = 1

También puedes usar expresiones if-else de la siguiente forma:

def abs(x:Int) = if (x >= 0) x else -x

Tabla de operadores booleanos:

true && e --> e
false && e --> false
true || e --> true
false || e --> e

def significa “por nombre”, val por valor. Por nombre se genera al evaluar esa expresión, por valor cuando se utiliza:

def loop: Boolean = loop
def x = loop // would die when it is used
val x = loop // would die here

Podemos hacer expresiones multilínea usando |:

def and(x:Boolean, y:Boolean) =
	|	if (x) y else false

Otra opción para hacer expreiones multilínea es usando paréntesis:

(someLongExpression1
+ someLongExpression2)

O, una última opción de expreiones multilínea es el uso de operadores:

someLongExpression1 +
someLongExpression2

Los bloques se delimitan por { … } y las definiciones existentes dentro de un bloque son visibles dentro de este, además ocultan las definiciones de fuera.

Semicolons are optional in most cases. We can put several expression in one line: El punto y coma es opcional en muchos casos, aún así nos permite para añadir más expresiones en una sola línea:

val y = 1; x + x

Listas

Un objeto List contiene los siguientes métodos:

def sum(xs: List[Int]): Int = {
  if (xs.isEmpty) 0
  else xs.head + sum(xs.tail)
}
 
def max(xs: List[Int]): Int = {
  if (xs.isEmpty) throw new java.util.NoSuchElementException
  if (!xs.tail.isEmpty) {
    val m = max(xs.tail)
    if (xs.head > m) xs.head
    else m
  } else xs.head
}

Excepciones

if (xs.isEmpty) throw new java.util.NoSuchElementException

Montar tests

Funciones y evaluación

Sintaxis de definición:

def nombre (par_name : tipo) : tipo_return = { ... }

Para indicar en Scala que un parámetro (en este caso el segundo) se evaluará por nombre, haremos:

def first (x: Double, y: => Double) = x

Diferencia entre evaluación por nombre y por valor

Teniendo…

square (x: Double) : Double = x * x
sumOfSquares (x: Double, y: Double) : Double = square(x) + square(y)

Por valor cada argumento se evalua una vez:

sumOfSquares(3, 2+2)
sumOfSquares(3, 4)
square(3) + square(4)
3 * 3 + square(4)
9 + square(4)
9 + 4 * 4
9 + 16
25

Por nombre cada argumento se evalua cuando es llamado:

sumOfSquares(3, 2+2)
square(3) + square(2+2)
3 * 3 + square(2+2)
9 + square(2+2)
9 + (2+2) * (2+2)
9 + 4 * (2+2)
9 + 4 * 4
25

Si tuviesemos la siguientes expresiones

def loop () = loop
def first (x: Double, y: Double) = x
first(x, loop)

Si evaluamos la tercera por nombre terminaría pero si la evaluamos por valor cae en bucle infinito.
Cuando definimos usando val lo hacemos haciéndolo por valor. Cuando lo hacemos usando def lo hacemos por nombre:

def loop () : Boolean = loop
def x = loop 
val x = loop  // bucle infinito

Notas