You are on page 1of 11

12/01/14

Tutorial de Scala para programadores Java - Scala Documentation

Tutorial de Scala para programadores Java
Por Michel Schinz y Philipp Haller. Traducción y arreglos Santiago Basulto.

Introducción
Este documento provee una rápida introducción al lenguaje Scala como también a su compilador. Está pensado para personas que ya poseen cierta experiencia en programación y quieren una vista rápida de lo que pueden hacer con Scala. Se asume como un conocimiento básico de programación orientada a objetos, especialmente en Java.

Un primer ejemplo Documentation

API Learn Quickref Contribute SIPs Wiki Como primer ejemplo, usaremos el programa Hola mundo estándar. No es muy fascinante, pero de esta manera resulta fácil demostrar el uso de herramientas de Scala sin saber demasiado acerca del lenguaje. Veamos como luce:
1 . o b j e c tH o l a M u n d o{ 2 . 3 . 4 . 5 . } } d e fm a i n ( a r g s :A r r a y [ S t r i n g ] ){ p r i n t l n ( " ¡ H o l a ,m u n d o ! " )

Search

Contents
Introducción Un primer ejemplo Compilando el ejemplo Ejecutando el ejemplo Interacción con Java Todo es un objeto Los números son objetos Las funciones son objetos Funciones anónimas Clases Métodos sin argumentos Herencia y sobreescritura Clases Case y Reconocimiento de patrones Traits Tipos Genéricos Conclusión

La estructura de este programa debería ser familiar para programadores Java: consiste de un método llamado m a i n que toma los argumentos de la línea de comando (un array de objetos String) como parámetro; el cuerpo de este método consiste en una sola llamada al método predefinido p r i n t l n con el saludo amistoso como argumento. El método m a i n no retorna un valor (se puede entender como un procedimiento). Por lo tanto, no es necesario que se declare un tipo retorno. Lo que es menos familiar a los programadores Java es la declaración de o b j e c t que contiene al método m a i n. Esa declaración introduce lo que es comúnmente conocido como objeto singleton, que es una clase con una sola instancia. Por lo tanto, dicha construcción declara tanto una clase llamada H o l a M u n d o como una instancia de esa clase también llamada H o l a M u n d o. Esta instancia es creada bajo demanda, es decir, la primera vez que es utilizada. El lector astuto notará que el método m a i n no es declarado como s t a t i c. Esto es así porque los miembros estáticos (métodos o campos) no existen en Scala. En vez de definir miembros estáticos, el programador de Scala declara estos miembros en un objeto singleton.

Compilando el ejemplo
Para compilar el ejemplo utilizaremos s c a l a c, el compilador de Scala. s c a l a c funciona como la mayoría de los compiladores. Toma un archivo fuente como argumento, algunas opciones y produce uno o varios archivos objeto. Los archivos objeto que produce son archivos class de Java estándar. Si guardamos el programa anterior en un archivo llamado H o l a M u n d o . s c a l a, podemos compilarlo ejecutando el siguiente comando (el símbolo mayor > representa el prompt del shell y no debe ser escrita):
1 . >s c a l a cH o l a M u n d o . s c a l a

Esto generará algunos archivos class en el directorio actual. Uno de ellos se llamará H o l a M u n d o . c l a s s y contiene una clase que puede ser directamente ejecutada utilizando el comando s c a l a, como mostramos en la siguiente sección.

Ejecutando el ejemplo
Una vez compilado, un programa Scala puede ser ejecutado utilizando el comando s c a l a. Su uso es muy similar al comando j a v a utilizado para ejecutar programas Java, y acepta las mismas opciones. El ejemplo de arriba puede ser ejecutado utilizando el siguiente comando, que produce la salida esperada:

docs.scala-lang.org/es/tutorials/scala-for-java-programmers.html

1/11

las primeras son bastante más poderosas. La declaración i m p o r t en la tercer línea por lo tanto importa todos los miembros de la clase D a t e F o r m a t. Las librerías de clases de Java definen clases de utilería poderosas. por ejemplo Francia. Para concluir esta sección sobre la interacción con Java. i m p o r tj a v a . Veamos un ejemplo que demuestra esto. Dentro del método m a i n primero creamos una instancia de la clase D a t e la cual por defecto contiene la fecha actual. 9 . y no nos permite manipular las funciones como valores. 1 0 . t e x t .L o c a l e .H o l a M u n d o 2 . Todas las clases del paquete j a v a . Esta última línea muestra una propiedad interesante de la sintaxis de Scala. utilizando el carácter guión bajo ( _) en vez del asterisco ( *). Queremos obtener y formatear la fecha actual de acuerdo a convenciones utilizadas en un país específico. pero tiene importantes consecuencias. sin embargo. i m p o r tj a v a .12/01/14 1 . 7 .html 2/11 . } } d e fm a i n ( a r g s :A r r a y [ S t r i n g ] ){ v a la h o r a=n e wD a t e v a ld f=g e t D a t e I n s t a n c e ( L O N G . i m p o r tj a v a . Los métodos que toman un solo argumento pueden ser usados con una sintaxis de infijo Es decir. no es necesario implementar estas clases equivalentes en las librerías de Scala –podemos simplemente importar las clases de los correspondientes paquetes de Java: 1 . d f . A continuación definimos un formateador de fechas utilizando el método estático g e t D a t e I n s t a n c e que importamos previamente. es importante notar que es también posible heredar de clases Java e implementar interfaces Java directamente en Scala. ¡ H o l a . Finalmente. Ya que Scala interacciona fácilmente con Java.m u n d o ! Tutorial de Scala para programadores Java . 3 . Difiere de Java en este aspecto. _ 4 . Múltiples clases pueden ser importadas desde el mismo paquete al encerrarlas en llaves como se muestra en la primer línea. Otra diferencia es que podemos importar todos los nombres de un paquete o clase. f o r m a t ( a h o r a ) Esto parece tener como un detalle sintáctico menor. 8 . Esto hace que el método estático g e t D a t e I n s t a n c e y el campo estático L O N G sean directamente visibles. como D a t ey D a t e F o r m a t. incluyendo números o funciones.org/es/tutorials/scala-for-java-programmers. Todo es un objeto Scala es un lenguaje puramente orientado a objetos en el sentido de que todo es un objeto. D a t e F o r m a t .Scala Documentation Interacción con Java Una de las fortalezas de Scala es que hace muy fácil interactuar con código Java. la expresión 1 . l a n g son importadas por defecto. una de ellas la exploraremos en la próxima sección.L o c a l e } 2 .scala-lang. >s c a l ac l a s s p a t h. 1 1 . u t i l . docs. F R A N C E ) p r i n t l n ( d ff o r m a ta h o r a ) Las declaraciones de importación de Scala lucen muy similares a las de Java. d ff o r m a ta h o r a es solamente otra manera más corta de escribir la expresión: 1 . mientras otras necesitan ser importadas explícitamente. Eso es porque el asterisco es un identificador válido en Scala (quiere decir que por ejemplo podemos nombrar a un método *). { D a t e . D a t e F o r m a t 3 . imprimimos la fecha actual formateada de acuerdo a la instancia de D a t e F o r m a t que fue “localizada”. ya que Java distingue tipos primitivos (como b o o l e a ne i n t) de tipos referenciales. t e x t . 5 . como veremos más adelante. o b j e c tF r e n c h D a t e{ 6 .

1+2*3/x Consiste exclusivamente de llamadas a métodos. 6 . porque es equivalente a la siguiente expresión. El tipo de esta función es escrito de la siguiente manera: ( ) = >U n i t y es el tipo de todas las funciones que no toman argumentos ni retornan valores (el tipo U n i t es similar a v o i d en Java/C/C++). ¿Cómo pasamos al temporizador la acción a realizar? Bastante lógico. Como un ejemplo muy simple de por qué puede ser útil usar funciones como valores consideremos una función temporizador (o timer. la función del temporizador se llama u n a V e z P o r S e g u n d o y recibe una función call-back como argumento. Las funciones son objetos Tal vez suene más sorprendente para los programadores Java. + ( ( ( 2 ) . 1 1 . / ( x ) ) Esto también indica que +. etc.org/es/tutorials/scala-for-java-programmers. Los paréntesis alrededor de los números en la segunda versión son necesarios porque el analizador léxico de Scala usa la regla de “mayor coincidencia”. ( 1 ) .Scala Documentation Los números son objetos Ya que los números son objetos. *. Este simple concepto de pasar funciones debería ser familiar para muchos programadores: es generalmente utilizado en código relacionado con Interfaces gráficas de usuario (GUIs) para registrar “retrollamadas” (call-back en inglés) que son invocadas cuando un evento ocurre. . en inglés) cuyo propósito es realizar alguna acción cada un segundo. Por lo tanto es posible pasar funciones como argumentos. 1 . y 2. haciendo a este un D o u b l e en vez de un I n t. 7 . Por lo tanto partiría la siguiente expresión: 1 . las funciones en Scala también son objetos. La razón que esta regla es elegida es porque 1 . una expresión aritmética como la siguiente: 1 . 5 . 4 . es una coincidencia válida y es mayor que 1. estos también tienen métodos. son identificadores válidos en Scala. * ( 3 ) ) . 1 . 3 . o b j e c tT e m p o r i z a d o r{ 2 . 9 . y retornarlas desde otras funciones. como vimos en la sección anterior: 1 . + ( 2 ) previene que el 1 sea tomado como un D o u b l e. almacenarlas en variables. Esta habilidad de manipular funciones como valores es una de las valores fundamentales de un paradigma de programación muy interesante llamado programación funcional.T h r e a ds l e e p1 0 0 0} Nota: si nunca tuviste experiencias previas con programación funcional te recomiendo que te tomes unos segundos para analizar cuando se utilizan paréntesis y cuando no en los lugares donde docs. 8 . De hecho. este programa imprime interminablemente la sentencia “El tiempo vuela como una flecha” cada segundo. En el siguiente programa.html 3/11 . " ) d e fu n a V e z P o r S e g u n d o ( c a l l b a c k :( )= >U n i t ){ w h i l e( t r u e ){c a l l b a c k ( ) . 1 0 . ( 1 ) . . En otras palabras..scala-lang. Al escribir la expresión así: 1 .12/01/14 Tutorial de Scala para programadores Java . + ( 2 ) En estas partes: 1 . +. } } } d e fm a i n ( a r g s :A r r a y [ S t r i n g ] ){ u n a V e z P o r S e g u n d o ( t i e m p o V u e l a ) } d e ft i e m p o V u e l a ( ){ p r i n t l n ( " E lt i e m p ov u e l ac o m ou n af l e c h a . La función principal de este programa simplemente invoca esta función temporizador con una call-back que imprime una sentencia en la terminal. como una función.

5 . el programador debería tener una buena idea de cuando omitir tipos y cuando explicitarlos. En este ejemplo. Ilustramos esto en el siguiente ejemplo. } } ) } d e fm a i n ( a r g s :A r r a y [ S t r i n g ] ){ u n a V e z P o r S e g u n d o ( ( )= >p r i n t l n ( " E lt i e m p ov u e l ac o m ou n af l e c h a . El cuerpo de la función es el mismo que en t i e m p o V u e l a del programa anterior. 1 0 . El compilador no es siempre capaz de inferir los tipos como lo hace aquí. que primero mira la parte derecha de estos métodos y puede deducir que ambos retornan un valor de tipo D o u b l e. 6 . c l a s sC o m p l e j o ( r e a l :D o u b l e . we used the predefined method p r i n t l n instead of using the one from S y s t e m . 8 . } d e fr e ( )=r e a l d e fi m ( )=i m a g i n a r i a Esta clase compleja toma dos argumentos. que es utilizada solamente una vez parece un poco innecesario y sería bueno poder construirla justo cuando sea pasada a u n a V e z P o r S e g u n d o. " ) d e fu n a V e z P o r S e g u n d o ( c a l l b a c k :( )= >U n i t ){ w h i l e( t r u e ){c a l l b a c k ( ) . o u t. esto generalmente no es un problema ya que el compilador se queja cuando no es capaz de inferir un tipo que no fue explícitamente fijado. y como tal tiene el concepto de Clase (en realidad existen lenguajes orientados a objetos que no cuentan con el concepto de clases. Esto es posible en Scala utilizando funciones anónimas. 3 ) La clase contiene dos métodos llamados r ee i m.html 4/11 . los programadores de Scala novatos deberían tratar de omitir las declaraciones de tipos que parecen ser simples de deducir del contexto y ver si el compilador no lanza errores. que proveen acceso a las dos partes del número.org/es/tutorials/scala-for-java-programmers. 3 . 5 . dentro de la declaración de u n a V e z P o r S e g u n d o no aparece. Debe notarse que el tipo de retorno de estos dos métodos no está expresado explícitamente. y desafortunadamente no existe una regla simple para saber cuándo será y cuándo no. de la siguiente manera: 1 . Una diferencia importante es que las clases en Scala pueden tener parámetros. Scala es un lenguaje orientado a objetos. Note that in order to print the string. Como regla simple. 7 . pero Scala no es uno de ellos). ya que en ese caso se la está invocando (por eso los paréntesis). Las clases en Scala son declaradas utilizando una sintaxis que es cercana a la de Java. 4 . la lista de argumentos está vacía. pero puede ser refinado aún más. Primero que nada es interesante notar que la función t i e m p o V u e l a está definida solamente para ser pasada posteriormente a la función u n a V e z P o r S e g u n d o. Después de algún tiempo. que son exactamente eso: funciones sin nombre. Clases Como hemos visto anteriormente.i m a g i n a r i a :D o u b l e ){ 2 . Estos argumentos deben ser pasados cuando se crea una instancia de la clase C o m p l e j o. ya que se trata de la función como un “valor”. . Tener que nombrar esa función.scala-lang. n e wC o m p l e j o ( 1 . o b j e c tT e m p o r i z a d o r A n o n i m o{ 2 . Funciones anónimas El programa anterior es fácil de entender. 4 . Por ejemplo. En la práctica. .12/01/14 Tutorial de Scala para programadores Java . La versión revisada de nuestro temporizador utilizando una función anónima luce así: 1 . 3 . Será inferido automáticamente por el compilador.Scala Documentation aparece callback.2 . Métodos sin argumentos docs.T h r e a ds l e e p1 0 0 0} La presencia de una función anónima en este ejemplo es revelada por la flecha a la derecha = > que separa los argumentos de la función del cuerpo de esta. como se ve por el par de paréntesis vacíos a la izquierda de la flecha. 9 . que son las partes real e imaginarias de un número complejo. a diferencia de cómo aparece dentro del método. la definición de un número complejo: 1 .

tanto en la definición como en el uso. 1 . como los árboles rojo y negro. como es el caso de C o m p l e j o se utiliza implícitamente s c a l a . 5 .html 5/11 .3 . La más natural es un árbol.org/es/tutorials/scala-for-java-programmers. a b s t r a c tc l a s sA r b o l 2 .i m a g i n a r i a :D o u b l e ){ 2 .12/01/14 Tutorial de Scala para programadores Java .scala-lang. donde los nodos son las operaciones (la adición en este caso) y las hojas son valores (constantes o variables). Primero tenemos que decidir una representación para tales expresiones. 4 ) p r i n t l n ( " P a r t ei m a g i n a r i a :"+c . nuestra clase C o m p l e j o puede ser aumentada con la redefinición del método t o S t r i n g heredado de O b j e c t. y muchos otros tipos de contenedores están basados en árboles. simplemente al definirlos como métodos sin argumentos. Aquí mostramos como pueden ser usadas para definir el tipo de los árboles en nuestro ejemplo: 1 . los documentos XML son árboles. o b j e c tN u m e r o s C o m p l e j o s{ 2 . } d e fr e=r e a l d e fi m=i m a g i n a r i a o v e r r i d ed e ft o S t r i n g ( )= " "+r e+( i f( i m<0 )" "e l s e" + " )+i m+" i " Clases Case y Reconocimiento de patrones Un tipo de estructura de datos que aparece seguido en programas es el Árbol. Cuando ninguna superclase es especificada. los intérpretes y compiladores usualmente representan los programas internamente como árboles. Ahora examinaremos cómo estos árboles son representados y manipulados en Scala mediante un pequeño programa que oficie de calculadora. Aunque es necesario explicitar específicamente que un método sobreescribe otro utilizando el modificador o v e r r i d e. sin poner los paréntesis vacíos. Esto es perfectamente realizable en Scala. Tales métodos difieren de los métodos con cero o más argumentos en que no tienen paréntesis después de su nombre. 3 .i m a g i n a r i a :D o u b l e ){ 2 . de manera de evitar sobreescrituras accidentales. Dos ejemplos de estas expresiones pueden ser: 1 + 2y ( x + x ) + ( 7 + y ). i m ( ) ) Sería mejor poder acceder las partes imaginarias y reales como si fueran campos. un árbol así sería representado utilizando una superclase abstracta para los árboles. } } d e fm a i n ( a r g s :A r r a y [ S t r i n g ] ){ v a lc=n e wC o m p l e j o ( 1 . c l a s sC o m p l e j o ( r e a l :D o u b l e . 3 . Es posible sobreescribir métodos heredados de una superclase en Scala. A n y R e f. V a ry C o n s t sean declaradas como clases case significa que docs. 4 . Nuestra clase C o m p l e j o puede ser reescrita así: 1 . c a s ec l a s sC o n s t ( v :I n t )e x t e n d sA r b o l El hecho de que las clases S u m. 3 . 5 .r :A r b o l )e x t e n d sA r b o l 3 . 6 . 4 .Scala Documentation Un pequeño problema de los métodos r ee i m es que para poder llamarlos es necesario agregar un par de paréntesis vacíos después de sus nombres. como muestra el siguiente ejemplo: 1 . c a s ec l a s sS u m ( l :A r b o l . } d e fr e=r e a l d e fi m=i m a g i n a r i a Herencia y sobreescritura Todas las clases en Scala heredan de una superclase. c a s ec l a s sV a r ( n :S t r i n g )e x t e n d sA r b o l 4 . 6 . Como ejemplo. c l a s sC o m p l e j o ( r e a l :D o u b l e . 2 . El objetivo de este programa es manipular expresiones aritméticas simples compuestas de sumas de enteros y variables. 4 . Por ejemplo. En Java. Scala provee el concepto de clases case que está en el medio de los dos conceptos anteriores. y una subclase concreta por nodo u hoja. En un lenguaje de programación funcional uno utilizaría un tipo de dato algebraico para el mismo propósito.

démosle un nombre al tipo de los entornos. pero podemos directamente utilizar funciones! Un entorno realmente no es nada más que una función la cual asocia valores a variables. es decir que el árbol no es una S u m. Ahora que hemos definido el tipo de datos para representar nuestra expresión aritmética podemos empezar definiendo operaciones para manipularlas. dado un string " x " como argumento retorna el entero 5. C o n s t ( 1 ) )). si la segunda comprobación también falla. Podríamos por supuesto utilizar alguna estructura de datos asociativa como una tabla hash. es muy sencillo: el valor de una suma de dos expresiones es simplemente la suma de los valores de estas expresiones. y hace que los futuros cambios sean más fáciles. el tipo E n t o r n o puede ser usado como un alias del tipo de funciones definidas de S t r i n ga I n t. } c a s eS u m ( i . El entorno { x > 5 } mostrado anteriormente puede ser fácilmente escrito de la siguiente manera en Scala: 1 . esta expresión puede (y hace) uso de las variables asociadas por el patrón que aparece del lado izquierdo de la flecha.scala-lang. 5 . por lo tanto comprueba que sea un C o n s t. Empezaremos con una función para evaluar una expresión en un entorno.e n v ) c a s eV a r ( n ) = >e n t ( n ) c a s eC o n s t ( v ) = >v Esta función evaluadora función realizando un reconocimiento de patrones (pattern matching) en el árbol a. asocia el sub-arbol izquierdo a una nueva variable llamada i y el sub-arbol derecho a la variable r. Ahora podemos dar la definición de la función evaluadora. si lo es. que trabajan sobre la estructura de las instancias y no sobre su identidad. v). la expresión x + 1 evaluada en un entorno que asocia el valor 5 a la variable x. 4 . {c a s e" x "= >5} Esta notación define una función la cual. 3 . si la primer comprobación (la de S u m) no prospera. El objetivo del entorno es darle valores a las variables. resulta que a no es un S u m ni un V a r.e n t )+e v a l ( d .12/01/14 dififieren de las clases normales en varios aspectos: Tutorial de Scala para programadores Java . 3. Antes de escribir la función evaluadora. el significado de la definición de arriba debería estar claro: 1. Por ejemplo.d )= >e v a l ( i . 4. escrito { x >5 }. pero simplifica el programa introducir un nombre para este tipo. se crea automáticamente un “getter” (un método para obtener el valor) para los parámetros utilizados en el constructor (por ejemplo es posible obtener el valor de v de una instancia c de la clase C o n s t de la siguiente manera: c . Esto lo realizamos de la siguiente manera: 1 . Expresar esto en Scala no resulta para nada difícil: 1 . asocia el valor contenido en el nodo C o n s ta la variable vy procede con el lado derecho.org/es/tutorials/scala-for-java-programmers. se puede escribir C o n s t ( 5 ) en lugar de n e wC o n s t ( 5 )).html 6/11 . da como resultado 6. docs. y el valor de una constante es la constante en sí misma. una excepción es lanzada para dar cuenta el fallo de la expresión. se proveen definiciones por defecto de los métodos e q u a l sy h a s h C o d e. Conceptualmente. y después procede con la evaluación de la expresión que sigue a la flecha ( = >). y si lo es. Por lo tanto tenemos que encontrar una manera de representar entornos. asocia el nombre contenido en el nodo V a ra la variable n y procede con la parte derecha de la expresión. y falla con una excepción si no fuera así. Podríamos por supuesto simplemente utilizar S t r i n g= >I n t para los entornos. esto puede pasar solo si existen más subclases de A r b o l. finalmente. 2. el valor de una variable es obtenido directamente del entorno. t y p eE n t o r n o=S t r i n g= >I n t De ahora en más. Primero comprueba si el árbol tes una S u m. sigue de largo y comprueba si a es un V a r. si todos las comprobaciones fallan.Scala Documentation no es obligatorio utilizar la palabra clave n e w para crear instancias de estas clases (es decir. d e fe v a l ( a :A r b o l . las instancias de estas clases pueden ser descompuestas mediante reconocimiento de patrones (pattern matching) como veremos más abajo.e n t :E n t o r n o ) :I n t=am a t c h{ 2 . y si lo es. se crea una definición por defecto del método t o S t r i n g que imprime el valor de una forma “tipo código) (ej: la expresión del árbol x + 1 se imprimiría S u m ( V a r ( x ) . Intuitivamente.

ya que requiere la modificación en todas las subclases. pero también tiene grandes implicancias en cuanto a la extensibilidad: cuando usamos métodos." x " ) ) p r i n t l n ( " D e r i v a d ac o nr e s p e c t oay : \ n"+d e r i v a d a ( e x p .e n t ) ) p r i n t l n ( " D e r i v a d ac o nr e s p e c t oax : \ n"+d e r i v a d a ( e x p . D e r i v a d ac o nr e s p e c t oay : docs. 5 .r )= >S u m ( d e r i v a d a ( l .y = 7 :2 4 3 . 3 . extraer y nombrar las varias partes del valor para finalmente evaluar algo de código que típicamente hace uso de esas partes nombradas. escrito con el guión bajo _. S u m ( C o n s t ( 7 ) .v ) ) c a s eV a r ( n )i f( v= =n )= >C o n s t ( 1 ) c a s e_= >C o n s t ( 0 ) Esta función introduce dos nuevos conceptos relacionados al pattern matching. pero nos detendremos aquí para mantener este documento corto. C o n s t ( 0 ) ) ) 5 . Por lo tanto decidir en usar reconocimiento de patrones o métodos es una cuestión de gustos. ya que Scala permite la definición de métodos en clases case tal como en clases normales. 1 . para tomar en cuenta un nuevo nodo. E v a l u a c i ó nc o nx = 5 .y = 7 :"+e v a l ( e x p . 4 . En realidad podríamos haberlo hecho. Un programador con experiencia en orientación a objetos puede preguntarse por qué no definimos e v a l como un método de la clase A r b o l y sus subclases.y> 7 } y después computa su derivada con respecto a x y después a y. Para explorar un poco más esto de pattern matching definamos otra operación aritmética: derivación simbólica. cuando utilizamos reconocimiento de patrones esta situación es inversa: agregar un nuevo tipo de nodo requiere la modificación de todas las funciones que hacen reconocimiento de patrones sobre el árbol. la derivada de una suma es la suma de las derivadas.scala-lang. por otro lado." y " ) ) Al ejecutar este programa obtenemos el siguiente resultado: 1 . } c a s eS u m ( l . 3 . para obtener la siguiente definición. 8 .org/es/tutorials/scala-for-java-programmers. es fácil añadir un nuevo tipo de nodo ya que esto puede ser realizado simplemente al definir una nueva subclase de A r b o l. V a r ( x ) ) . Aquí es usada para asegurarse que retornamos la constante 1 solo si el nombre de la variable siendo derivada es el mismo que la variable derivada v. E x p r e s i ó n :S u m ( S u m ( V a r ( x ) . Todavía nos queda pendiente ver cómo funcionan las dos funciones de arriba en un ejemplo real. Para ese propósito. Estas reglas pueden ser traducidas casi literalmente en código Sclaa. V a r ( y ) ) ) 2 .Scala Documentation Hemos visto que la idea básica del reconocimiento de patrones es intentar coincidir un valor con una serie de patrones.12/01/14 Tutorial de Scala para programadores Java . d e fm a i n ( a r g s :A r r a y [ S t r i n g ] ){ 2 . 3. pero por otro lado agregar una nueva operación fácil. 7 . que coincide con cualquier valor que aparezca. añadir una nueva operación para manipular el árbol es tedioso. S u m ( C o n s t ( 7 ) . d e fd e r i v a d a ( a :A r b o l . C o n s t ( 1 ) ) .html 7/11 . El segundo concepto nuevo usado aquí es el comodín. 2. } v a le x p :A r b o l=S u m ( S u m ( V a r ( " x " ) . 5 . D e r i v a d ac o nr e s p e c t oax : 4 .v :S t r i n g ) :A r b o l=am a t c h{ 2 . S u m ( S u m ( C o n s t ( 1 ) . sin darle un nombre. la derivada de una constante es cero (0). 6 . solamente definiendolo como una función independiente. V a r ( " y " ) ) ) v a le n t :E n t o n r n o={c a s e" x "= >5c a s e" y "= >7} p r i n t l n ( " E x p r e s i ó n :"+e x p ) p r i n t l n ( " E v a l u a c i ó nc o nx = 5 . escribamos una función main simple que realice algunas operaciones sobre la expresión ( x + x ) + ( 7 + y ): primero computa su valor en el entorno { x >5 . El lector recordará las siguientes reglas sobre esta operación: 1. y cero (0)de otra manera. una expresión siguiendo la palabra clave i f. V a r ( " x " ) ) .v ) . S u m ( C o n s t ( 0 ) .d e r i v a d a ( r . y tan pronto como un patrón coincida. 1 . Esta guarda previene que el patrón concuerde al menos que la expresión sea verdadera. la derivada de una variable v es uno (1) si v es la variable relativa a la cual la derivada toma lugar. No hemos explorado el completo poder del pattern matching aún. 4 . Primero que nada la expresión c a s e para variables tienen una guarda.

12/01/14 6 . El tipo A n y el cual es usado arriba es el supertipo de todos los otros tipos en Scala. especialmente que cuatro de estos pueden ser expresados en base a los otros dos. 4 . La implementación por defecto de e q u a l s no es utilizable. uno puede expresar los otros. 3 . menor o igual. y hereda todo el código contenido en el trait. Para ver la utilidad de los traits. a n n o = =a n n o docs. una clase en Scala puede también importar código de uno o varios traits. veamos un ejemplo clásico: objetos ordenados. que necesita una solución astuta). 5 . d e fa n n o=a d e fm e s=m d e fd i a=d o v e r r i d ed e ft o S t r i n g ( ) :S t r i n g=a n n o+" "+m e s+" "+d i a La parte importante aquí es la declaración e x t e n d sO r d la cual sigue al nombre de la clase y los parámetros. por ejemplo. Después redefinimos el método e q u a l s. Como un ejemplo. Tutorial de Scala para programadores Java . En Scala. C o n s t ( 1 ) ) ) Al examinar la salida vemos que el resultado de la derivada debería ser simplificado antes de ser presentado al usuario. ya que A n y también es supertipo de I n t. podemos hacer algo un poco mejor que en Java al definir un trait equivalente C o m p a r a b l e que invocará a O r d. t h a t . 4 . Tal vez la forma más fácil para un programador Java de entender qué son los traits es verlos como interfaces que también pueden contener código. compara los objetos físicamente.a :I n t )e x t e n d sO r d{ 2 . Esto es. Para hacer a un objeto de la clase comparable es suficiente definir los predicados que comprueban la igualdad y la inferioridad y mezclar la clase O r d de arriba. cosa que no se cumple en Java ( i n t por ejemplo es un tipo primitivo). i s I n s t a n c e O f [ F e c h a ]& &{ v a lo=t h a t . Por lo tanto llegamos a esto: 1 .org/es/tutorials/scala-for-java-programmers. 3 . igual. implementa la interface de ese trait. 4 . dados los predicados “igual” y “menor” (por ejemplo). d i a = =d i a& &o . como también provee implementaciones de tres predicados en términos de un cuarto. c l a s sF e c h a ( d :I n t . distinto. De todas maneras. por no decir complejo. todas estas observaciones pueden ser fácilmente capturadas mediante la siguiente declaración de un Trait: 1 . m e s= =m e s& &o .html 8/11 . lo dejamos para un ejercicio para el lector. De todas maneras decido utilizar la notación original por ser un concepto muy arraigado a Scala Aparte de poder heredar código de una super clase. Puede ser visto como una versión más general del tipo O b j e c t en Java. 1 . definir todos estos es fastidioso. C o n s t ( 0 ) ) . o v e r r i d ed e fe q u a l s ( t h a t :A n y ) :B o o l e a n= 2 . Generalmente es útil tener la posibilidad de comparar objetos de una clase dada entre ellos. a s I n s t a n c e O f [ F e c h a ] o . S u m ( C o n s t ( 0 ) . pronunciado Treit) puede ser traducida literalmente como “Rasgo”. cuando una clase hereda de un trait. para ordenarlos. no igual) no aparecen aquí ya que por defecto están presenten en todos los objetos. los objetos que son comparables implementan la interfaz C o m p a r a b l e. En Scala. En Java. 5 . Definir una función de simplificación básica utilizando reconocimiento de patrones es un problema interesante (y. Cuando comparamos objetos podemos utilizar seis predicados distintos: menor. Traits Nota: La palabra Trait(/treɪt/. abstracto. En Scala. para comparar correctamente fechas mediante sus campos individuales.scala-lang. Declara que la clase F e c h a hereda del trait O r d. mayor o igual y mayor. } d e f<( t h a t :A n y ) :B o o l e a n d e f< = ( t h a t :A n y ) :B o o l e a n= ( t h i s<t h a t )| |( t h i s= =t h a t ) d e f>( t h a t :A n y ) :B o o l e a n=! ( t h i s< =t h a t ) d e f> = ( t h a t :A n y ) :B o o l e a n=! ( t h i s<t h a t ) Esta definición crea un nuevo tipo llamado O r d el cual juega el mismo rol que la interfaz C o m p a r a b l e.Scala Documentation S u m ( S u m ( C o n s t ( 0 ) . heredado de O b j e c t.m :I n t . Los predicados para igualidad y su inverso (distinto. F l o a t. definamos una clase F e c h a que representa fechas en el calendario gregoriano. 6 . t r a i tO r d{ 2 . porque como en Java. etc. 3 .

esta es vista como tal. 5 . La última característica de Scala que exploraremos en este tutorial es la de los tipos genéricos. a n n o )| | ( a n n o = =o . El segundo. l o n g. Este hace uso de otro método predefinido. lo cual es solucionado en Java 1. Este tipo es usado en el cuerpo de la clase como el tipo de la variable c o n t e n i d o. digamos. Scala hace posible definir clases genéricas (y métodos) para resolver este problema. i s I n s t a n c e O f [ F e c h a ] ) e r r o r ( " n os ep u e d ec o m p a r a r "+t h a t+"yu n af e c h a " ) Esto completa la definición de la clase F e c h a. que puede estar tanto vacía como apuntar a un objeto de algún tipo. Los programadores de Java deben estar bien al tanto de los problemas que genera la falta de genéricos en su lenguaje. m e s| | ( m e s= =o . Los tipos genéricos proveen al programador la habilidad de escribir código parametrizado por tipos. ya que no funciona con tipos primitivos ( i n t.scala-lang. } Tutorial de Scala para programadores Java . c l a s sR e f e r e n c i a [ T ]{ 2 . 4 . pero discutir sus aplicaciones está fuera del alcance de este documento. Ya que esta lista está pensada para ser usada en diferentes contextos. m e s& &d i a<o . El ejemplo anterior introduce a las variables en Scala. que es el tipo de sus elementos.Scala Documentation Este método utiliza el método predefinido i s I n s t a n c e O f (“es instancia de”) y a s I n s t a n c e O f (“como instancia de”). 3 . El primero i s I n s t a n c e O f se corresponde con el operador java i n s t a n c e O f y retorna t r u e si y solo si el objeto en el cual es aplicado es una instancia del tipo dado.5. que es el supertipo de todos los objetos. Además. Los programadores Java cuentan como último recurso con O b j e c t. 8 . ( ) para el tipo U n i ty n u l l para el resto de los objetos.) e implica que el programador tenga que realizar muchos casteos de tipos en su programa.org/es/tutorials/scala-for-java-programmers. escribir una librería para listas enlazadas se enfrenta al problema de decidir qué tipo darle a los elementos de la lista. de otra manera se lanza una excepción C l a s s C a s t E x c e p t i o n. no es posible decidir que el tipo de elementos sea. Por ejemplo. f a l s e para tipos B o o l e a n. 4 . Para utilizar esta clase R e f e r e n c i a. Este valor por defecto es 0 para tipos numéricos. etc.html 9/11 . que representa un valor por defecto. 3 . 1 . Tipos Genéricos Nota: El diseñador de los tipos genéricos en Java fue nada más ni nada menos que Martin Odersky. Las instancias de esta clase pueden ser vistas tanto como fechas o como objetos comparables. que no deberían requerir mayor explicación. I n t. a s I n s t a n c e O f [ F e c h a ] ( a n n o<o . Los traits son útiles en muchas otras más situaciones que las aquí mostrada. } p r i v a t ev a rc o n t e n i d o :T=_ d e fs e t ( v a l o r :T ){c o n t e n i d o=v a l o r} d e fg e t :T=c o n t e n i d o La clase R e f e r e n c i a es parametrizada por un tipo llamado T. docs. Esta solución de todas maneras está lejos de ser ideal. uno necesita especificar qué tipo utilizar por el parámetro T. Es interesante notar que el valor inicial dado a la variable c o n t e n i d o es _. d i a ) ) ) i f( ! t h a t . 7 . el diseñador de Scala. Esto sería completamente arbitrario y muy restrictivo. el argumento del método s e t y el tipo de retorno del método g e t. 5 . todas ellas definen los seis predicados de comparación mencionados arriba: e q u a l s y < porque aparecen directamente en la definición de la clase F e c h a y los otros porque son heredados del trait O r d. Finalmente el último método para definir es el predicado que comprueba la inferioridad. e r r o r que lanza una excepción con el mensaje de error provisto. f l o a t. 9 . a n n o& &( m e s<o . } v a lo=t h a t . d e f< ( t h a t :A n y ) :B o o l e a n={ 2 . Examinemos esto con un ejemplo del contenedor más simple posible: una referencia. a s I n s t a n c e O f.12/01/14 5 . 1 . corresponde al operador de casteo en Java: si el objeto es una instancia de un tipo dado. 6 .

el tipo del elemento contenido por la referencia. 2 comments Join the discussion… Best Community victor pacheco • 3 months ago 2 Share Login Muchas gracias por traducir el pdf http://www. para crear y utilizar una referencia que contenga un entero. Java no es la excepción. También puede consultar la especificación del lenguaje cuando lo desee. 7 . El solo pensar en el código necesario para proveer a un J B u t t o n con el código que debe ejecutar al ser presionado nos muestra lo necesario que sería contar con herramientas funcionales. Scala los aumenta.Scala Documentation es decir. La diferencia que vemos es que para cada uno de los conceptos de Java.12/01/14 Tutorial de Scala para programadores Java . Por ejemplo..org/docu. el programador experimentado puede notar la falta de soporte de este paradigma en múltiples ocasiones. no es necesario castear el valor retornado por el método g e t antes de usarlo como un entero. docs. Si bien la programación funcional no ha sido una característica de Java.. Conclusión Scala es un lenguaje tremendamente poderoso que ha sabido heredar las mejores cosas de cada uno de los lenguajes más exitosos que se han conocido. • Reply • Share › Henser Villar Herrera • a year ago hay unos errores con los nombres de las variables en la parte de Clases Case y Reconocimiento de patrones.. 3 . • Reply • Share › Subscribe Add Disqus to your site API Current Nightly Learn Guides & Overviews Tutorials Scala Style Guide Quickref Glossary Cheatsheets Contribute Source Code Contributors Guide Suggestions Other Resources Wiki Scala Improvement Process Copyright © 2011-2013 EPFL. aparecen los nombres de la version en ingles. podríamos escribir lo siguiente: 1 . o b j e c tR e f e r e n c i a E n t e r o{ 2 . ya que fue declarada como contenedora de un entero. Tampoco es posible almacenar otra cosa que no sea un entero en esa referencia en particular. por más que sea difícil para el programador Java al estar tan acostumbrado al paradigma imperativo de este lenguaje. } } d e fm a i n ( a r g s :A r r a y [ S t r i n g ] ){ v a lr e f=n e wR e f e r e n c i a [ I n t ] r e f . s e t ( 1 3 ) p r i n t l n ( " L ar e f e r n c i at i e n el am i t a dd e"+( r e f .org/es/tutorials/scala-for-java-programmers.scala-lang. Poder aprender todas las características de Scala nos equipa con más y mejores herramientas a la hora de escribir nuestros programas. 4 . El lector interesado puede seguir.html 10/11 . leyendo el Tutorial de Scala que figura en el sitio de documentación. y comparte muchas cosas con este. All rights reserved. Recomendamos entonces tratar de ir incorporando estas características.. Este documento dio una rápida introducción al lenguaje Scala y presento algunos ejemplos básicos. g e t*2 ) ) Como puede verse en el ejemplo. 6 . refina y mejora. por ejemplo.scala-lang. o Scala by Example (en inglés). 5 .

html 11/11 .12/01/14 Tutorial de Scala para programadores Java .scala-lang.Scala Documentation docs.org/es/tutorials/scala-for-java-programmers.