Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema...

29
Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes 5 de abril de 2011 Referencias • Programming in Scala. Martin Odersky, Lex Spoon, Bil Venners. Ed. Artima. • Programming Scala. Dean Wampler, Alex Payne. Ed. O'Reilly. • Scala by Example . Martin Odersky. November 2010. • A Scala Tutorial for Java programmers . Michel Schinz, Philipp Haller. November 2010. • The Scala Language Specification . Martin Odersky. November 2010. martes 5 de abril de 2011

Transcript of Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema...

Page 1: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Tema 6: Programación funcional en Scala

Sesión 17: Introducción a Scala (1)

martes 5 de abril de 2011

Referencias

• Programming in Scala. Martin Odersky, Lex Spoon, Bil Venners. Ed. Artima.

• Programming Scala. Dean Wampler, Alex Payne. Ed. O'Reilly.

• Scala by Example. Martin Odersky. November 2010.

• A Scala Tutorial for Java programmers. Michel Schinz, Philipp Haller. November 2010.

• The Scala Language Specification. Martin Odersky. November 2010.

martes 5 de abril de 2011

Page 2: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

El lenguaje de programación Scala

• Se desarrolla en 2001 en la universidad EPFL (Suiza) por un equipo dirigido por Martin Odersky

• El objetivo principal del lenguaje es integrar el paradigma funcional y el paradigma orientado a objetos

• Énfasis en la facilidad del desarrollo de componentes reusables

• Está basado en Java: los programas en Scala se compilan a bytecodes de Java y se ejecutan en la máquina virtual Java

• Sus características funcionales lo hacen muy apropiado para desarrollar programas muy eficientes en arquitecturas paralelas formadas por granjas de múltiples ordenadores (Twitter usa Scala)

• Sitio web: www.scala-lang.orgmartes 5 de abril de 2011

Unificación de PF y POO

• Programación funcional: hace fácil desarrollar cosas interesantes desde partes sencillas, usando:

• funciones de orden superior

• tipos algebraicos y pattern matching

• polimorfismo paramétrico

• Programación orientada a objetos: hace fácil adaptar y extender sistemas complejos, usando:

• especialización (subclases) y herencia

• configuraciones dinámicas

• clases como abstracciones parcialesmartes 5 de abril de 2011

Page 3: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Diseño de Scala

• Lenguaje moderno que satisface las necesidades más importantes de los desarrolladores actuales

• Completamente compatible con Java

• Modelo de objetos uniforme

• Pattern matching

• Funciones de orden superior

• Nuevas formas para abstraer y componer programas

martes 5 de abril de 2011

Características de Scala

• Estáticamente tipeado, con características de scripting porque en muchas ocasiones el compilador realiza una inferencia de tipos

• Interoperabilidad: encaja perfectamente en un entorno Java.

• Conciso// Javaclass MyClass{ private int index; private String name;

public MyClass(int index, String name){ this.index = index; this.name = name; }}

// Scalaclass MyClass(index: Int, name: String)

martes 5 de abril de 2011

Page 4: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Scala utiliza la PF

• Un par de ejemplos con funciones de orden superior:

//Javaboolean nameHasUpperCase = false;for (int i=0; i<name.length(); ++i){ if(Character.isUpperCase(name.charAt(i))){ nameHasUpperCase = true; break; }}

//Scalaval nameHasUpperCase = name.exists(_.isUpperCase)

martes 5 de abril de 2011

Scala utiliza la PF

scala> val matrix = Array(Array(1, 0, 0), Array(0, 1, 0), Array(0, 0, 1))matrix: Array[Array[Int]] = Array ([I@164da25,...scala> matrix.exists(row => row.forall(0 ==))res13: Boolean = false

martes 5 de abril de 2011

Page 5: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Scala es orientado a objetos

• A diferencia de Java o C++ en Scala no existen tipos primitivos que no son objetos

• Todas las expresiones se compilan a llamadas a métodos de objetos

• Veremos más detalles de POO en Scala en los últimos tema de la asignatura

scala> (1).hashCoderes8: Int = 1scala> (1).+(2)res10: Int = 3

martes 5 de abril de 2011

Scala como intérprete y compilador

• Scala permite ejecutar sus programas en modo scripting o en modo compilado

• Hasta ahora hemos usado el intérprete de Scala

• Cada línea de código es compilada y se genera bytecode que es ejecutado por la MV Java

martes 5 de abril de 2011

Page 6: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Scala como intérprete y compilador

• Se puede llamar a un script de Scala con el comando scala

• También es posible utilizar el compilador de Scala explícitamente, con el comando scalac

helloworld.scala:// Definimos un singleton: una clase con un único objetoobject HelloWorld { def main(args: Array[String]) { println("Hello, world!") } }$ scalac helloworld.scala$ scala HelloWorld

println("Hola, "+ args(0) +"!")args.foreach(arg => println(arg))

martes 5 de abril de 2011

Expresiones y funciones simples en el intérprete

• El intérprete analiza las expresiones, realiza las inferencias de tipos necesarias y evalua la expresión:

scala> 5 + 2 * 3scala> 5 + 2.0 * 3scala> "hola" + " mundo!"

martes 5 de abril de 2011

Page 7: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Tema 6: Programación funcional en Scala

Sesión 18: Programación funcional en Scala

jueves 7 de abril de 2011

Referencias

• Programming in Scala. Martin Odersky, Lex Spoon, Bil Venners. Ed. Artima.

• Programming Scala. Dean Wampler, Alex Payne. Ed. O'Reilly.

• Scala by Example. Martin Odersky. November 2010.

• A Scala Tutorial for Java programmers. Michel Schinz, Philipp Haller. November 2010.

• The Scala Language Specification. Martin Odersky. November 2010.

jueves 7 de abril de 2011

Page 8: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Expresiones y funciones simples en el intérprete

• El intérprete analiza las expresiones, realiza las inferencias de tipos necesarias y evalua la expresión:

scala> 5 + 2 * 3scala> 5 + 2.0 * 3scala> "hola" + " mundo!"

jueves 7 de abril de 2011

Variables mutables e inmutables

• Scala diferencia entre variables inmutables (declaradas con val y variables mutables var)

• Es recomendable utilizar siempre que podamos variables inmutables (val), esto refuerza el carácter funcional de nuestros programas

• Las variables son estrictamente tipeadas, aunque no es necesario declarar el tipo porque Scala puede inferirlo

jueves 7 de abril de 2011

Page 9: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Variables mutables e inmutables

scala> val msg = "Hola mundo!"msg: java.lang.String = Hola mundo!scala> var saludo = "Hola mundo!"saludo: java.lang.String = Hola mundo!scala> saludo = "Hasta luego!"saludo: java.lang.String = Hasta luego!scala> saludo = 3.0<console>:5: error: type mismatch; found : Double(3.0) required: java.lang.String

jueves 7 de abril de 2011

Variables mutables e inmutables

• ¡Cuidado! El intérprete permite declarar varias veces la misma variable. Cada ejecución de una nueva sentencia crea un nuevo ámbito en el que se define la nueva variable. Las variables anteriores se pierden. Esto no es correcto en un programa; una variable sólo se puede declarar una vez.

• Las variables declaradas con val no pueden ser reasignadas. Esto no impide que cambie el valor del objeto que contienen (en el caso de estar en el paradigma imperativo). Ejemplo:

scala> val a = Array(1,0,0)a: Array[Int] = Array(1, 0, 0)scala> a(1) = 1scala> ares42: Array[Int] = Array(1, 1, 0)

jueves 7 de abril de 2011

Page 10: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Tipos de datos básicos

• Aunque hablemos de tipos de datos, en Scala todos los tipos de datos son clases

• Algunos tipos de datos y formas de inicializarlos:

• El API completo de Scala se puede consultar en http://www.scala-lang.org/api/current/index.html

Tipo de dato Rango Ejemplo

Byte 8-bit con signo 38Short 16-bit con signo 23Long 64-bit con signo 3434332

Int 32-bit con signo 70Char 16-bit sin signo A’Float 32 bit flotante con signo 1.234

Double 64 bit flotante con signo 1.234Boolean true o false trueString secuencia de caracteres “hola”

jueves 7 de abril de 2011

Operadores

• Aritméticos: + - = * %

• Relacionales: < <= > >= != ==

• Lógicos: && || !

jueves 7 de abril de 2011

Page 11: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

def para dar nombre a expresiones

• def es una primitiva declarativa: le da un nombre a una expresión, pero no la evalua

• La evaluación se realiza cuando se llame al identificador

• En el caso de val o var la evaluación se realiza antes de hacer la asignación

def t = 8 / 0 --> No da errort --> al evaluar t, error división por cero

val t = 8 / 0 --> error

jueves 7 de abril de 2011

¿Cuándo se evalúan las variables en un def?

• Las variables en una expresión definida por def se evaluan cuando se invoca al identificador definido:

var x = 10def t = x / 5var x = 5t -> 1

jueves 7 de abril de 2011

Page 12: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

def para definir funciones

• Sintaxis:

• Ejemplo:

def <nombre_funcion>(<parametro1:tipo1>,...):<tipo_resultado>={ <cuerpo de la función>}

def max(x: Int, y: Int): Int = { if (x > y) x else y}max: (Int,Int)Int

jueves 7 de abril de 2011

def para definir funciones

• Las llaves son opcionales si el cuerpo tiene una sóla sentencia

• El tipo de retorno es opcional si Scala puede inferirlo (no aplicable a funciones recursivas)

• La función se evalúa cuando se invoca:

• Los ejemplos anteriores en los que se definían expresiones se pueden interpretar de esta manera: como una definición de una función de una única sentencia (la expresión) que se evalua cuando se invoca

scala> def max2(x: Int, y: Int) = if (x > y) x else ymax2: (Int,Int)Int

scala> max2(3, 5)res6: Int = 5

jueves 7 de abril de 2011

Page 13: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Una función que no devuelve nada

• Por ahora todas las funciones que vamos a definir van a estar en el paradigma funcional, siempre devolverán algún valor

• Sin embargo Scala es también procedural:

• La función hola no devuelve ningún valor; la clase Unit es similar al tipo void de Java

scala> def hola() = println("Hola mundo")hola: ()Unit

jueves 7 de abril de 2011

Expresiones condicionales: if

• if: condicional; cuidado con el fin de línea si no utilizamos llaves

• Correcto:

• Incorrecto:

• Correcto:

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

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

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

jueves 7 de abril de 2011

Page 14: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Expresiones if anidadas

def entre(x: Double, x1: Double, x2: Double) = if (x < x1) false else if (x > x2) false else true

jueves 7 de abril de 2011

Expresiones condicionales: match

• Similar al cond de Scheme

• El “default” se escribe como _

var myVar = 3;

myVar match { case 1 => "Uno" case 2 => "Dos" case 3 => "Tres" case 4 => "Cuatro"}

case _ => “otro caso”

jueves 7 de abril de 2011

Page 15: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Funciones recursivas

• El típico ejemplo de función recursiva: factorial en Scala

• Máximo común divisor recursivo:

def factorial(x: Long): Long = if (x == 0) 1 else x * factorial(x - 1)

def gcd(x: Long, y:Long): Long = if (y == 0) x else gcd(y, x % y)

jueves 7 de abril de 2011

Listas

• La clase List de Scala permite definir listas

• Al igual que Scheme son inmutables y tienen una estructura recursiva

• A diferencia de Scheme son estrictamente tipeadas

val fruit = List("apples", "oranges", "pears") val nums = List(1, 2, 3, 4) val diag3 = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) val empty = List()

jueves 7 de abril de 2011

Page 16: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Operador cons

• Funciona igual que en Scheme, produce una nueva lista añadiendo un nuevo elemento a su cabeza

• Se define con 4 puntos ::

• La lista vacía se define con el identificador Nil

val dosTres = List(2, 3)val unDosTres = 1 :: dosTres

val unoDosTres = 1 :: 2 :: 3 :: Nilval fruit = "apples" :: ("oranges" :: ("pears" :: Nil)) val nums = 1 :: (2 :: (3 :: (4 :: Nil))) val diag3 = (1::(0::(0::Nil))):: (0 :: (1 :: (0 :: Nil))) :: (0 :: (0 :: (1 :: Nil))) :: Nil val empty = Nilval nums = 1::2::3::4::Nil

jueves 7 de abril de 2011

Operaciones básicas sobre listas

• head: devuelve el primer elemento de la lista

• tail: devuelve el resto de la lista

• isEmpty: predicado que comprueba si la lista es vacía

• ::: operador similar a append que concatena dos listas

jueves 7 de abril de 2011

Page 17: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Funciones sobre listas

• Con las operaciones previas se pueden definir funciones similares a las que vimos en Scheme

• Inserción en una lista ordenada:

jueves 7 de abril de 2011

Funciones sobre listas

• Con las operaciones previas se pueden definir funciones similares a las que vimos en Scheme

• Inserción en una lista ordenada:

def insert(x: Int, lista: List[Int]) : List[Int] = if (lista.isEmpty) x :: Nil else if (x < lista.head) x :: lista else lista.head :: insert(x, lista.tail)

jueves 7 de abril de 2011

Page 18: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Tema 6: Programación funcional en Scala

Sesión 19: Programación funcional en Scala (3)

martes 12 de abril de 2011

Referencias

• Programming in Scala. Martin Odersky, Lex Spoon, Bil Venners. Ed. Artima.

• Programming Scala. Dean Wampler, Alex Payne. Ed. O'Reilly.

• Scala by Example. Martin Odersky. November 2010.

• A Scala Tutorial for Java programmers. Michel Schinz, Philipp Haller. November 2010.

• The Scala Language Specification. Martin Odersky. November 2010.

martes 12 de abril de 2011

Page 19: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Funciones sobre listas

• Con las operaciones previas se pueden definir funciones similares a las que vimos en Scheme

• Inserción en una lista ordenada:

• Ordenación de una lista:

martes 12 de abril de 2011

Funciones sobre listas

• Con las operaciones previas se pueden definir funciones similares a las que vimos en Scheme

• Inserción en una lista ordenada:

• Ordenación de una lista:

def insert(x: Int, lista: List[Int]) : List[Int] = if (lista.isEmpty) x :: Nil else if (x < lista.head) x :: lista else lista.head :: insert(x, lista.tail)

martes 12 de abril de 2011

Page 20: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Funciones sobre listas

• Con las operaciones previas se pueden definir funciones similares a las que vimos en Scheme

• Inserción en una lista ordenada:

• Ordenación de una lista:

def insert(x: Int, lista: List[Int]) : List[Int] = if (lista.isEmpty) x :: Nil else if (x < lista.head) x :: lista else lista.head :: insert(x, lista.tail)

def sort(lista: List[Int]): List[Int] = if (lista.isEmpty) Nil else insert(lista.head, sort(lista.tail))

martes 12 de abril de 2011

Funciones sobre listas

• Reverse-list:

martes 12 de abril de 2011

Page 21: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Funciones sobre listas

• Reverse-list:

def reverse(l: List[Int]) : List[Int] = if (l == Nil) l else reverse(l.tail) ::: List(l.head)

martes 12 de abril de 2011

Cadenas

• El tipo de Scala es String y se convierte en la clase de Java java.lang.String

• Al igual que las listas son inmutables

• Concatenación con el operador +

• Funciones head, tail, charAt

"hola" + "adios" --> "holaadios"

"hola".head --> h"hola".tail -->"ola""hola".charAt(0) --> 'h'

martes 12 de abril de 2011

Page 22: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Tuplas

• Scala permite construir tuplas de n elementos de distinto tipo

• Es un tipo también inmutable

• La forma de definir una tupla de n tipos es: (tipo1, tipo2,..., tipoN)

• Métodos de acceso al elemento de la tupla ._1, ._2, …

• Ejemplo con una tupla de tres elementos:

val miTupla = (99, "Hola", true)println(miTupla._1)println(miTupla._2)println(miTupla._3)

martes 12 de abril de 2011

Tuplas

• Muy útiles para funciones que tienen que devolver más de un elemento:

martes 12 de abril de 2011

Page 23: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Tuplas

• Muy útiles para funciones que tienen que devolver más de un elemento:

def sumaCadenas(s1: String, s2: String): (String, Int) = (s1+s2, s1.length+s2.length)

martes 12 de abril de 2011

Ámbito de variables

• Una vez definida una variable en un ámbito no podemos volver a definirla

• Sería un error el siguiente script:

• Sí es posible hacerlo en el intérprete, porque cada evaluación de una expresión crea una nuevo ámbito

val a = 1val a = 2 // errorprintln(a)

martes 12 de abril de 2011

Page 24: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Ámbito de variables

• Podemos crear un ámbito interior utilizando llaves:

• Podemos utilizar funciones locales que definen su propio ámbito:

val a = 1;{ val a = 2; println(a)}println(a)

def function1(x : Int) = { def function2(y: Int) = { x*y } function2(3)}function1(2)

martes 12 de abril de 2011

Funciones como objetos de primera clase

• En Scala las funciones son también objetos de primera clase

• Podemos:

• Definir variables y parámetros de tipo función

• Almacenar funciones en estructuras de datos como listas o arrays

• Construir funciones en tiempo de ejecución (closures) y devolverlas como valor de retorno de otra función

martes 12 de abril de 2011

Page 25: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Ejemplo: sumatorio

• La diferencia con Scheme es que Scala es un lenguaje tipeado y hay que definir el tipo de la función que se pasa como parámetro

• La función f que se pasa como primer parámetro de sum debe recibir un entero y devolver un entero

• Si pasamos otro tipo de función, Scala detecta el error de tipos

def square(x: Int): Int = x * x

def sum(f: Int => Int, a:Int, b:Int): Int = if (a>b) 0 else f(a) + sum(f, a+1, b)

martes 12 de abril de 2011

Funciones anónimas

• Al igual que en Scheme con la forma especial lambda, en Scala podemos definir funciones anónimas creadas en tiempo de ejecución

• La función square anterior se podría definir de forma anónima como:

• Podemos definirla como parámetro de sum y no hace falta definir el tipo de las variables, porque Scala lo infiere a partir del tipo del primer parámetro:

(x: Int) => x * x

sum(x => x * x, a, b)

martes 12 de abril de 2011

Page 26: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Funciones anónimas

• Una notación más concisa utiliza subrayados como huecos (placeholders) de los parámetros de la función:

• Es equivalente a:

sum(_+2, a, b)

sum(x => x+2, a, b)

martes 12 de abril de 2011

Variables de tipo función

• Al igual que en Scheme, podemos asignar funciones a variables:

• Para asignar una función ya definida a una variable hay que utilizar la sintaxis de huecos (placeholders) para indicar al compilador que no tiene que aplicar la función:

def suma3(a: Int, b: Int, c: Int) = a + b + cval f = suma3 _ f(1,2,3) --> 6

val f = (s:String) => s + “adios”f(“hola”)

martes 12 de abril de 2011

Page 27: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Variables de tipo función

• Podemos almacenar funciones en listas, pero todas las funciones deben tener el mismo perfil:

def suma3(a: Int, b: Int, c: Int) = a + b + c def mult3(a: Int, b: Int, c: Int) = a * b * c

val listaFuncs = List(suma3 _, mult3 _)

val f = listaFuncs.headf(1,2,3)

martes 12 de abril de 2011

Variables de tipo función

• Ejemplo de función que toma una lista de funciones de un argumento y las aplica:

def aplicaLista (lista: List[(Int) => Int], x: Int): Int = if (lista.length == 1) lista.head(x) else lista.head(aplicaLista(lista.tail,x))

def mas5(x: Int) = x+5def por8(x: Int) = x*8val l = List(mas5 _, por8 _)aplicaLista(l, 10)

martes 12 de abril de 2011

Page 28: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Variables de tipo función

• Es posible utilizar la sintaxis de los huecos para proporcionar algunos de los argumentos y dejar libres otros.

• Con la siguiente expresión definimos una variable de tipo función de un argumento a partir de una función anterior

val g = suma3(1, _: Int, 10)

• Es posible utilizar la sintaxis de los huecos para proporcionar algunos de los argumentos y dejar libres otros.

• Con la siguiente expresión definimos una variable de tipo función de un argumento a partir de una función anterior

martes 12 de abril de 2011

Devolviendo funciones anónimas

• Las funciones pueden crearse y ser devueltas por otras funciones

• ¿Cómo declararías el tipo devuelto por la función makeSumador(Int)?

def makeSumador(k: Int) = (x: Int) => x + kval f = makeSumador(10)val g = makeSumador(100)f(4)g(4)

martes 12 de abril de 2011

Page 29: Tema 6: Programación funcional en Scalarua.ua.es/dspace/bitstream/10045/19672/7/tema6.pdf · Tema 6: Programación funcional en Scala Sesión 17: Introducción a Scala (1) martes

Closures

• Al igual que en Scheme, las funciones definidas en un ámbito mantienen el acceso a ese ámbito y pueden usar los valores allí definidos.

• Llamamos closure a estas funciones

• En el ejemplo siguiente, el ámbito en el que se crea la función devuelta contiene la variable i (el argumento de makeClosure) y la variable valor x declarada con el valor 5

def makeClosure(i : Int) : Int => Int = { val x = 5 (j : Int) => i + j + x}val returnedFuncion : Int => Int = makeClosure(10)println(returnedFuncion) //=> <function>println(returnedFunction(20)) //=> 35, porque 10 + 20 + 5 = 35

martes 12 de abril de 2011