Articulo de referencia

Scala (lenguaje de programación)

[[JavaScript]] ([https://scala-js.org Scala.js]) [[LLVM]] ([http://scala-native.org Scala Native]) (experimental)"},"license":{"wt":"[[Apache License|Apache]] 2.0 {{cite web |ur...

Scala ( / ˈ s k ɑː l ɑː / SKAH -lah ) [ 7 ] [ 8 ] es un lenguaje de programación de alto nivel, de propósito general y con tipado estático fuerte que admite tanto la programación orientada a objetos como la programación funcional . Diseñado para ser conciso, [ 9 ] muchas de las decisiones de diseño de Scala tienen como objetivo abordar las críticas a Java . [ 6 ]

El código fuente de Scala se puede compilar a bytecode de JVM y ejecutarse en una máquina virtual Java (JVM). Scala también se puede transcompilar a JavaScript para ejecutarse en un navegador, o compilarse directamente a un ejecutable nativo usando Clang . Al ejecutarse en la JVM, Scala proporciona interoperabilidad de lenguaje con Java, de modo que las bibliotecas escritas en cualquiera de los dos lenguajes se pueden referenciar directamente en código Scala o Java. [ 10 ] Al igual que Java, Scala es orientado a objetos y utiliza una sintaxis denominada llave de cierre, similar al lenguaje C. Desde Scala 3, también existe la opción de usar la regla de sangría (off-side ) para estructurar bloques , y se recomienda su uso. Martin Odersky ha dicho que este resultó ser el cambio más productivo introducido en Scala 3. [ 11 ]

A diferencia de Java, Scala posee muchas características de los lenguajes de programación funcional (como Scheme , Standard ML y Haskell ), incluyendo currificación , inmutabilidad , evaluación perezosa y coincidencia de patrones . También cuenta con un sistema de tipos avanzado que admite tipos de datos algebraicos , covarianza y contravarianza , tipos de orden superior (pero no de rango superior ), tipos anónimos , sobrecarga de operadores , parámetros opcionales , parámetros con nombre , cadenas sin formato y una versión experimental de efectos algebraicos que solo maneja excepciones y que puede considerarse una versión más potente de las excepciones verificadas de Java . [ 12 ]

El nombre Scala es una combinación de las palabras escalable y lenguaje , lo que significa que está diseñado para crecer con las demandas de sus usuarios. [ 13 ]

Historia

El diseño de Scala comenzó en 2001 en la École Polytechnique Fédérale de Lausanne (EPFL) (en Lausana , Suiza ) por Martin Odersky . Surgió a partir del trabajo en Funnel, un lenguaje de programación que combina ideas de la programación funcional y las redes de Petri . [ 14 ] Odersky trabajó anteriormente en Generic Java y javac , el compilador de Java de Sun. [ 14 ]

Después de un lanzamiento interno a finales de 2003, Scala se lanzó públicamente a principios de 2004 en la plataforma Java , [ 15 ] [ 6 ] [ 14 ] [ 16 ] Una segunda versión (v2.0) le siguió en marzo de 2006. [ 6 ]

El 17 de enero de 2011, el equipo de Scala ganó una subvención de investigación de cinco años de más de 2,3 millones de euros del Consejo Europeo de Investigación . [ 17 ] El 12 de mayo de 2011, Odersky y sus colaboradores lanzaron Typesafe Inc. (más tarde renombrada Lightbend Inc. ), una empresa para proporcionar soporte comercial, formación y servicios para Scala. Typesafe recibió una inversión de 3 millones de dólares en 2011 de Greylock Partners . [ 18 ] [ 19 ] [ 20 ] [ 21 ]

Plataformas y licencias

Scala se ejecuta en la plataforma Java ( máquina virtual Java ) y es compatible con los programas Java existentes . [ 15 ] Dado que las aplicaciones de Android suelen escribirse en Java y se traducen del bytecode de la JVM al bytecode de Dalvik (que puede traducirse posteriormente a código máquina nativo durante la instalación) al empaquetarse , la compatibilidad de Scala con Java lo hace idóneo para el desarrollo de Android, sobre todo cuando se prefiere la programación funcional. [ 22 ]

La distribución de software de referencia de Scala, que incluye el compilador y las bibliotecas, se publica bajo la licencia Apache . [ 23 ]

Otros compiladores y objetivos

Scala.js es un compilador de Scala que compila a JavaScript, lo que permite escribir programas Scala que pueden ejecutarse en navegadores web o Node.js. [ 24 ] El compilador, en desarrollo desde 2013, dejó de ser experimental en 2015 (v0.6). La versión v1.0.0-M1 se lanzó en junio de 2018 y la versión 1.1.1 en septiembre de2020. [ 25 ]

Scala Native es un compilador de Scala que se dirige a la infraestructura del compilador LLVM para crear código ejecutable que utiliza un entorno de ejecución gestionado ligero, el cual emplea el recolector de basura Boehm . El proyecto está liderado por Denys Shabalin y su primera versión, la 0.1, se lanzó el 14 de marzo de 2017. El desarrollo de Scala Native comenzó en 2015 con el objetivo de ser más rápido que la compilación justo a tiempo para la JVM, eliminando la compilación inicial del código en tiempo de ejecución y proporcionando además la capacidad de llamar directamente a rutinas nativas. [ 26 ] [ 27 ]

En junio de 2004 se publicó un compilador de referencia de Scala dirigido al .NET Framework y su Common Language Runtime , [ 14 ] pero se abandonó oficialmente en 2012. [ 28 ]

Ejemplos

Ejemplo de "Hola Mundo"

El programa "Hola Mundo" escrito en Scala 3 tiene esta forma:

@main def main () = println ( "Hola, Mundo!" )

A diferencia de la aplicación independiente Hello World para Java , no hay declaración de clase y nada se declara como estático.

Cuando el programa se almacena en el archivo HelloWorld.scala , el usuario lo compila con el comando:

$ scalac HelloWorld.scala

y lo ejecuta con

$ scala HolaMundo

Esto es análogo al proceso de compilación y ejecución de código Java. De hecho, el modelo de compilación y ejecución de Scala es idéntico al de Java, lo que lo hace compatible con herramientas de compilación de Java como Apache Ant .

Una versión más corta del programa "Hola Mundo" en Scala es:

println ( "Hola, mundo!" )

Scala incluye un intérprete de comandos interactivo y soporte para scripts. [ 29 ] Guardado en un archivo llamado HelloWorld2.scala, esto se puede ejecutar como un script usando el comando:

$ scala HelloWorld2.scala

Los comandos también se pueden introducir directamente en el intérprete de Scala, utilizando la opción -e :

$ scala -e 'println("¡Hola, mundo!")'

Las expresiones se pueden introducir de forma interactiva en el REPL :

$ scala Bienvenido a Scala 2.12.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_131). Escriba expresiones para su evaluación. O pruebe :help.scala> List(1, 2, 3).map(x => x * x) res0: List[Int] = List(1, 4, 9)scala>

Ejemplo básico

El siguiente ejemplo muestra las diferencias entre la sintaxis de Java y Scala. La función mathFunction toma un entero, lo eleva al cuadrado y luego suma la raíz cúbica de ese número al logaritmo natural de ese número, devolviendo el resultado (es decir,norte2/3+ln(norte2){\displaystyle n^{2/3}+\ln(n^{2})}):

Algunas diferencias sintácticas en este código son:

  • Scala no requiere punto y coma (;) para finalizar las sentencias.
  • Los tipos de valor se escriben con mayúscula inicial (mayúsculas): Int, Double, Booleanen lugar de int, double, boolean.
  • Los tipos de parámetros y de retorno siguen, como en Pascal , en lugar de preceder como en C.
  • Los métodos deben ir precedidos de def.
  • Las variables locales o de clase deben ir precedidas de val(indica una variable inmutablevar ) o (indica una variable mutable ).
  • El returnoperador es innecesario en una función (aunque está permitido); el valor de la última instrucción o expresión ejecutada es normalmente el valor de la función.
  • En lugar del operador de conversión de Java (Type) foo, Scala utiliza foo.asInstanceOf[Type], o una función especializada como toDoubleo toInt.
  • La función o método foo()también puede llamarse simplemente como foo; el método thread.send(signo)también puede llamarse simplemente como thread send signo; y el método foo.toString()también puede llamarse simplemente como foo toString.

Estas relajaciones sintácticas están diseñadas para permitir la compatibilidad con lenguajes específicos de dominio .

Otras diferencias sintácticas básicas:

  • Las referencias a arrays se escriben como llamadas a funciones, por ejemplo, array(i)en lugar de array[i]. (Internamente en Scala, la primera se expande en array.apply(i), que devuelve la referencia).
  • Los tipos genéricos se escriben como , por ejemplo, List[String]en lugar de como en Java .List<String>
  • En lugar del pseudotipo void, Scala tiene la clase singletonUnit real (ver más abajo).

Ejemplo con clases

El siguiente ejemplo contrasta la definición de clases en Java y Scala.

El código anterior muestra algunas de las diferencias conceptuales entre el manejo de clases en Java y Scala:

  • Scala no tiene variables ni métodos estáticos. En su lugar, tiene objetos singleton , que son esencialmente clases con una sola instancia. Los objetos singleton se declaran usando objecten lugar de class. Es común colocar variables y métodos estáticos en un objeto singleton con el mismo nombre que la clase, que entonces se conoce como objeto compañero . [ 15 ] (La clase subyacente para el objeto singleton tiene un $añadido. Por lo tanto, para class Foocon objeto compañero object Foo, internamente hay una clase Foo$que contiene el código del objeto compañero, y se crea un objeto de esta clase, usando el patrón singleton .)
  • En lugar de parámetros de constructor, Scala tiene parámetros de clase , que se colocan en la clase, de forma similar a los parámetros de una función. Cuando se declaran con un modificador valo var, los campos también se definen con el mismo nombre y se inicializan automáticamente a partir de los parámetros de clase. (Internamente, el acceso externo a los campos públicos siempre se realiza a través de métodos de acceso (getter) y modificación (setter), que se crean automáticamente. La función de acceso tiene el mismo nombre que el campo, por lo que en el ejemplo anterior no es necesario declarar explícitamente los métodos de acceso). También se pueden declarar constructores alternativos, como en Java. El código que iría en el constructor predeterminado (excepto la inicialización de las variables miembro) va directamente a nivel de clase.
  • En Scala es posible definir operadores usando símbolos como nombres de métodos. En lugar de addPoint, el ejemplo de Scala define +=, que luego se invoca con notación infija como grid += this.
  • La visibilidad predeterminada en Scala es public.

Funcionalidades (con referencia a Java)

Scala tiene el mismo modelo de compilación que Java y C# , es decir, compilación separada y carga dinámica de clases , de modo que el código Scala puede llamar a las bibliotecas de Java.

Las características operativas de Scala son las mismas que las de Java. El compilador de Scala genera código de bytes casi idéntico al generado por el compilador de Java. [ 15 ] De hecho, el código Scala se puede descompilar a código Java legible, con la excepción de ciertas operaciones de constructor. Para la máquina virtual de Java (JVM), el código Scala y el código Java son indistinguibles. La única diferencia es una biblioteca de tiempo de ejecución adicional scala-library.jar. [ 30 ]

Scala incorpora numerosas características adicionales en comparación con Java, y presenta diferencias fundamentales en su modelo subyacente de expresiones y tipos, lo que, en teoría, simplifica el lenguaje y elimina varios casos excepcionales de Java. Desde la perspectiva de Scala, esto tiene una gran importancia práctica, ya que varias de las características añadidas también están disponibles en C#.

Flexibilidad sintáctica

Como se mencionó anteriormente, Scala tiene una gran flexibilidad sintáctica en comparación con Java. A continuación se muestran algunos ejemplos:

  • Los puntos y comas no son necesarios; las líneas se unen automáticamente si comienzan o terminan con un carácter que normalmente no puede aparecer en esa posición, o si hay paréntesis o corchetes sin cerrar.
  • Cualquier método puede usarse como operador infijo , por ejemplo "%d apples".format(num), y "%d apples" format numson equivalentes. De hecho, los operadores aritméticos como +y se tratan igual que cualquier otro método, ya que los nombres de las funciones pueden constar de secuencias de símbolos arbitrarios (con algunas excepciones para elementos como paréntesis, corchetes y llaves que deben manejarse de forma especial); el único tratamiento especial que reciben estos métodos con nombres de símbolos se refiere al manejo de la precedencia.<<
  • Los métodos applyy updatetienen formas abreviadas sintácticas. foo()—donde fooes un valor (objeto singleton o instancia de clase)— es abreviatura de foo.apply(), y foo() = 42es abreviatura de foo.update(42). De manera similar, foo(42)es abreviatura de foo.apply(42), y foo(4) = 2es abreviatura de foo.update(4, 2). Esto se usa para clases de colección y se extiende a muchos otros casos, como celdas STM .
  • Scala distingue entre métodos sin paréntesis ( def foo = 42) y def foo() = 42métodos con paréntesis vacíos ( ). Al llamar a un método con paréntesis vacíos, se pueden omitir los paréntesis, lo cual es útil al llamar a bibliotecas Java que no conocen esta distinción, por ejemplo, usando foo.toStringen lugar de foo.toString(). Por convención, un método debe definirse con paréntesis vacíos cuando realiza efectos secundarios .
  • Los nombres de métodos que terminan en dos puntos ( :) esperan el argumento en el lado izquierdo y el receptor en el lado derecho. Por ejemplo, es lo mismo que , la primera forma corresponde visualmente al resultado (una lista con el primer elemento 4 y el segundo elemento 2).4 :: 2 :: NilNil.::(2).::(4)
  • Las variables del cuerpo de la clase se pueden implementar de forma transparente como métodos getter y setter separados. Para trait FooLike { var bar: Int }, una implementación puede ser . El sitio de llamada aún podrá usar un conciso .objectFooextendsFooLike{privatevarx=0;defbar=x;defbar_=(value:Int){x=value}}}}foo.bar = 42
  • Se permite el uso de llaves en lugar de paréntesis en las llamadas a métodos. Esto permite implementaciones de biblioteca puras de nuevas estructuras de control. [ 31 ] Por ejemplo, breakable { ... if (...) break() ... }parece que breakablefuera una palabra clave definida por el lenguaje, pero en realidad es solo un método que toma un argumento thunk . Los métodos que toman thunks o funciones a menudo los colocan en una segunda lista de parámetros, lo que permite mezclar la sintaxis de paréntesis y llaves: Vector.fill(4) { math.random }es lo mismo que Vector.fill(4)(math.random). La variante de llaves permite que la expresión abarque varias líneas.
  • Las expresiones For (que se explican más adelante) pueden acomodar cualquier tipo que defina métodos monádicos como map, flatMapy filter.

Individualmente, estas opciones pueden parecer cuestionables, pero en conjunto permiten definir lenguajes específicos de dominio en Scala sin necesidad de extender el compilador. Por ejemplo, la sintaxis especial de Erlang para enviar un mensaje a un actor, ie , puede implementarse (y de hecho se implementa) en una biblioteca de Scala sin necesidad de extensiones del lenguaje.actor ! message

Sistema de tipos unificado

Java establece una clara distinción entre tipos primitivos (por ejemplo, inty boolean) y tipos de referencia (cualquier clase ). Solo los tipos de referencia forman parte del esquema de herencia, que deriva de java.lang.Object. En Scala, todos los tipos heredan de una clase de nivel superior Any, cuyos hijos inmediatos son AnyVal(tipos de valor, como Inty Boolean) y AnyRef(tipos de referencia, como en Java). Esto significa que la distinción de Java entre tipos primitivos y tipos encapsulados (por ejemplo, intvs. Integer) no está presente en Scala; el encapsulado y desempaquetado es completamente transparente para el usuario. Scala 2.10 permite que el usuario defina nuevos tipos de valor.

Expresiones for

En lugar de los bucles " foreach " de Java para recorrer un iterador, Scala tiene forexpresiones for, que son similares a las comprensiones de listas en lenguajes como Haskell , o una combinación de comprensiones de listas y expresiones generadoras en Python . Las expresiones for que usan la yieldpalabra clave permiten generar una nueva colecciónmap iterando sobre una existente, devolviendo una nueva colección del mismo tipo. El compilador las traduce en una serie de llamadas a , flatMapy filter. Cuando yieldno se usa , el código se aproxima a un bucle de estilo imperativo, traduciéndolo a foreach.

Un ejemplo sencillo es:

val s = para ( x <- 1 a 25 si x * x > 50 ) produce 2 * x

El resultado de ejecutarlo es el siguiente vector:

Vector(16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50)

(La expresión 1 to 25no es una sintaxis especial. El método toestá definido en la biblioteca estándar de Scala como un método de extensión para enteros, utilizando una técnica conocida como conversiones implícitas [ 32 ] que permite agregar nuevos métodos a tipos existentes).

Un ejemplo más complejo de iteración sobre un mapa es:

// Dado un mapa que especifica los usuarios de Twitter mencionados en un conjunto de tweets, // y el número de veces que se mencionó a cada usuario, busca a los usuarios // en un mapa de políticos conocidos y devuelve un nuevo mapa que muestra solo a los // políticos demócratas (como objetos, en lugar de cadenas). val dem_mentions = for ( mention , times ) <- mentions account <- accounts . get ( mention ) if account . party == "Democratic" yield ( account , times )

La expresión es un ejemplo de coincidencia de patrones (ver más abajo). Iterar sobre un mapa devuelve un conjunto de tuplas clave-valor , y la coincidencia de patrones permite desestructurar fácilmente las tuplas en variables separadas para la clave y el valor. De manera similar, el resultado de la comprensión también devuelve tuplas clave-valor, que se reconstruyen automáticamente en un mapa porque el objeto de origen (de la variable ) es un mapa. Si en cambio contuviera una lista, un conjunto, una matriz u otra colección de tuplas, exactamente el mismo código anterior produciría una nueva colección del mismo tipo.(mention, times) <- mentionsmentionsmentions

Tendencias funcionales

Si bien Scala admite todas las características de la programación orientada a objetos disponibles en Java (e incluso las amplía de diversas maneras), también ofrece una gran cantidad de funcionalidades que normalmente solo se encuentran en lenguajes de programación funcional . En conjunto, estas características permiten escribir programas en Scala con un estilo casi completamente funcional y, además, permiten combinar estilos funcionales y orientados a objetos.

Algunos ejemplos son:

Todo es una expresión

A diferencia de C o Java , pero de forma similar a lenguajes como Lisp , Scala no distingue entre sentencias y expresiones . Todas las sentencias son, de hecho, expresiones que se evalúan a algún valor. Las funciones que se declararían como de retorno voiden C o Java, y las sentencias como whileesa lógicamente no devuelven un valor, en Scala se consideran de retorno del tipo Unit, que es un tipo singleton , con un único objeto de ese tipo. Las funciones y los operadores que nunca devuelven ningún valor (por ejemplo, el throwoperador o una función que siempre sale de forma no local mediante una excepción) lógicamente tienen un tipo de retorno Nothing, un tipo especial que no contiene objetos; es decir, un tipo inferior , o sea, una subclase de cada tipo posible. (Esto a su vez hace que el tipo Nothingsea compatible con todos los tipos, lo que permite que la inferencia de tipos funcione correctamente). [ 33 ]

De manera similar, una if-then-else"sentencia" es en realidad una expresión que produce un valor, es decir, el resultado de evaluar una de las dos ramas. Esto significa que dicho bloque de código puede insertarse donde se desee una expresión, obviando la necesidad de un operador ternario en Scala:

Por razones similares, returnlas sentencias condicionales son innecesarias en Scala y, de hecho, se desaconsejan. Al igual que en Lisp , la última expresión de un bloque de código es el valor de dicho bloque, y si el bloque de código es el cuerpo de una función, esta lo devolverá.

Para dejar claro que todas las funciones son expresiones, incluso los métodos que devuelven un valor Unitse escriben con un signo igual.

def printValue ( x : String ): Unit = println ( "Comí un %s" . format ( x ))

o equivalentemente (con inferencia de tipo y omitiendo el salto de línea innecesario):

def printValue ( x : String ) = println ( "Comí un %s" format x )

Inferencia de tipo

Debido a la inferencia de tipos , el tipo de las variables, los valores de retorno de las funciones y muchas otras expresiones generalmente se pueden omitir, ya que el compilador puede deducirlo. Ejemplos de esto son val x = "foo"(para una constante inmutable o un objeto inmutable ) o var x = 1.5(para una variable cuyo valor puede cambiarse posteriormente). La inferencia de tipos en Scala es esencialmente local, a diferencia del algoritmo Hindley-Milner más global utilizado en Haskell, ML y otros lenguajes más puramente funcionales. Esto se hace para facilitar la programación orientada a objetos. El resultado es que ciertos tipos aún necesitan ser declarados (principalmente, los parámetros de las funciones y los tipos de retorno de las funciones recursivas ), por ejemplo

def formatApples ( x : Int ) = "Comí %d manzanas " .format ( x )

o (con un tipo de retorno declarado para una función recursiva)

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

Funciones anónimas

En Scala, las funciones son objetos, y existe una sintaxis conveniente para especificar funciones anónimas . Un ejemplo es la expresión x => x < 2, que especifica una función con un parámetro, que compara su argumento para ver si es menor que 2. Es equivalente a la forma de Lisp . Ni el tipo de x ni el tipo de retorno necesitan especificarse explícitamente, y generalmente pueden inferirse mediante inferencia de tipos ; pero pueden especificarse explícitamente, por ejemplo, como o incluso .(lambda(x)(<x2))(x:Int)=>x<2(x:Int)=>(x<2):Boolean

Las funciones anónimas se comportan como cierres verdaderos, ya que capturan automáticamente cualquier variable disponible léxicamente en el entorno de la función que las contiene. Estas variables estarán disponibles incluso después de que la función que las contiene finalice su ejecución y, a diferencia de las clases internas anónimas de Java , no es necesario declararlas como finales. (Incluso es posible modificar dichas variables si son mutables, y el valor modificado estará disponible la próxima vez que se llame a la función anónima).

Una forma aún más corta de función anónima utiliza variables de marcador de posición : por ejemplo, la siguiente:

list map { x => sqrt(x) }

se puede escribir de forma más concisa como

list map { sqrt(_) }

o incluso

list map sqrt

Inmutabilidad

Scala impone una distinción entre variables inmutables y mutables. Las variables mutables se declaran usando la varpalabra clave y los valores inmutables se declaran usando la valpalabra clave. Una variable declarada usando la valpalabra clave no se puede reasignar de la misma manera que una variable declarada usando la finalpalabra clave no se puede reasignar en Java. valLos son solo superficialmente inmutables, es decir, no se garantiza que un objeto referenciado por un val sea en sí mismo inmutable.

Las clases inmutables son recomendadas por convención, y la biblioteca estándar de Scala proporciona un amplio conjunto de clases de colección inmutables . Scala ofrece variantes mutables e inmutables de la mayoría de las clases de colección, y siempre se utiliza la versión inmutable a menos que se importe explícitamente la versión mutable. [ 34 ] Las variantes inmutables son estructuras de datos persistentes que siempre devuelven una copia actualizada de un objeto antiguo en lugar de actualizarlo de forma destructiva. Un ejemplo de esto son las listas enlazadas inmutables, donde agregar un elemento al principio de una lista se realiza devolviendo un nuevo nodo de lista que consta del elemento y una referencia al final de la lista. Agregar un elemento a una lista solo se puede hacer agregando todos los elementos de la lista antigua a una nueva lista con solo el nuevo elemento. De la misma manera, insertar un elemento en medio de una lista copiará la primera mitad de la lista, pero mantendrá una referencia a la segunda mitad. Esto se denomina compartición estructural. Esto permite una concurrencia muy sencilla: no se necesitan bloqueos, ya que ningún objeto compartido se modifica. [ 35 ]

Evaluación perezosa (no estricta)

La evaluación es estricta ("eager") por defecto. En otras palabras, Scala evalúa las expresiones tan pronto como están disponibles, en lugar de cuando se necesitan. Sin embargo, es posible declarar una variable como no estricta ("lazy") con la lazypalabra clave, lo que significa que el código para producir el valor de la variable no se evaluará hasta la primera vez que se haga referencia a la variable. También existen colecciones no estrictas de varios tipos (como el tipo Stream, una lista enlazada no estricta), y cualquier colección puede hacerse no estricta con el viewmétodo. Las colecciones no estrictas proporcionan un buen ajuste semántico para cosas como los datos producidos por el servidor, donde la evaluación del código para generar elementos posteriores de una lista (que a su vez activa una solicitud a un servidor, posiblemente ubicado en algún otro lugar de la web) solo ocurre cuando los elementos son realmente necesarios.

Recursión de cola

Los lenguajes de programación funcional suelen proporcionar optimización de llamadas recursivas para permitir un uso extensivo de la recursión sin problemas de desbordamiento de pila . Las limitaciones en el bytecode de la JVM complican la optimización de llamadas recursivas en la JVM. En general, una función que se llama a sí misma con una llamada recursiva puede optimizarse, pero las funciones mutuamente recursivas no. Se han sugerido los trampolines como solución alternativa. [ 36 ] La biblioteca Scala ha proporcionado soporte para trampolines con el objeto scala.util.control.TailCallsdesde Scala 2.8.0 (lanzado el 14 de julio de 2010). Una función puede ser opcionalmente anotada con @tailrec, en cuyo caso no compilará a menos que sea recursiva de cola. [ 37 ]

Un ejemplo de esta optimización podría implementarse utilizando la definición del factorial . Por ejemplo, la versión recursiva del factorial:

def factorial ( n : Int ): Int = if n == 0 then 1 else n * factorial ( n - 1 )

Podría optimizarse a la versión recursiva de cola de esta manera:

@tailrec def factorial ( n : Int , accum : Int ): Int = si n == 0 entonces accum else factorial ( n - 1 , n * accum )

Sin embargo, esto podría comprometer la capacidad de composición con otras funciones debido al nuevo argumento en su definición, por lo que es común utilizar cierres para preservar su firma original:

def factorial ( n : Int ): Int =@tailrecdef bucle ( actual : Int , acumulado : Int ): Int =Si la corriente es igual a 0 , entonces el acumuladorelse bucle ( actual - 1 , actual * acumulado )bucle ( n , 1 ) // Llamada al cierre usando el caso basefactorial final

Esto garantiza la optimización de las llamadas recursivas y, por lo tanto, evita un error de desbordamiento de pila.

Clases de casos y coincidencia de patrones

Scala cuenta con soporte integrado para la coincidencia de patrones , que puede considerarse una versión más sofisticada y extensible de una sentencia switch , donde se pueden comparar tipos de datos arbitrarios (en lugar de solo tipos simples como enteros, booleanos y cadenas), incluyendo anidamiento arbitrario. Se proporciona un tipo especial de clase, conocida como clase case , que incluye soporte automático para la coincidencia de patrones y puede usarse para modelar los tipos de datos algebraicos empleados en muchos lenguajes de programación funcional. (Desde la perspectiva de Scala, una clase case es simplemente una clase normal a la que el compilador agrega automáticamente ciertos comportamientos que también podrían proporcionarse manualmente, por ejemplo, definiciones de métodos que permiten comparaciones profundas y funciones hash, y la desestructuración de una clase case en función de los parámetros de su constructor durante la coincidencia de patrones).

Un ejemplo de definición del algoritmo quicksort mediante coincidencia de patrones es el siguiente:

def qsort ( lista : Lista [ Int ]): Lista [ Int ] = lista coincidencia caso Nil => Nil caso pivot :: cola => val ( más pequeño , resto ) = cola . partición ( _ < pivot ) qsort ( más pequeño ) ::: pivot :: qsort ( resto )

La idea consiste en dividir una lista en dos partes: los elementos menores que un pivote y los elementos iguales o mayores, ordenar recursivamente cada parte y unir los resultados con el pivote intercalado. Esto utiliza la misma estrategia de divide y vencerás que el algoritmo de ordenación por fusión y otros algoritmos de ordenación rápida.

El matchoperador se utiliza para realizar la coincidencia de patrones en el objeto almacenado en list. Cada caseexpresión se prueba a su vez para ver si coincide, y la primera coincidencia determina el resultado. En este caso, Nilsolo coincide con el objeto literal Nil, pero coincide con una lista no vacía, y simultáneamente desestructura la lista según el patrón dado. En este caso, el código asociado tendrá acceso a una variable local llamada que contiene la cabeza de la lista, y otra variable que contiene la cola de la lista. Estas variables son de solo lectura y son semánticamente muy similares a las vinculaciones de variables establecidas mediante el operador en Lisp y Scheme.pivot :: tailpivottaillet

La coincidencia de patrones también se produce en las declaraciones de variables locales. En este caso, el valor de retorno de la llamada tail.partitiones una tupla , concretamente dos listas. (Las tuplas se diferencian de otros tipos de contenedores, como las listas, en que siempre tienen un tamaño fijo y sus elementos pueden ser de tipos distintos, aunque en este caso son del mismo tipo). La coincidencia de patrones es la forma más sencilla de obtener las dos partes de la tupla.

El formulario consiste en la declaración de una función anónima con una variable de marcador de posición; consulte la sección anterior sobre funciones anónimas._ < pivot

Los operadores de lista ::(que añade un elemento al principio de una lista, similar a consen Lisp y Scheme) y :::(que concatena dos listas, similar a appenden Lisp y Scheme) aparecen ambos. A pesar de las apariencias, ninguno de estos operadores es "integrado". Como se especificó anteriormente, cualquier cadena de símbolos puede servir como nombre de función, y un método aplicado a un objeto puede escribirse en estilo "infijo" sin punto ni paréntesis. La línea anterior tal como está escrita:

qsort(smaller) ::: pivot :: qsort(rest)

También podría escribirse así:

qsort(rest).::(pivot).:::(qsort(smaller))

en la notación de llamada a método más estándar. (Los métodos que terminan con dos puntos son asociativos por la derecha y se vinculan al objeto de la derecha).

Funciones parciales

En el ejemplo de coincidencia de patrones anterior, el cuerpo del matchoperador es una función parcial , que consta de una serie de caseexpresiones, donde prevalece la primera expresión coincidente, de forma similar al cuerpo de una instrucción switch . Las funciones parciales también se utilizan en la parte de manejo de excepciones de una tryinstrucción:

try ... catch case nfe : NumberFormatException => { println ( nfe ); List ( 0 ) } case _ => Nil

Finalmente, una función parcial puede usarse sola, y el resultado de llamarla es equivalente a realizar una operación matchsobre ella. Por ejemplo, el código anterior para quicksort se puede escribir de la siguiente manera:

val qsort : List [ Int ] => List [ Int ] = case Nil => Nil case pivot :: tail => val ( smaller , rest ) = tail . partition ( _ < pivot ) qsort ( smaller ) ::: pivot :: qsort ( rest )

Aquí se declara una variable de solo lectura cuyo tipo es una función que transforma listas de enteros en listas de enteros, y se la vincula a una función parcial. (El único parámetro de la función parcial nunca se declara ni se nombra explícitamente). Sin embargo, podemos llamar a esta variable exactamente como si fuera una función normal:

scala > qsort ( Lista ( 6 , 2 , 5 , 9 )) res32 : Lista [ Int ] = Lista ( 2 , 5 , 6 , 9 )

Extensiones orientadas a objetos

Scala es un lenguaje puramente orientado a objetos, en el sentido de que cada valor es un objeto . Los tipos de datos y los comportamientos de los objetos se describen mediante clases y rasgos . Las abstracciones de clase se extienden mediante la herencia y un mecanismo de composición flexible basado en mixins para evitar los problemas de la herencia múltiple .

Los traits son el reemplazo de las interfaces de Java en Scala . Las interfaces en las versiones de Java anteriores a la 8 son muy restringidas y solo pueden contener declaraciones de funciones abstractas. Esto ha generado críticas, ya que proporcionar métodos de conveniencia en las interfaces resulta engorroso (los mismos métodos deben reimplementarse en cada implementación) y extender una interfaz publicada de forma retrocompatible es imposible. Los traits son similares a las clases mixin , pues poseen casi toda la potencia de una clase abstracta regular, careciendo únicamente de parámetros de clase (el equivalente en Scala a los parámetros del constructor de Java), dado que los traits siempre se integran con una clase. El superoperador `component` se comporta de manera especial en los traits, permitiendo encadenarlos mediante composición, además de la herencia. El siguiente ejemplo muestra un sistema de ventanas simple:

clase abstracta Ventana : // función abstracta dibujar ()clase SimpleWindow extiende Window : def draw () println ( "en SimpleWindow" ) // dibuja una ventana básicaEl rasgo WindowDecoration extiende Windowtrait HorizontalScrollbarDecoration extends WindowDecoration : // Se necesita una "sobreescritura abstracta" aquí para que "super()" funcione porque la función padre // es abstracta. Si fuera concreta, una "sobreescritura" normal sería suficiente. abstract override def draw ( ) println ( "en HorizontalScrollbarDecoration" ) super.draw ( ) // ahora dibuja una barra de desplazamiento horizontaltrait VerticalScrollbarDecoration extends WindowDecoration : abstract override def draw () println ( "en VerticalScrollbarDecoration" ) super . draw () // ahora dibuja una barra de desplazamiento verticaltrait TitleDecoration extends WindowDecoration : abstract override def draw () println ( "en TitleDecoration" ) super . draw () // ahora dibuja la barra de título

Una variable puede declararse de la siguiente manera:

val mywin = new SimpleWindow with VerticalScrollbarDecoration with HorizontalScrollbarDecoration with TitleDecoration

El resultado de la llamada mywin.draw()es:

en TitleDecoration en HorizontalScrollbarDecoration en VerticalScrollbarDecoration en SimpleWindow

En otras palabras, la llamada drawprimero ejecutó el código en TitleDecoration(el último rasgo mezclado), luego (a través de las super()llamadas) volvió a través de los otros rasgos mezclados y finalmente al código en Window, aunque ninguno de los rasgos heredaba de otro . Esto es similar al patrón decorador , pero es más conciso y menos propenso a errores, ya que no requiere encapsular explícitamente la ventana principal, reenviar explícitamente funciones cuya implementación no se modifica, o depender de la inicialización en tiempo de ejecución de las relaciones de entidad. En otros lenguajes, se podría lograr un efecto similar en tiempo de compilación con una larga cadena lineal de herencia de implementación , pero con la desventaja en comparación con Scala de que habría que declarar una cadena de herencia lineal para cada posible combinación de los mix-ins.

Sistema de tipos expresivo

Scala is equipped with an expressive static type system that mostly enforces the safe and coherent use of abstractions. The type system is, however, not sound.[38] In particular, the type system supports:

Scala is able to infer types by use. This makes most static type declarations optional. Static types need not be explicitly declared unless a compiler error indicates the need. In practice, some static type declarations are included for the sake of code clarity.

Type enrichment

A common technique in Scala, known as "enrich my library"[39] (originally termed "pimp my library" by Martin Odersky in 2006;[32] concerns were raised about this phrasing due to its negative connotations[40] and immaturity[41]), allows new methods to be used as if they were added to existing types. This is similar to the C# concept of extension methods but more powerful, because the technique is not limited to adding methods and can, for instance, be used to implement new interfaces. In Scala, this technique involves declaring an implicit conversion from the type "receiving" the method to a new type (typically, a class) that wraps the original type and provides the additional method. If a method cannot be found for a given type, the compiler automatically searches for any applicable implicit conversions to types that provide the method in question.

This technique allows new methods to be added to an existing class using an add-on library such that only code that imports the add-on library gets the new functionality, and all other code is unaffected.

The following example shows the enrichment of type Int with methods isEven and isOdd:

objectMyExtensions:extension(i:Int)defisEven=i%2==0defisOdd=!i.isEvenimportMyExtensions.*// bring implicit enrichment into scope4.isEven// -> true

Importing the members of MyExtensions brings the implicit conversion to extension class IntPredicates into scope.[42]

Concurrency

Scala's standard library includes support for futures and promises, in addition to the standard Java concurrency APIs. Originally, it also included support for the actor model, which is now available as a separate source-available platform Akka[43] licensed by Lightbend Inc. Akka actors may be distributed or combined with software transactional memory (transactors). Alternative communicating sequential processes (CSP) implementations for channel-based message passing are Communicating Scala Objects,[44] or simply via JCSP.

An Actor is like a thread instance with a mailbox. It can be created by system.actorOf, overriding the receive method to receive messages and using the ! (exclamation point) method to send a message.[45] The following example shows an EchoServer that can receive messages and then print them.

valechoServer=actor(newAct:become:casemsg=>println("echo "+msg))echoServer!"hi"

Scala also comes with built-in support for data-parallel programming in the form of Parallel Collections[46] integrated into its Standard Library since version 2.9.0.

The following example shows how to use Parallel Collections to improve performance.[47]

valurls=List("https://scala-lang.org","https://github.com/scala/scala")deffromURL(url:String)=scala.io.Source.fromURL(url).getLines().mkString("\n")valt=System.currentTimeMillis()urls.par.map(fromURL(_))// par returns parallel implementation of a collectionprintln("time: "+(System.currentTimeMillis-t)+"ms")

Besides futures and promises, actor support, and data parallelism, Scala also supports asynchronous programming with software transactional memory, and event streams.[48]

Cluster computing

The most well-known open-source cluster-computing solution written in Scala is Apache Spark. Additionally, Apache Kafka, the publish–subscribemessage queue popular with Spark and other stream processing technologies, is written in Scala.

Testing

There are several ways to test code in Scala. ScalaTest supports multiple testing styles and can integrate with Java-based testing frameworks.[49] ScalaCheck is a library similar to Haskell's QuickCheck.[50] specs2 is a library for writing executable software specifications.[51] ScalaMock provides support for testing high-order and curried functions.[52]JUnit and TestNG are popular testing frameworks written in Java.

Versions

Comparación con otros lenguajes de la JVM

A menudo se compara Scala con Groovy y Clojure , otros dos lenguajes de programación que también utilizan la JVM. Existen diferencias sustanciales entre estos lenguajes en cuanto al sistema de tipos, el grado de compatibilidad de cada uno con la programación orientada a objetos y la programación funcional, y la similitud de su sintaxis con la de Java.

Scala es de tipado estático , mientras que Groovy y Clojure son de tipado dinámico . Esto hace que el sistema de tipos sea más complejo y difícil de entender, pero permite que casi todos los errores de tipo [ 38 ] se detecten en tiempo de compilación y puede resultar en una ejecución significativamente más rápida. Por el contrario, el tipado dinámico requiere más pruebas para garantizar la corrección del programa y, por lo tanto, es generalmente más lento, para permitir una mayor flexibilidad y simplicidad de programación. En cuanto a las diferencias de velocidad, las versiones actuales de Groovy y Clojure permiten anotaciones de tipo opcionales para ayudar a los programas a evitar la sobrecarga del tipado dinámico en casos donde los tipos son prácticamente estáticos. Esta sobrecarga se reduce aún más al usar versiones recientes de la JVM, que se ha mejorado con una instrucción `invoke dynamic` para métodos que se definen con argumentos de tipado dinámico. Estos avances reducen la brecha de velocidad entre el tipado estático y el dinámico, aunque un lenguaje de tipado estático, como Scala, sigue siendo la opción preferida cuando la eficiencia de ejecución es muy importante.

En cuanto a paradigmas de programación, Scala hereda el modelo orientado a objetos de Java y lo amplía de diversas maneras. Groovy, si bien también es fuertemente orientado a objetos, se centra más en reducir la verbosidad. En Clojure, la programación orientada a objetos se minimiza, siendo la programación funcional su principal fortaleza. Scala también cuenta con numerosas herramientas de programación funcional, incluyendo características presentes en lenguajes funcionales avanzados como Haskell, y procura ser neutral respecto a ambos paradigmas, permitiendo al desarrollador elegir entre ellos o, más frecuentemente, una combinación de ambos.

En cuanto a la similitud sintáctica con Java, Scala hereda gran parte de la sintaxis de Java, al igual que Groovy. Clojure, por otro lado, sigue la sintaxis de Lisp , que difiere tanto en apariencia como en filosofía.

Adopción

Clasificación de idiomas

En 2013, cuando Scala estaba en la versión 2.10, el ThoughtWorks Technology Radar, que es un informe semestral basado en la opinión de un grupo de tecnólogos sénior, [ 156 ] recomendó la adopción de Scala en su categoría de lenguajes y marcos. [ 157 ]

En julio de 2014, esta evaluación se hizo más específica y ahora se refiere a "Scala, las partes buenas", que se describe como "Para usar Scala con éxito, necesitas investigar el lenguaje y tener una opinión muy firme sobre qué partes son adecuadas para ti, creando tu propia definición de Scala, las partes buenas". [ 158 ]

En la edición de 2018 de la encuesta State of Java , [ 159 ] que recopiló datos de 5160 desarrolladores sobre varios temas relacionados con Java, Scala ocupa el tercer lugar en términos de uso de lenguajes alternativos en la JVM . En relación con la edición del año anterior de la encuesta, el uso de Scala entre los lenguajes alternativos de la JVM cayó del 28,4% al 21,5%, superado por Kotlin , que subió del 11,4% en 2017 al 28,8% en 2018. El Índice de Popularidad de Lenguajes de Programación, [ 160 ] que rastrea las búsquedas de tutoriales de lenguajes, clasificó a Scala en el puesto 15 en abril de 2018 con una pequeña tendencia a la baja, y en el puesto 17 en enero de 2021. Esto convierte a Scala en el tercer lenguaje basado en JVM más popular después de Java y Kotlin, clasificado en el puesto 12.

El ranking de lenguajes de programación RedMonk , que establece clasificaciones basadas en el número de proyectos de GitHub y preguntas formuladas en Stack Overflow , clasificó a Scala en el puesto 14 en enero de 2021. [ 161 ] Aquí, Scala se ubicó dentro de un grupo de lenguajes de segundo nivel, por delante de Go , PowerShell y Haskell, y por detrás de Swift , Objective-C , TypeScript y R.

El índice TIOBE [ 162 ] de popularidad de lenguajes de programación utiliza clasificaciones de motores de búsqueda de internet y recuentos de publicaciones similares para determinar la popularidad de un lenguaje. En septiembre de 2021, Scala ocupaba el puesto 31. En esta clasificación, Scala estaba por delante de Haskell (puesto 38) y Erlang , pero por debajo de Go (puesto 14), Swift (puesto 15) y Perl (puesto 19).

A partir de 2022Los lenguajes basados ​​en JVM, como Clojure, Groovy y Scala, tienen una alta clasificación, pero aún son significativamente menos populares que el lenguaje Java original , que generalmente se ubica entre los tres primeros puestos. [ 161 ] [ 162 ]

Empresas

Crítica

En noviembre de 2011, Yammer dejó de usar Scala por razones que incluían la curva de aprendizaje para los nuevos miembros del equipo y la incompatibilidad entre las distintas versiones del compilador de Scala. [ 193 ] En marzo de 2015, el ex vicepresidente del grupo de Ingeniería de Plataformas de Twitter, Raffi Krikorian , declaró que no habría elegido Scala en 2011 debido a su curva de aprendizaje . [ 194 ] Ese mismo mes, el vicepresidente sénior de LinkedIn, Kevin Scott, declaró su decisión de «minimizar [su] dependencia de Scala». [ 195 ]

Véase también

  • sbt , una herramienta de compilación ampliamente utilizada para proyectos Scala.
  • Spark Framework está diseñado para manejar y procesar grandes cantidades de datos, y solo admite Scala.
  • Neo4j es un framework Java Spring con soporte para Scala que ofrece funcionalidades específicas de dominio, capacidades analíticas, algoritmos de grafos y mucho más.
  • Play!, un framework de aplicaciones web de código abierto que admite Scala.
  • Akka , un conjunto de herramientas de código abierto para crear aplicaciones concurrentes y distribuidas.
  • Chisel , un lenguaje de código abierto construido sobre Scala que se utiliza para el diseño y la generación de hardware. [ 196 ]

Referencias

  1. "Versión 3.8.4" . 5 de junio de 2026. Consultado el 6 de junio de 2026 .
  2. "Archivo de aviso" . GitHub . 24/01/2019 . Consultado el 04/12/2019 .
  3. "Macros de Scala" .
  4. Fogus, Michael (6 de agosto de 2010). "MartinOdersky toma(5) aList" . Send More Paramedics . Recuperado el 9 de febrero de 2012 .
  5. 1 2 3 4 Odersky, Martin (11 de enero de 2006). "El experimento Scala: ¿Podemos brindar un mejor soporte de lenguaje para sistemas de componentes?" (PDF) . Recuperado el 22 de junio de 2016 .
  6. 1 2 3 4 Odersky, Martín; et al. (2006). "Una descripción general del lenguaje de programación Scala" (PDF) (2ª ed.). Escuela Politécnica Federal de Lausana (EPFL). Archivado (PDF) desde el original el 9 de julio de 2020.  
  7. Odersky, Martin (2008). Programación en Scala . Mountain View, California: Artima. pág. 3. ISBN  9780981531601Consultado el 12 de junio de 2014 .
  8. Wampler, Dean; Payne, Alex (15 de septiembre de 2009). Programación en Scala: Escalabilidad = Programación funcional + Objetos . O'Reilly Media, Inc. pág. 7. ISBN  978-1-4493-7926-1. Consultado el 13 de mayo de 2024. Los creadores de Scala en realidad lo pronuncian scah-lah , como la palabra italiana para "escaleras". Las dos "a" se pronuncian igual.
  9. Potvin, Pascal; Bonja, Mario (24 de septiembre de 2015). SDL 2013: Ingeniería de confiabilidad basada en modelos . Lecture Notes in Computer Science. Vol. 7916. arXiv : 1509.07326 . doi : 10.1007/978-3-642-38911-5 . ISBN  978-3-642-38910-8. S2CID 1214469 . 
  10. "Preguntas frecuentes: Interoperabilidad de Java" . Scala-lang.org . Consultado el 6 de febrero de 2015 .
  11. Martin Odersky (17 de junio de 2020). Martin Odersky: Actualización de Scala 3 (vídeo). YouTube. El evento ocurre entre los minutos 36:35 y 45:08. Archivado del original el 21 de diciembre de 2021. Consultado el 24 de abril de 2021 .
  12. "Efecto expt" . scala . Consultado el 31/07/2022 .
  13. Loverdo, Christos (2010). Pasos en Scala: Una introducción a la programación objeto-funcional . Cambridge University Press . pág. xiii. ISBN  9781139490948Consultado el 31 de julio de 2014 .
  14. 1 2 3 4 Odersky, Martin (9 de junio de 2006). "Una breve historia de Scala" . Artima.com .
  15. 1 2 3 4 Odersky, M.; Rompf, T. (2014). "Unificando la programación funcional y orientada a objetos con Scala" . Communications of the ACM . 57 (4): 76. doi : 10.1145/2591013 .
  16. Martin Odersky, "Especificación del lenguaje Scala, versión 2.7"
  17. "Equipo de Scala gana subvención del ERC" . Consultado el 4 de julio de 2015 .
  18. "Soporte comercial para Scala" . 12 de mayo de 2011. Consultado el 18 de agosto de 2011 .
  19. "Por qué invertimos en Typesafe: las aplicaciones modernas exigen herramientas modernas" . 12 de mayo de 2011. Consultado el 8 de mayo de 2018 .
  20. "Scala de código abierto obtiene respaldo comercial" . 12 de mayo de 2011. Consultado el 9 de octubre de 2011 .
  21. "El pionero de la computación en la nube, Martin Odersky, presenta su nueva empresa Typesafe" . 12 de mayo de 2011. Consultado el 24 de agosto de 2011 .
  22. "Scala en Android" . Archivado del original el 20 de junio de 2016. Consultado el 8 de junio de 2016 .
  23. "¡Scala 2.12.8 ya está disponible!" . 2018-12-04 . Consultado el 2018-12-09 .
  24. "Scala Js ya no es experimental | El lenguaje de programación Scala" . Scala-lang.org. 5 de febrero de 2015. Consultado el 28 de octubre de 2015 .
  25. "Versiones · scala-js/Scala-js" . GitHub .
  26. Krill, Paul (15 de marzo de 2017). "Una variante reducida de Scala rompe lazos con la JVM" . InfoWorld . Consultado el 21 de marzo de 2017 .
  27. Krill, Paul (11 de mayo de 2016). "El lenguaje Scala se acerca al hardware de bajo nivel" . InfoWorld .
  28. Se eliminó el backend .net. por paulp · Solicitud de extracción n.° 1718 · scala/scala · GitHub . Github.com (5 de diciembre de 2012). Recuperado el 2 de noviembre de 2013.
  29. "Primeros pasos con Scala" . Scala-lang.org . 15 de julio de 2008. Consultado el 31 de julio de 2014 .
  30. "Inicio" . Blog.lostlake.org. Archivado del original el 31 de agosto de 2010. Consultado el 25 de junio de 2013 .
  31. Las estructuras de control integradas de Scala, comoifo ,whileno se pueden reimplementar. Existe un proyecto de investigación, Scala-Virtualized, que busca eliminar estas restricciones: Adriaan Moors, Tiark Rompf, Philipp Haller y Martin Odersky. Scala-Virtualized . Actas del taller ACM SIGPLAN 2012 sobre evaluación parcial y manipulación de programas , 117–120. Julio de 2012.
  32. 1 2 "Pimp my Library" . Artima.com. 9 de octubre de 2006. Consultado el 25 de junio de 2013 .
  33. "Expressions | Scala 2.13" . scala-lang.org . Consultado el 24 de mayo de 2021 .
  34. "Colecciones mutables e inmutables - Documentación de Scala" . Consultado el 30 de abril de 2020 .
  35. "Colecciones - Clases de colecciones inmutables concretas - Documentación de Scala" . Consultado el 4 de julio de 2015 .
  36. Dougherty, Rich. "Blog de Rich Dougherty" . Consultado el 4 de julio de 2015 .
  37. "TailCalls - API de la biblioteca estándar de Scala (Scaladoc) 2.10.2 - scala.util.control.TailCalls" . Scala-lang.org . Consultado el 25 de junio de 2013 .
  38. 1 2 "Los sistemas de tipos de Java y Scala son defectuosos" (PDF) .
  39. Giarrusso, Paolo G. (2013). "¡Reifica tus consultas de colección para lograr modularidad y velocidad!". Actas de la 12.ª conferencia internacional anual sobre desarrollo de software orientado a aspectos . ACM. arXiv : 1210.6284 . Bibcode : 2012arXiv1210.6284G . También conocido como patrón "pimp-my-library".
  40. Gilbert, Clint (15 de noviembre de 2011). "¿Cuál es la máxima prioridad para que Scala tenga éxito en el mundo empresarial (¿Debería estar en scala-debate?) ?" . Scala-lang.org . Consultado el 8 de mayo de 2019 . 
  41. "¿Deberíamos "enriquecer" o "mejorar" las bibliotecas de Scala?" . stackexchange.com . 17 de junio de 2013 . Consultado el 15 de abril de 2016 .
  42. Las clases implícitas se introdujeron en Scala 2.10 para hacer que las extensiones de métodos sean más concisas. Esto es equivalente a agregar un métodoimplicit def IntPredicate(i: Int) = new IntPredicate(i). La clase también se puede definir comoimplicit class IntPredicates(val i: Int) extends AnyVal { ... }, produciendo una llamada clase de valor , también introducida en Scala 2.10. El compilador eliminará entonces las instanciaciones reales y generará métodos estáticos en su lugar, lo que permite que los métodos de extensión tengan prácticamente ninguna sobrecarga de rendimiento.
  43. ¿Qué es Acká? , documentación en línea de Akka
  44. Sufrin, Bernard (2008). "Comunicación de objetos Scala". En Welch, PH; Stepney, S.; Polack, FAC; Barnes, FRM; McEwan, AA; Stiles, GS; Broenink, JF; Sampson, AT (eds.). Arquitecturas de procesos comunicantes 2008: WoTUG-31 (PDF) . IOS Press. ISBN 978-1586039073.
  45. Yan, Kay. "Scala Tour" . Consultado el 4 de julio de 2015 .
  46. "Colecciones paralelas - Descripción general - Documentación de Scala" . Docs.scala-lang.org . Consultado el 25 de junio de 2013 .
  47. Yan, Kay. "Scala Tour" . Consultado el 4 de julio de 2015 .
  48. Aprendiendo programación concurrente en Scala , Aleksandar Prokopec, Packt Publishing
  49. Kops, Micha (13 de enero de 2013). "Una breve introducción a ScalaTest" . hascode.com . Consultado el 7 de noviembre de 2014 .
  50. Nilsson, Rickard (2008-11-17). "ScalaCheck 1.5" . Scala-lang.org . Recuperado el 2014-11-07 .
  51. "Crea aplicaciones web usando Scala y el Play Framework" . workwithplay.com . 22 de mayo de 2013. Consultado el 7 de noviembre de 2014 .
  52. Butcher, Paul (04-06-2012). "ScalaMock 3.0 Preview Release" . paulbutcher.com . Archivado del original el 08-11-2014 . Recuperado el 07-11-2014 .
  53. 1 2 3 4 5 6 7 "Historial de cambios de Scala" . Scala-lang.org . Archivado del original el 9 de octubre de 2007.
  54. "Eliminado: literales XML" . dotty.epfl.ch . Consultado el 5 de marzo de 2021 .
  55. "Cambios en la versión 2.0 (12-Mar-2006)" . Scala-lang.org . 12-03-2006 . Consultado el 07-11-2014 .
  56. "Cambios en la versión 2.1.8 (23-ago-2006)" . Scala-lang.org . 23-08-2006 . Consultado el 07-11-2014 .
  57. "Cambios en la versión 2.3.0 (23-Nov-2006)" . Scala-lang.org . 2006-11-23 . Consultado el 2014-11-07 .
  58. "Cambios en la versión 2.4.0 (09-Mar-2007)" . Scala-lang.org . 2007-03-09 . Consultado el 2014-11-07 .
  59. "Cambios en la versión 2.5 (02-May-2007)" . Scala-lang.org . 2007-05-02 . Consultado el 2014-11-07 .
  60. "Cambios en la versión 2.6 (27-jul-2007)" . Scala-lang.org . 27-06-2007 . Consultado el 07-11-2014 .
  61. "Cambios en la versión 2.7.0 (07-feb-2008)" . Scala-lang.org . 2008-02-07 . Consultado el 2014-11-07 .
  62. "Cambios en la versión 2.8.0 (14-jul-2010)" . Scala-lang.org . 10-07-2010 . Consultado el 07-11-2014 .
  63. "Cambios en la versión 2.9.0 (12 de mayo de 2011)" . Scala-lang.org . 12 de mayo de 2011. Consultado el 7 de noviembre de 2014 .
  64. "Cambios en la versión 2.10.0" . Scala-lang.org . 4 de enero de 2013. Consultado el 7 de noviembre de 2014 .
  65. Harrah, Mark. "Clases de valor y rasgos universales" . Scala-lang.org . Consultado el 7 de noviembre de 2014 .
  66. Suereth, Josh. "SIP-13 - Clases implícitas" . Scala-lang.org . Archivado del original el 8 de noviembre de 2014. Consultado el 7 de noviembre de 2014 .
  67. Suereth, Josh. "Interpolación de cadenas" . Scala-lang.org . Consultado el 7 de noviembre de 2014 .
  68. Haller, Philipp; Prokopec, Aleksandar. "Futuros y promesas" . Scala-lang.org . Consultado el 7 de noviembre de 2014 .
  69. "SIP-17 - Tipo dinámico" . Scala-lang.org . Archivado del original el 8 de noviembre de 2014. Consultado el 7 de noviembre de 2014 .
  70. "SIP-18 - Modularización de características del lenguaje" . Scala-lang.org . Archivado del original el 8 de noviembre de 2014. Consultado el 7 de noviembre de 2014 .
  71. Prokopec, Aleksandar; Miller, Heather. "Colecciones paralelas" . Scala-lang.org . Consultado el 7 de noviembre de 2014 .
  72. Miller, Heather; Burmako, Eugene. "Reflexión general" . Scala-lang.org . Consultado el 7 de noviembre de 2014 .
  73. Burmako, Eugene. "Def Macros" . Scala-lang.org . Consultado el 7 de noviembre de 2014 .
  74. "¡Scala 2.10.2 ya está disponible!" . Scala-lang.org . 6 de junio de 2013. Archivado del original el 8 de noviembre de 2014. Consultado el 7 de noviembre de 2014 .
  75. "¡Scala 2.10.3 ya está disponible!" . Scala-lang.org . 1 de octubre de 2013. Archivado del original el 8 de noviembre de 2014. Consultado el 7 de noviembre de 2014 .
  76. "¡Scala 2.10.4 ya está disponible!" . Scala-lang.org . 18-03-2014 . Consultado el 07-01-2015 .
  77. "¡Scala 2.10.5 ya está disponible!" . Scala-lang.org . 2015-03-04 . Consultado el 2015-03-23 ​​.
  78. "¡Scala 2.11.0 ya está disponible!" . Scala-lang.org . 2014-04-21 . Consultado el 2014-11-07 .
  79. "¡Scala 2.11.1 ya está disponible!" . Scala-lang.org . 2014-05-20 . Consultado el 2014-11-07 .
  80. "¡Scala 2.11.2 ya está disponible!" . Scala-lang.org . 22-07-2014 . Consultado el 07-11-2014 .
  81. "¡Scala 2.11.4 ya está disponible!" . Scala-lang.org . 30-10-2014 . Consultado el 07-11-2014 .
  82. "¡Scala 2.11.5 ya está disponible!" . Scala-lang.org . 8 de enero de 2015 . Consultado el 22 de enero de 2015 .
  83. "¡Scala 2.11.6 ya está disponible!" . Scala-lang.org . 2015-03-05 . Consultado el 2015-03-12 .
  84. "¡Scala 2.11.7 ya está disponible!" . Scala-lang.org . 2015-06-23 . Consultado el 2015-07-03 .
  85. "¡Scala 2.11.8 ya está disponible!" . Scala-lang.org . 8 de marzo de 2016 . Consultado el 9 de marzo de 2016 .
  86. 1 2 "¡Tres nuevos lanzamientos y más cosas buenas de GitHub!" . Scala-lang.org . 2017-04-18 . Consultado el 2017-04-19 .
  87. "Actualización de seguridad: 2.12.4, 2.11.12, 2.10.7 (CVE-2017-15288)" . Scala-lang.org . 13 de noviembre de 2017. Consultado el 4 de mayo de 2018 .
  88. "¡Scala 2.12.0 ya está disponible!" . Scala-lang.org . 2016-11-03 . Consultado el 2017-01-08 .
  89. "¡Scala 2.12.1 ya está disponible!" . Scala-lang.org . 2016-12-05 . Consultado el 2017-01-08 .
  90. "¡Scala 2.12.3 ya está disponible!" . Scala-lang.org . 26-07-2017 . Consultado el 16-08-2017 .
  91. "¡Scala 2.12.4 ya está disponible!" . Scala-lang.org . 18-10-2017 . Consultado el 26-10-2017 .
  92. "¡Scala 2.12.5 ya está disponible!" . Scala-lang.org . 15-03-2018 . Consultado el 20-03-2018 .
  93. "¡Scala 2.12.6 ya está disponible!" . Scala-lang.org . 27-04-2018 . Consultado el 04-05-2018 .
  94. "¡Scala 2.12.7 ya está disponible!" . Scala-lang.org . 2018-09-27 . Consultado el 2018-10-09 .
  95. "¡Scala 2.12.8 ya está disponible!" . Scala-lang.org . 4 de diciembre de 2018 . Consultado el 9 de diciembre de 2018 .
  96. "¡Scala 2.12.9 ya está disponible!" . Scala-lang.org . 2019-08-05 . Consultado el 2021-01-20 .
  97. "¡Scala 2.12.10 ya está disponible!" . Scala-lang.org . 10-09-2019 . Consultado el 20-01-2021 .
  98. "¡Scala 2.12.11 ya está disponible!" . Scala-lang.org . 16-03-2020 . Consultado el 20-01-2021 .
  99. "¡Scala 2.12.12 ya está disponible!" . Scala-lang.org . 13-07-2020 . Consultado el 20-01-2021 .
  100. "¡Scala 2.12.13 ya está disponible!" . Scala-lang.org . 12/01/2021 . Consultado el 20/01/2021 .
  101. "¡Scala 2.12.14 ya está disponible!" . Scala-lang.org . 2021-05-28 . Consultado el 2022-04-15 .
  102. "¡Scala 2.12.15 ya está disponible!" . Scala-lang.org . 14-09-2021 . Consultado el 19-06-2022 .
  103. "¡Scala 2.12.16 ya está disponible!" . Scala-lang.org . 10-06-2022 . Consultado el 19-06-2022 .
  104. "¡Scala 2.12.17 ya está disponible!" . Scala-lang.org . 10-06-2022 . Consultado el 16-09-2022 .
  105. "¡Scala 2.12.18 ya está disponible!" . Scala-lang.org . 10-06-2022 . Consultado el 07-06-2023 .
  106. "¡Scala 2.12.19 ya está disponible!" . Scala-lang.org . 2024-02-25 . Consultado el 2024-08-12 .
  107. "¡Scala 2.13.0 ya está disponible!" . Scala-lang.org . 11-06-2019 . Consultado el 17-06-2018 .
  108. "¡Scala 2.13.1 ya está disponible!" . Scala-lang.org . 18-09-2019 . Consultado el 20-01-2021 .
  109. "¡Scala 2.13.2 ya está disponible!" . Scala-lang.org . 22-04-2020 . Consultado el 20-01-2021 .
  110. "¡Scala 2.13.3 ya está disponible!" . Scala-lang.org . 2020-06-25 . Consultado el 2021-01-20 .
  111. "¡Scala 2.13.4 ya está disponible!" . Scala-lang.org . 19/11/2020 . Consultado el 20/01/2021 .
  112. "¡Scala 2.13.5 ya está disponible!" . Scala-lang.org . 22/02/2021 . Consultado el 26/02/2021 .
  113. "¡Scala 2.13.6 ya está disponible!" . Scala-lang.org . 17-05-2021 . Consultado el 15-04-2022 .
  114. "¡Scala 2.13.7 ya está disponible!" . Scala-lang.org . 2021-11-01 . Consultado el 2022-04-15 .
  115. "¡Scala 2.13.8 ya está disponible!" . Scala-lang.org . 12/01/2022 . Consultado el 15/04/2022 .
  116. "¡Scala 2.13.9 ya está disponible!" . Scala-lang.org . 2022-09-21 . Consultado el 2023-08-28 .
  117. "¡Scala 2.13.10 ya está disponible!" . Scala-lang.org . 13-10-2022 . Consultado el 28-08-2023 .
  118. "¡Scala 2.13.11 ya está disponible!" . Scala-lang.org . 2023-06-07 . Consultado el 2023-08-28 .
  119. "¡Scala 2.13.12 ya está disponible!" . Scala-lang.org . 11-09-2023 . Consultado el 12-08-2024 .
  120. "¡Scala 2.13.13 ya está disponible!" . Scala-lang.org . 26-02-2024 . Consultado el 12-08-2024 .
  121. "¡Scala 2.13.14 ya está disponible!" . Scala-lang.org . 2024-05-01 . Consultado el 2024-08-12 .
  122. "¡Scala 2.13.15 ya está disponible!" . Scala-lang.org . 2024-09-25 . Consultado el 2024-12-05 .
  123. "¡Scala 3 ya está aquí!" . Scala-lang.org . 14-05-2021 . Consultado el 26-05-2021 .
  124. "¡Scala 3.0.1 y 3.0.2-RC1 ya están aquí!" . Scala-lang.org . 31-07-2021 . Consultado el 12-08-2024 .
  125. "¡Scala 3.0.2 publicado!" . Scala-lang.org . 2021-09-07 . Consultado el 2024-08-12 .
  126. "¡Scala 3.1.0 publicado!" . Scala-lang.org . 2021-10-21 . Consultado el 2024-08-12 .
  127. "Noticias sobre Scala 3.1.1 y compatibilidad con versiones futuras" . Scala-lang.org . 1 de febrero de 2022. Consultado el 12 de agosto de 2024 .
  128. "¡Scala 3.1.2 publicado!" . Scala-lang.org . 2022-04-12 . Consultado el 2024-08-12 .
  129. "¡Scala 3.1.3 publicado!" . Scala-lang.org . 2022-06-21 . Consultado el 2024-08-12 .
  130. "¡Scala 3.2.0 lanzado!" . Scala-lang.org . 2022-09-05 . Consultado el 2024-08-12 .
  131. "¡Scala 3.2.1 publicado!" . Scala-lang.org . 2022-11-07 . Consultado el 2024-08-12 .
  132. "¡Scala 3.2.2 ya está disponible!" . Scala-lang.org . 30-01-2023 . Consultado el 12-08-2024 .
  133. "¡Scala 3.3.0 lanzado!" . Scala-lang.org . 30-05-2023 . Consultado el 12-08-2024 .
  134. "¡Scala 3.3.1 LTS ya está disponible!" . Scala-lang.org . 2023-09-07 . Consultado el 2024-08-12 .
  135. "Scala 3.3.2" . github.com . 2024-02-29 . Consultado el 2024-08-12 .
  136. 1 2 "¡Scala 3.4.0 y 3.3.3 LTS publicados!" . Scala-lang.org . 2024-02-29 . Consultado el 2024-08-12 .
  137. "¡Scala 3.3.8 ya está disponible!" . Scala-lang.org . 10-06-2026 . Consultado el 18-06-2026 .
  138. "¡Scala 3.4.1 ya está disponible!" . Scala-lang.org . 2024-03-29 . Consultado el 2024-08-12 .
  139. "¡Scala 3.4.2 ya está disponible!" . Scala-lang.org . 16-05-2024 . Consultado el 12-08-2024 .
  140. "Todas las versiones disponibles" . www.scala-lang.org . Consultado el 20 de abril de 2026 .
  141. "¡Scala 3.5.0 lanzado!" . Scala-lang.org . 22-08-2024 . Consultado el 18-06-2026 .
  142. "¡Scala 3.5.1 ya está disponible!" . Scala-lang.org . 2024-09-20 . Consultado el 2026-06-18 .
  143. "¡Scala 3.5.2 ya está disponible!" . Scala-lang.org . 22-10-2024 . Consultado el 18-06-2026 .
  144. "¡Scala 3.6.2 ya está disponible!" . Scala-lang.org . 10-12-2024 . Consultado el 18-06-2026 .
  145. "¡Scala 3.6.3 ya está disponible!" . Scala-lang.org . 2025-01-20 . Consultado el 2026-06-18 .
  146. "¡Scala 3.6.4 ya está disponible!" . Scala-lang.org . 2025-03-07 . Consultado el 2026-06-18 .
  147. "¡Scala 3.7.0 lanzado!" . Scala-lang.org . 2025-05-07 . Consultado el 2026-06-18 .
  148. "¡Scala 3.7.1 ya está disponible!" . Scala-lang.org . 2025-06-04 . Consultado el 2026-06-18 .
  149. "¡Scala 3.7.2 ya está disponible!" . Scala-lang.org . 2025-08-01 . Consultado el 2026-06-18 .
  150. "¡Scala 3.7.3 ya está disponible!" . Scala-lang.org . 2025-09-09 . Consultado el 2026-06-18 .
  151. "¡Scala 3.7.4 ya está disponible!" . Scala-lang.org . 11/11/2025 . Consultado el 18/06/2026 .
  152. 1 2 "¡Scala 3.8 lanzado!" . Scala-lang.org . 2026-01-22 . Consultado el 2026-06-18 .
  153. "¡Scala 3.8.2 ya está disponible!" . Scala-lang.org . 24-02-2026 . Consultado el 18-06-2026 .
  154. "¡Scala 3.8.3 ya está disponible!" . Scala-lang.org . 2026-03-31 . Consultado el 2026-06-18 .
  155. "¡Scala 3.8.4 ya está disponible!" . Scala-lang.org . 2026-06-05 . Consultado el 2026-06-18 .
  156. "Preguntas frecuentes sobre ThoughtWorks Technology Radar" .
  157. "ThoughtWorks Technology Radar MAYO 2013" (PDF) .
  158. "Scala, las partes buenas" .
  159. "El estado de Java en 2018" .
  160. "Índice de popularidad de lenguajes de programación" .
  161. 1 2 O'Grady, Stephen (1 de marzo de 2021). "Clasificación de lenguajes de programación de RedMonk: enero de 2021" . RedMonk .
  162. 1 2 "Índice TIOBE de mayo de 2021" .
  163. Greene, Kate (1 de abril de 2009). "El secreto detrás del crecimiento de Twitter: cómo un nuevo lenguaje de programación web está ayudando a la empresa a manejar su creciente popularidad" . Technology Review . MIT . Consultado el 6 de abril de 2009 .
  164. Breck, Colin; Link, Percy (23 de marzo de 2020). "Planta de energía virtual de Tesla (arquitectura y diseño)" . Recuperado el 28 de marzo de 2023 .
  165. "Código fuente de Apache Kafka en GitHub" . Apache Software Foundation . Consultado el 29 de marzo de 2023 .
  166. "Play Framework, Akka y Scala en Gilt Groupe" . Lightbend. 15 de julio de 2013. Consultado el 16 de julio de 2016 .
  167. "Scala, Lift y el futuro" . Archivado del original el 13 de enero de 2016. Consultado el 4 de julio de 2015 .
  168. Saeta, Brennan (17 de febrero de 2014). "Por qué nos encanta Scala en Coursera" . Ingeniería de Coursera . Consultado el 21 de septiembre de 2023 .
  169. "Jarrod Nettles, gerente de producto de ingeniería de Apple, en Twitter" . Jarrod Nettles . Consultado el 11 de marzo de 2016 .
  170. "30 ofertas de trabajo para programadores Scala en Apple" . Alvin Alexander . Consultado el 11 de marzo de 2016 .
  171. David Reid y Tania Teixeira (26 de febrero de 2010). "¿Está la gente dispuesta a pagar por las noticias en línea?" . BBC . Consultado el 28 de febrero de 2010 .
  172. "Guardian cambia de Java a Scala" . Heise Online . 5 de abril de 2011. Consultado el 5 de abril de 2011 .
  173. "Guardian.co.uk Cambiando de Java a Scala" . InfoQ.com. 4 de abril de 2011. Consultado el 5 de abril de 2011 .
  174. Roy, Suman; Sundaresan, Krishna (13 de mayo de 2014). "Construyendo Blackbeard: Un sistema de sindicación impulsado por Play, Scala y Akka" . The New York Times . Recuperado el 20 de julio de 2014 .
  175. Pavley, John (11 de agosto de 2013). "Avance: HuffPost lleva la colaboración en tiempo real a la redacción" . Huffington Post . Recuperado el 20 de julio de 2014 .
  176. Binstock, Andrew (14 de julio de 2011). "Entrevista con Martin Odersky de Scala" . Dr. Dobb's Journal . Consultado el 10 de febrero de 2012 .
  177. Synodinos, Dionysios G. (2010-10-11). "LinkedIn Signal: Un estudio de caso para Scala, JRuby y Voldemort" . InfoQ .
  178. "Los encuentros en la vida real merecen API en tiempo real" .
  179. "Actualizaciones en tiempo real llegan a la aplicación web Remember The Milk" .
  180. "¿QUÉ ES SCALA?" . 8 de marzo de 2023. Archivado del original el 17 de marzo de 2023. Consultado el 17 de marzo de 2023 .
  181. Novet, Jordan (4 de junio de 2015). "Airbnb anuncia Aerosolve, un paquete de software de aprendizaje automático de código abierto" . Recuperado el 9 de marzo de 2016 .
  182. Kops, Alexander (14 de diciembre de 2015). "Zalando Tech: De Java a Scala en menos de tres meses" . Recuperado el 9 de marzo de 2016 .
  183. Calçado, Phil (13 de junio de 2014). "Creación de productos en SoundCloud—Parte III: Microservicios en Scala y Finagle" . Recuperado el 9 de marzo de 2016 .
  184. "Estudios de casos de clientes: SoundCloud" . Concurrent Inc. 18 de noviembre de 2014. Consultado el 9 de marzo de 2016 .
  185. Scala en Morgan Stanley (video). Skills Matter. 3 de diciembre de 2015. Consultado el 11 de marzo de 2016 .
  186. Greg Soltis (3 de diciembre de 2015). SF Scala, Greg Soltis: Servicios de alto rendimiento en Scala (vídeo). Skills Matter. Archivado del original el 21 de diciembre de 2021. Consultado el 11 de marzo de 2016 .
  187. Lee Mighdoll. "Empleos de Scala en Nest" . Consultado el 11 de marzo de 2016 .
  188. Nurun. "Nurun lanza una plataforma transaccional rediseñada con Walmart Canadá" . Consultado el 11 de diciembre de 2013 .
  189. Horie, André K. (31 de enero de 2017). "Reescritura del motor de Duolingo en Scala" . Recuperado el 3 de febrero de 2017 .
  190. "Repositorio de HMRC en GitHub" . GitHub .
  191. "Conozca a M1 Finance, patrocinador Oro de ScalaCon" . ScalaCon . Consultado el 2 de septiembre de 2023 .
  192. "Repositorio de Lichess en GitHub" . GitHub .
  193. Hale, Coda (29 de noviembre de 2011). "El resto de la historia" . codahale.com . Consultado el 7 de noviembre de 2013 .
  194. Krikorian, Raffi (17 de marzo de 2015). O'Reilly Software Architecture Conference 2015 Complete Video Compilation: Re-Architecting on the Fly - Raffi Krikorian - Part 3 (video). O'Reilly Media. El evento ocurre a las 4:57 . Recuperado el 8 de marzo de 2016. Lo que yo habría hecho diferente hace cuatro años es usar Java y no usar Scala como parte de esta reescritura. [...] a un ingeniero le tomaría dos meses antes de que fuera completamente productivo y escribiera código Scala.
  195. Scott, Kevin (11 de marzo de 2015). "¿LinkedIn se está deshaciendo de Scala?" . quora.com . Consultado el 25 de enero de 2016 .
  196. "Chisel: Construcción de hardware en un lenguaje embebido Scala" . UC Berkeley APSIRE . Consultado el 27 de mayo de 2020 .

Lecturas adicionales

  • Odersky, Martin; Spoon, Lex; Venners, Bill (15 de diciembre de 2019). Programación en Scala: Una guía completa paso a paso (4.ª  ed.). Artima Inc. pág.  896. ISBN 978-0-9815316-1-8.
  • Horstmann, Cay (15 de diciembre de 2016). Scala para impacientes (2.ª  ed.). Addison-Wesley Professional . pág.  384. ISBN 978-0-134-54056-6.
  • Wampler, Dean; Payne, Alex (14 de diciembre de 2014). Programación en Scala: Escalabilidad = Programación funcional + Objetos (2.ª  ed.). O'Reilly Media . pág.  583. ISBN 978-1-491-94985-6.
  • Suereth, Joshua D. (Primavera de 2011). Scala en profundidad . Manning Publications . pág . 225. ISBN  978-1-935182-70-2.
  • Meredith, Gregory (2011). Patrones de diseño monádicos para la web (PDF) (1.ª  ed.). pág.  300.
  • Odersky, Martin; Spoon, Lex; Venners, Bill (10 de diciembre de 2008). Programación en Scala, libro electrónico (1.ª  ed.). Artima Inc.