Sunteți pe pagina 1din 11

12/01/14

Tutorial de Scala para programadores Java - Scala Documentation

Tutorial de Scala para programadores Java


Por Michel Schinz y Philipp Haller. Traduccin y arreglos Santiago Basulto.

Introduccin
Este documento provee una rpida introduccin al lenguaje Scala como tambin a su compilador. Est pensado para personas que ya poseen cierta experiencia en programacin y quieren una vista rpida de lo que pueden hacer con Scala. Se asume como un conocimiento bsico de programacin orientada a objetos, especialmente en Java.

Un primer ejemplo Documentation

API Learn Quickref Contribute SIPs Wiki Como primer ejemplo, usaremos el programa Hola mundo estndar. No es muy fascinante, pero de esta manera resulta fcil 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
Introduccin Un primer ejemplo Compilando el ejemplo Ejecutando el ejemplo Interaccin con Java Todo es un objeto Los nmeros son objetos Las funciones son objetos Funciones annimas Clases Mtodos sin argumentos Herencia y sobreescritura Clases Case y Reconocimiento de patrones Traits Tipos Genricos Conclusin

La estructura de este programa debera ser familiar para programadores Java: consiste de un mtodo llamado m a i n que toma los argumentos de la lnea de comando (un array de objetos String) como parmetro; el cuerpo de este mtodo consiste en una sola llamada al mtodo predefinido p r i n t l n con el saludo amistoso como argumento. El mtodo 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 declaracin de o b j e c t que contiene al mtodo m a i n. Esa declaracin introduce lo que es comnmente conocido como objeto singleton, que es una clase con una sola instancia. Por lo tanto, dicha construccin declara tanto una clase llamada H o l a M u n d o como una instancia de esa clase tambin 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 mtodo m a i n no es declarado como s t a t i c. Esto es as porque los miembros estticos (mtodos o campos) no existen en Scala. En vez de definir miembros estticos, 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 mayora 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 estndar. 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 smbolo 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 seccin.

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

12/01/14
1 . >s c a l ac l a s s p a t h.H o l a M u n d o 2 . 3 . H o l a ,m u n d o !

Tutorial de Scala para programadores Java - Scala Documentation

Interaccin con Java


Una de las fortalezas de Scala es que hace muy fcil interactuar con cdigo Java. Todas las clases del paquete j a v a . l a n g son importadas por defecto, mientras otras necesitan ser importadas explcitamente. Veamos un ejemplo que demuestra esto. Queremos obtener y formatear la fecha actual de acuerdo a convenciones utilizadas en un pas especfico, por ejemplo Francia. Las libreras de clases de Java definen clases de utilera poderosas, como D a t ey D a t e F o r m a t. Ya que Scala interacciona fcilmente con Java, no es necesario implementar estas clases equivalentes en las libreras de Scala podemos simplemente importar las clases de los correspondientes paquetes de Java:
1 . i m p o r tj a v a . u t i l . { D a t e ,L o c a l e } 2 . i m p o r tj a v a . t e x t . D a t e F o r m a t 3 . i m p o r tj a v a . t e x t . D a t e F o r m a t . _ 4 . 5 . o b j e c tF r e n c h D a t e{ 6 . 7 . 8 . 9 . 1 0 . 1 1 . } } 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 ,L o c a l e . 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 importacin de Scala lucen muy similares a las de Java, sin embargo, las primeras son bastante ms poderosas. Mltiples clases pueden ser importadas desde el mismo paquete al encerrarlas en llaves como se muestra en la primer lnea. Otra diferencia es que podemos importar todos los nombres de un paquete o clase, utilizando el carcter guin bajo ( _) en vez del asterisco ( *). Eso es porque el asterisco es un identificador vlido en Scala (quiere decir que por ejemplo podemos nombrar a un mtodo *), como veremos ms adelante. La declaracin i m p o r t en la tercer lnea por lo tanto importa todos los miembros de la clase D a t e F o r m a t. Esto hace que el mtodo esttico g e t D a t e I n s t a n c e y el campo esttico L O N G sean directamente visibles. Dentro del mtodo m a i n primero creamos una instancia de la clase D a t e la cual por defecto contiene la fecha actual. A continuacin definimos un formateador de fechas utilizando el mtodo esttico g e t D a t e I n s t a n c e que importamos previamente. Finalmente, imprimimos la fecha actual formateada de acuerdo a la instancia de D a t e F o r m a t que fue localizada. Esta ltima lnea muestra una propiedad interesante de la sintaxis de Scala. Los mtodos que toman un solo argumento pueden ser usados con una sintaxis de infijo Es decir, la expresin
1 . d ff o r m a ta h o r a

es solamente otra manera ms corta de escribir la expresin:


1 . d f . f o r m a t ( a h o r a )

Esto parece tener como un detalle sintctico menor, pero tiene importantes consecuencias, una de ellas la exploraremos en la prxima seccin. Para concluir esta seccin sobre la interaccin con Java, es importante notar que es tambin posible heredar de clases Java e implementar interfaces Java directamente en Scala.

Todo es un objeto
Scala es un lenguaje puramente orientado a objetos en el sentido de que todo es un objeto, incluyendo nmeros o funciones. Difiere de Java en este aspecto, ya que Java distingue tipos primitivos (como b o o l e a ne i n t) de tipos referenciales, y no nos permite manipular las funciones como valores.

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

2/11

12/01/14

Tutorial de Scala para programadores Java - Scala Documentation

Los nmeros son objetos


Ya que los nmeros son objetos, estos tambin tienen mtodos. De hecho, una expresin aritmtica como la siguiente:
1 . 1+2*3/x

Consiste exclusivamente de llamadas a mtodos, porque es equivalente a la siguiente expresin, como vimos en la seccin anterior:
1 . ( 1 ) . + ( ( ( 2 ) . * ( 3 ) ) . / ( x ) )

Esto tambin indica que +, *, etc. son identificadores vlidos en Scala. Los parntesis alrededor de los nmeros en la segunda versin son necesarios porque el analizador lxico de Scala usa la regla de mayor coincidencia. Por lo tanto partira la siguiente expresin:
1 . 1 . + ( 2 )

En estas partes: 1 ., +, y 2. La razn que esta regla es elegida es porque 1 . es una coincidencia vlida y es mayor que 1, haciendo a este un D o u b l e en vez de un I n t. Al escribir la expresin as:
1 . ( 1 ) . + ( 2 )

previene que el 1 sea tomado como un D o u b l e.

Las funciones son objetos


Tal vez suene ms sorprendente para los programadores Java, las funciones en Scala tambin son objetos. Por lo tanto es posible pasar funciones como argumentos, almacenarlas en variables, y retornarlas desde otras funciones. Esta habilidad de manipular funciones como valores es una de las valores fundamentales de un paradigma de programacin muy interesante llamado programacin funcional. Como un ejemplo muy simple de por qu puede ser til usar funciones como valores consideremos una funcin temporizador (o timer, en ingls) cuyo propsito es realizar alguna accin cada un segundo. Cmo pasamos al temporizador la accin a realizar? Bastante lgico, como una funcin. Este simple concepto de pasar funciones debera ser familiar para muchos programadores: es generalmente utilizado en cdigo relacionado con Interfaces grficas de usuario (GUIs) para registrar retrollamadas (call-back en ingls) que son invocadas cuando un evento ocurre. En el siguiente programa, la funcin del temporizador se llama u n a V e z P o r S e g u n d o y recibe una funcin call-back como argumento. El tipo de esta funcin 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++). La funcin principal de este programa simplemente invoca esta funcin temporizador con una call-back que imprime una sentencia en la terminal. En otras palabras, este programa imprime interminablemente la sentencia El tiempo vuela como una flecha cada segundo.
1 . o b j e c tT e m p o r i z a d o r{ 2 . 3 . 4 . 5 . 6 . 7 . 8 . 9 . 1 0 . 1 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 . . . " ) 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 ( ) ;T h r e a ds l e e p1 0 0 0}

Nota: si nunca tuviste experiencias previas con programacin funcional te recomiendo que te tomes unos segundos para analizar cuando se utilizan parntesis y cuando no en los lugares donde

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

3/11

12/01/14

Tutorial de Scala para programadores Java - Scala Documentation

aparece callback. Por ejemplo, dentro de la declaracin de u n a V e z P o r S e g u n d o no aparece, ya que se trata de la funcin como un valor, a diferencia de cmo aparece dentro del mtodo, ya que en ese caso se la est invocando (por eso los parntesis). Note that in order to print the string, we used the predefined method p r i n t l n instead of using the one from S y s t e m . o u t.

Funciones annimas
El programa anterior es fcil de entender, pero puede ser refinado an ms. Primero que nada es interesante notar que la funcin t i e m p o V u e l a est definida solamente para ser pasada posteriormente a la funcin u n a V e z P o r S e g u n d o. Tener que nombrar esa funcin, que es utilizada solamente una vez parece un poco innecesario y sera bueno poder construirla justo cuando sea pasada a u n a V e z P o r S e g u n d o. Esto es posible en Scala utilizando funciones annimas, que son exactamente eso: funciones sin nombre. La versin revisada de nuestro temporizador utilizando una funcin annima luce as:
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 . 3 . 4 . 5 . 6 . 7 . 8 . 9 . 1 0 . } } ) } 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 . . . " ) 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 ( ) ;T h r e a ds l e e p1 0 0 0}

La presencia de una funcin annima en este ejemplo es revelada por la flecha a la derecha = > que separa los argumentos de la funcin del cuerpo de esta. En este ejemplo, la lista de argumentos est vaca, como se ve por el par de parntesis vacos a la izquierda de la flecha. El cuerpo de la funcin es el mismo que en t i e m p o V u e l a del programa anterior.

Clases
Como hemos visto anteriormente, Scala es un lenguaje orientado a objetos, y como tal tiene el concepto de Clase (en realidad existen lenguajes orientados a objetos que no cuentan con el concepto de clases, pero Scala no es uno de ellos). Las clases en Scala son declaradas utilizando una sintaxis que es cercana a la de Java. Una diferencia importante es que las clases en Scala pueden tener parmetros. Ilustramos esto en el siguiente ejemplo, la definicin de un nmero complejo:
1 . c l a s sC o m p l e j o ( r e a l :D o u b l e ,i m a g i n a r i a :D o u b l e ){ 2 . 3 . 4 . } 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 son las partes real e imaginarias de un nmero complejo. Estos argumentos deben ser pasados cuando se crea una instancia de la clase C o m p l e j o, de la siguiente manera:
1 . n e wC o m p l e j o ( 1 . 5 ,2 . 3 )

La clase contiene dos mtodos llamados r ee i m, que proveen acceso a las dos partes del nmero. Debe notarse que el tipo de retorno de estos dos mtodos no est expresado explcitamente. Ser inferido automticamente por el compilador, que primero mira la parte derecha de estos mtodos y puede deducir que ambos retornan un valor de tipo D o u b l e. El compilador no es siempre capaz de inferir los tipos como lo hace aqu, y desafortunadamente no existe una regla simple para saber cundo ser y cundo no. En la prctica, esto generalmente no es un problema ya que el compilador se queja cuando no es capaz de inferir un tipo que no fue explcitamente fijado. Como regla simple, los programadores de Scala novatos deberan tratar de omitir las declaraciones de tipos que parecen ser simples de deducir del contexto y ver si el compilador no lanza errores. Despus de algn tiempo, el programador debera tener una buena idea de cuando omitir tipos y cuando explicitarlos.

Mtodos sin argumentos


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

12/01/14

Tutorial de Scala para programadores Java - Scala Documentation

Un pequeo problema de los mtodos r ee i m es que para poder llamarlos es necesario agregar un par de parntesis vacos despus de sus nombres, como muestra el siguiente ejemplo:
1 . o b j e c tN u m e r o s C o m p l e j o s{ 2 . 3 . 4 . 5 . 6 . } } 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 . 2 ,3 . 4 ) p r i n t l n ( " P a r t ei m a g i n a r i a :"+c . i m ( ) )

Sera mejor poder acceder las partes imaginarias y reales como si fueran campos, sin poner los parntesis vacos. Esto es perfectamente realizable en Scala, simplemente al definirlos como mtodos sin argumentos. Tales mtodos difieren de los mtodos con cero o ms argumentos en que no tienen parntesis despus de su nombre, tanto en la definicin como en el uso. Nuestra clase C o m p l e j o puede ser reescrita as:
1 . c l a s sC o m p l e j o ( r e a l :D o u b l e ,i m a g i n a r i a :D o u b l e ){ 2 . 3 . 4 . } 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. Cuando ninguna superclase es especificada, como es el caso de C o m p l e j o se utiliza implcitamente s c a l a . A n y R e f. Es posible sobreescribir mtodos heredados de una superclase en Scala. Aunque es necesario explicitar especficamente que un mtodo sobreescribe otro utilizando el modificador o v e r r i d e, de manera de evitar sobreescrituras accidentales. Como ejemplo, nuestra clase C o m p l e j o puede ser aumentada con la redefinicin del mtodo t o S t r i n g heredado de O b j e c t.
1 . c l a s sC o m p l e j o ( r e a l :D o u b l e ,i m a g i n a r i a :D o u b l e ){ 2 . 3 . 4 . 5 . 6 . } 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. Por ejemplo, los intrpretes y compiladores usualmente representan los programas internamente como rboles; los documentos XML son rboles; y muchos otros tipos de contenedores estn basados en rboles, como los rboles rojo y negro. Ahora examinaremos cmo estos rboles son representados y manipulados en Scala mediante un pequeo programa que oficie de calculadora. El objetivo de este programa es manipular expresiones aritmticas simples compuestas de sumas de enteros y variables. Dos ejemplos de estas expresiones pueden ser: 1 + 2y ( x + x ) + ( 7 + y ). Primero tenemos que decidir una representacin para tales expresiones. La ms natural es un rbol, donde los nodos son las operaciones (la adicin en este caso) y las hojas son valores (constantes o variables). En Java, un rbol as sera representado utilizando una superclase abstracta para los rboles, y una subclase concreta por nodo u hoja. En un lenguaje de programacin funcional uno utilizara un tipo de dato algebraico para el mismo propsito. Scala provee el concepto de clases case que est en el medio de los dos conceptos anteriores. Aqu mostramos como pueden ser usadas para definir el tipo de los rboles en nuestro ejemplo:
1 . a b s t r a c tc l a s sA r b o l 2 . c a s ec l a s sS u m ( l :A r b o l ,r :A r b o l )e x t e n d sA r b o l 3 . 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 . 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, V a ry C o n s t sean declaradas como clases case significa que

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

5/11

12/01/14
dififieren de las clases normales en varios aspectos:

Tutorial de Scala para programadores Java - Scala Documentation

no es obligatorio utilizar la palabra clave n e w para crear instancias de estas clases (es decir, se puede escribir C o n s t ( 5 ) en lugar de n e wC o n s t ( 5 )), se crea automticamente un getter (un mtodo para obtener el valor) para los parmetros 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 . v), se proveen definiciones por defecto de los mtodos e q u a l sy h a s h C o d e, que trabajan sobre la estructura de las instancias y no sobre su identidad, se crea una definicin por defecto del mtodo t o S t r i n g que imprime el valor de una forma tipo cdigo) (ej: la expresin del rbol x + 1 se imprimira S u m ( V a r ( x ) , C o n s t ( 1 ) )), las instancias de estas clases pueden ser descompuestas mediante reconocimiento de patrones (pattern matching) como veremos ms abajo. Ahora que hemos definido el tipo de datos para representar nuestra expresin aritmtica podemos empezar definiendo operaciones para manipularlas. Empezaremos con una funcin para evaluar una expresin en un entorno. El objetivo del entorno es darle valores a las variables. Por ejemplo, la expresin x + 1 evaluada en un entorno que asocia el valor 5 a la variable x, escrito { x >5 }, da como resultado 6. Por lo tanto tenemos que encontrar una manera de representar entornos. Podramos por supuesto utilizar alguna estructura de datos asociativa como una tabla hash, pero podemos directamente utilizar funciones! Un entorno realmente no es nada ms que una funcin la cual asocia valores a variables. El entorno { x > 5 } mostrado anteriormente puede ser fcilmente escrito de la siguiente manera en Scala:
1 . {c a s e" x "= >5}

Esta notacin define una funcin la cual, dado un string " x " como argumento retorna el entero 5, y falla con una excepcin si no fuera as. Antes de escribir la funcin evaluadora, dmosle un nombre al tipo de los entornos. Podramos por supuesto simplemente utilizar S t r i n g= >I n t para los entornos, pero simplifica el programa introducir un nombre para este tipo, y hace que los futuros cambios sean ms fciles. Esto lo realizamos de la siguiente manera:
1 . t y p eE n t o r n o=S t r i n g= >I n t

De ahora en ms, 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. Ahora podemos dar la definicin de la funcin evaluadora. Conceptualmente, es muy sencillo: el valor de una suma de dos expresiones es simplemente la suma de los valores de estas expresiones; el valor de una variable es obtenido directamente del entorno; y el valor de una constante es la constante en s misma. Expresar esto en Scala no resulta para nada difcil:
1 . d e fe v a l ( a :A r b o l ,e n t :E n t o r n o ) :I n t=am a t c h{ 2 . 3 . 4 . 5 . } c a s eS u m ( i ,d )= >e v a l ( i ,e n t )+e v a l ( d ,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 funcin evaluadora funcin realizando un reconocimiento de patrones (pattern matching) en el rbol a. Intuitivamente, el significado de la definicin de arriba debera estar claro: 1. Primero comprueba si el rbol tes una S u m, y si lo es, asocia el sub-arbol izquierdo a una nueva variable llamada i y el sub-arbol derecho a la variable r, y despus procede con la evaluacin de la expresin que sigue a la flecha ( = >); esta expresin puede (y hace) uso de las variables asociadas por el patrn que aparece del lado izquierdo de la flecha. 2. si la primer comprobacin (la de S u m) no prospera, es decir que el rbol no es una S u m, sigue de largo y comprueba si a es un V a r; si lo es, asocia el nombre contenido en el nodo V a ra la variable n y procede con la parte derecha de la expresin. 3. si la segunda comprobacin tambin falla, resulta que a no es un S u m ni un V a r, por lo tanto comprueba que sea un C o n s t, y si lo es, asocia el valor contenido en el nodo C o n s ta la variable vy procede con el lado derecho. 4. finalmente, si todos las comprobaciones fallan, una excepcin es lanzada para dar cuenta el fallo de la expresin; esto puede pasar solo si existen ms subclases de A r b o l.

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

6/11

12/01/14

Tutorial de Scala para programadores Java - Scala Documentation

Hemos visto que la idea bsica del reconocimiento de patrones es intentar coincidir un valor con una serie de patrones, y tan pronto como un patrn coincida, extraer y nombrar las varias partes del valor para finalmente evaluar algo de cdigo que tpicamente hace uso de esas partes nombradas. Un programador con experiencia en orientacin a objetos puede preguntarse por qu no definimos e v a l como un mtodo de la clase A r b o l y sus subclases. En realidad podramos haberlo hecho, ya que Scala permite la definicin de mtodos en clases case tal como en clases normales. Por lo tanto decidir en usar reconocimiento de patrones o mtodos es una cuestin de gustos, pero tambin tiene grandes implicancias en cuanto a la extensibilidad: cuando usamos mtodos, es fcil aadir un nuevo tipo de nodo ya que esto puede ser realizado simplemente al definir una nueva subclase de A r b o l; por otro lado, aadir una nueva operacin para manipular el rbol es tedioso, ya que requiere la modificacin en todas las subclases. cuando utilizamos reconocimiento de patrones esta situacin es inversa: agregar un nuevo tipo de nodo requiere la modificacin de todas las funciones que hacen reconocimiento de patrones sobre el rbol, para tomar en cuenta un nuevo nodo; pero por otro lado agregar una nueva operacin fcil, solamente definiendolo como una funcin independiente. Para explorar un poco ms esto de pattern matching definamos otra operacin aritmtica: derivacin simblica. El lector recordar las siguientes reglas sobre esta operacin: 1. la derivada de una suma es la suma de las derivadas, 2. la derivada de una variable v es uno (1) si v es la variable relativa a la cual la derivada toma lugar, y cero (0)de otra manera, 3. la derivada de una constante es cero (0). Estas reglas pueden ser traducidas casi literalmente en cdigo Sclaa, para obtener la siguiente definicin.
1 . d e fd e r i v a d a ( a :A r b o l ,v :S t r i n g ) :A r b o l=am a t c h{ 2 . 3 . 4 . 5 . } c a s eS u m ( l ,r )= >S u m ( d e r i v a d a ( l ,v ) ,d e r i v a d a ( r ,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 funcin introduce dos nuevos conceptos relacionados al pattern matching. Primero que nada la expresin c a s e para variables tienen una guarda, una expresin siguiendo la palabra clave i f. Esta guarda previene que el patrn concuerde al menos que la expresin sea verdadera. 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. El segundo concepto nuevo usado aqu es el comodn, escrito con el guin bajo _, que coincide con cualquier valor que aparezca, sin darle un nombre. No hemos explorado el completo poder del pattern matching an, pero nos detendremos aqu para mantener este documento corto. Todava nos queda pendiente ver cmo funcionan las dos funciones de arriba en un ejemplo real. Para ese propsito, escribamos una funcin main simple que realice algunas operaciones sobre la expresin ( x + x ) + ( 7 + y ): primero computa su valor en el entorno { x >5 ,y> 7 } y despus computa su derivada con respecto a x y despus a y.
1 . d e fm a i n ( a r g s :A r r a y [ S t r i n g ] ){ 2 . 3 . 4 . 5 . 6 . 7 . 8 . } v a le x p :A r b o l=S u m ( S u m ( V a r ( " x " ) , V a r ( " x " ) ) , S u m ( C o n s t ( 7 ) , 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 ,y = 7 :"+e v a l ( 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 ," 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 ," y " ) )

Al ejecutar este programa obtenemos el siguiente resultado:


1 . E x p r e s i n :S u m ( S u m ( V a r ( x ) , V a r ( x ) ) , S u m ( C o n s t ( 7 ) , V a r ( y ) ) ) 2 . E v a l u a c i nc o nx = 5 ,y = 7 :2 4 3 . D e r i v a d ac o nr e s p e c t oax : 4 . S u m ( S u m ( C o n s t ( 1 ) , C o n s t ( 1 ) ) , S u m ( C o n s t ( 0 ) , C o n s t ( 0 ) ) ) 5 . D e r i v a d ac o nr e s p e c t oay :

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

7/11

12/01/14
6 .

Tutorial de Scala para programadores Java - Scala Documentation


S u m ( S u m ( C o n s t ( 0 ) , C o n s t ( 0 ) ) , S u m ( C o n s t ( 0 ) , C o n s t ( 1 ) ) )

Al examinar la salida vemos que el resultado de la derivada debera ser simplificado antes de ser presentado al usuario. Definir una funcin de simplificacin bsica utilizando reconocimiento de patrones es un problema interesante (y, por no decir complejo, que necesita una solucin astuta), lo dejamos para un ejercicio para el lector.

Traits
Nota: La palabra Trait(/tret/, pronunciado Treit) puede ser traducida literalmente como Rasgo. De todas maneras decido utilizar la notacin original por ser un concepto muy arraigado a Scala Aparte de poder heredar cdigo de una super clase, una clase en Scala puede tambin importar cdigo de uno o varios traits. Tal vez la forma ms fcil para un programador Java de entender qu son los traits es verlos como interfaces que tambin pueden contener cdigo. En Scala, cuando una clase hereda de un trait, implementa la interface de ese trait, y hereda todo el cdigo contenido en el trait. Para ver la utilidad de los traits, veamos un ejemplo clsico: objetos ordenados. Generalmente es til tener la posibilidad de comparar objetos de una clase dada entre ellos, por ejemplo, para ordenarlos. En Java, los objetos que son comparables implementan la interfaz C o m p a r a b l e. En Scala, 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. Cuando comparamos objetos podemos utilizar seis predicados distintos: menor, menor o igual, igual, distinto, mayor o igual y mayor. De todas maneras, definir todos estos es fastidioso, especialmente que cuatro de estos pueden ser expresados en base a los otros dos. Esto es, dados los predicados igual y menor (por ejemplo), uno puede expresar los otros. En Scala, todas estas observaciones pueden ser fcilmente capturadas mediante la siguiente declaracin de un Trait:
1 . t r a i tO r d{ 2 . 3 . 4 . 5 . 6 . } 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 definicin 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, como tambin provee implementaciones de tres predicados en trminos de un cuarto, abstracto. Los predicados para igualidad y su inverso (distinto, no igual) no aparecen aqu ya que por defecto estn presenten en todos los objetos. El tipo A n y el cual es usado arriba es el supertipo de todos los otros tipos en Scala. Puede ser visto como una versin ms general del tipo O b j e c t en Java, ya que A n y tambin es supertipo de I n t, F l o a t, etc. cosa que no se cumple en Java ( i n t por ejemplo es un tipo primitivo). 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. Como un ejemplo, definamos una clase F e c h a que representa fechas en el calendario gregoriano.
1 . c l a s sF e c h a ( d :I n t ,m :I n t ,a :I n t )e x t e n d sO r d{ 2 . 3 . 4 . 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 declaracin e x t e n d sO r d la cual sigue al nombre de la clase y los parmetros. Declara que la clase F e c h a hereda del trait O r d. Despus redefinimos el mtodo e q u a l s, heredado de O b j e c t, para comparar correctamente fechas mediante sus campos individuales. La implementacin por defecto de e q u a l s no es utilizable, porque como en Java, compara los objetos fsicamente. Por lo tanto llegamos a esto:
1 . 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 . 3 . 4 . t h a t . i s I n s t a n c e O f [ F e c h a ]& &{ v a lo=t h a t . a s I n s t a n c e O f [ F e c h a ] o . d i a = =d i a& &o . m e s= =m e s& &o . a n n o = =a n n o

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

8/11

12/01/14
5 . }

Tutorial de Scala para programadores Java - Scala Documentation

Este mtodo utiliza el mtodo 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). 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. El segundo, a s I n s t a n c e O f, corresponde al operador de casteo en Java: si el objeto es una instancia de un tipo dado, esta es vista como tal, de otra manera se lanza una excepcin C l a s s C a s t E x c e p t i o n. Finalmente el ltimo mtodo para definir es el predicado que comprueba la inferioridad. Este hace uso de otro mtodo predefinido, e r r o r que lanza una excepcin con el mensaje de error provisto.
1 . d e f< ( t h a t :A n y ) :B o o l e a n={ 2 . 3 . 4 . 5 . 6 . 7 . 8 . 9 . } v a lo=t h a t . a s I n s t a n c e O f [ F e c h a ] ( a n n o<o . a n n o )| | ( a n n o = =o . a n n o& &( m e s<o . m e s| | ( m e s= =o . m e s& &d i a<o . d i a ) ) ) i f( ! t h a t . 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 definicin de la clase F e c h a. Las instancias de esta clase pueden ser vistas tanto como fechas o como objetos comparables. Adems, todas ellas definen los seis predicados de comparacin mencionados arriba: e q u a l s y < porque aparecen directamente en la definicin de la clase F e c h a y los otros porque son heredados del trait O r d. Los traits son tiles en muchas otras ms situaciones que las aqu mostrada, pero discutir sus aplicaciones est fuera del alcance de este documento.

Tipos Genricos
Nota: El diseador de los tipos genricos en Java fue nada ms ni nada menos que Martin Odersky, el diseador de Scala. La ltima caracterstica de Scala que exploraremos en este tutorial es la de los tipos genricos. Los programadores de Java deben estar bien al tanto de los problemas que genera la falta de genricos en su lenguaje, lo cual es solucionado en Java 1.5. Los tipos genricos proveen al programador la habilidad de escribir cdigo parametrizado por tipos. Por ejemplo, escribir una librera para listas enlazadas se enfrenta al problema de decidir qu tipo darle a los elementos de la lista. Ya que esta lista est pensada para ser usada en diferentes contextos, no es posible decidir que el tipo de elementos sea, digamos, I n t. Esto sera completamente arbitrario y muy restrictivo. Los programadores Java cuentan como ltimo recurso con O b j e c t, que es el supertipo de todos los objetos. Esta solucin de todas maneras est lejos de ser ideal, ya que no funciona con tipos primitivos ( i n t, l o n g, f l o a t, etc.) e implica que el programador tenga que realizar muchos casteos de tipos en su programa. Scala hace posible definir clases genricas (y mtodos) para resolver este problema. Examinemos esto con un ejemplo del contenedor ms simple posible: una referencia, que puede estar tanto vaca como apuntar a un objeto de algn tipo.
1 . c l a s sR e f e r e n c i a [ T ]{ 2 . 3 . 4 . 5 . } 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, que es el tipo de sus elementos. 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, el argumento del mtodo s e t y el tipo de retorno del mtodo g e t. El ejemplo anterior introduce a las variables en Scala, que no deberan requerir mayor explicacin. Es interesante notar que el valor inicial dado a la variable c o n t e n i d o es _, que representa un valor por defecto. Este valor por defecto es 0 para tipos numricos, f a l s e para tipos B o o l e a n, ( ) para el tipo U n i ty n u l l para el resto de los objetos. Para utilizar esta clase R e f e r e n c i a, uno necesita especificar qu tipo utilizar por el parmetro T,

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

9/11

12/01/14

Tutorial de Scala para programadores Java - Scala Documentation

es decir, el tipo del elemento contenido por la referencia. Por ejemplo, para crear y utilizar una referencia que contenga un entero, podramos 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 . 3 . 4 . 5 . 6 . 7 . } } 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 . g e t*2 ) )

Como puede verse en el ejemplo, no es necesario castear el valor retornado por el mtodo g e t antes de usarlo como un entero. Tampoco es posible almacenar otra cosa que no sea un entero en esa referencia en particular, ya que fue declarada como contenedora de un entero.

Conclusin
Scala es un lenguaje tremendamente poderoso que ha sabido heredar las mejores cosas de cada uno de los lenguajes ms exitosos que se han conocido. Java no es la excepcin, y comparte muchas cosas con este. La diferencia que vemos es que para cada uno de los conceptos de Java, Scala los aumenta, refina y mejora. Poder aprender todas las caractersticas de Scala nos equipa con ms y mejores herramientas a la hora de escribir nuestros programas. Si bien la programacin funcional no ha sido una caracterstica de Java, el programador experimentado puede notar la falta de soporte de este paradigma en mltiples ocasiones. El solo pensar en el cdigo necesario para proveer a un J B u t t o n con el cdigo que debe ejecutar al ser presionado nos muestra lo necesario que sera contar con herramientas funcionales. Recomendamos entonces tratar de ir incorporando estas caractersticas, por ms que sea difcil para el programador Java al estar tan acostumbrado al paradigma imperativo de este lenguaje. Este documento dio una rpida introduccin al lenguaje Scala y presento algunos ejemplos bsicos. El lector interesado puede seguir, por ejemplo, leyendo el Tutorial de Scala que figura en el sitio de documentacin, o Scala by Example (en ingls). Tambin puede consultar la especificacin del lenguaje cuando lo desee.

2 comments Join the discussion


Best Community victor pacheco
3 months ago

Share

Login

Muchas gracias por traducir el pdf http://www.scala-lang.org/docu...


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, aparecen los nombres de la version en ingles...
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. All rights reserved.

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

10/11

12/01/14

Tutorial de Scala para programadores Java - Scala Documentation

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

11/11

S-ar putea să vă placă și