Scala (lenguaje de programación)
Scala es un lenguaje de programación multi-paradigma diseñado para expresar patrones comunes de programación en forma concisa, elegante y con tipos seguros. Integra sutilmente características de lenguajes funcionales y orientados a objetos. La implementación actual se ejecuta en la máquina virtual de Java y es compatible con las aplicaciones Java existentes.
Scala | ||
---|---|---|
Desarrollador(es) | ||
Laboratorio de métodos de programación de la EPFL https://www.scala-lang.org/ | ||
Información general | ||
Extensiones comunes | scala y sc | |
Paradigma | funcional, orientado a objetos | |
Apareció en | 2003 | |
Diseñado por | Martin Odersky | |
Última versión estable | 3.2.1 (7 de noviembre de 2022 (10 meses y 27 días)) | |
Sistema de tipos | estático, fuerte | |
Influido por | Smalltalk, Java, Haskell, Standard ML, OCaml | |
Licencia | BSD | |
Características
Orientación a objetos
Scala es un lenguaje de programación puro orientado a objetos, en el sentido de que cada valor es un objeto. El tipo y comportamiento de los objetos se describe por medio de clases y traits. La abstracción de clases se realiza extendiendo otras clases y usando un mecanismo de composición basado en mixins como un reemplazo limpio de la herencia múltiple.
Lenguaje funcional
Scala también posee características propias de los lenguajes funcionales. Por ejemplo, las funciones son valores de primera clase, soportando funciones anónimas, orden superior, funciones anidadas y currificación. Viene integrado de fábrica con la técnica de pattern matching para modelar tipos algebraicos usados en muchos lenguajes funcionales.
Tipificado estático
Scala está equipado con un sistema de tipos expresivo que refuerza a que las abstracciones de tipos se usen en forma coherente y segura.
Extensibilidad
Scala se diseñó teniendo en mente el hecho de que en la práctica el desarrollo de aplicaciones requiere a menudo de extensiones específicas del lenguaje. Para ello, se proporcionan una combinación única de mecanismos que facilitan agregar construcciones nuevas al lenguaje en forma de bibliotecas.
Ejemplos
Hola Mundo escrito en Scala 3
@main def main() = println("Hello, World!")
A diferencia de la típica aplicación 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 se ejecuta con:
$ scala HelloWorld
Esto es análogo al proceso de compilación y ejecución de código Java. De hecho, el proceso de compilación y ejecución de Scala es idéntico al de Java, haciéndolo compatible con herramientas como Apache Ant.
Una versión más corta del "Hola mundo" en Scala es:
println("Hello, world!")
Scala incluye un shell interactivo y soporte de scripting incorporado. Guardado en un archivo llamado HelloWorld2.scala, el cual puede ser ejecutado como script sin prioridad de compilación usando:
$ scala HelloWorld2.scala
Los comandos también pueden ser ingresados en el intérprete de Scala, usando la opción -e:
$ scala -e 'println("Hello, World!")'
Las expresiones pueden ser ingresadas en el REPL:
$ scala
Welcome to Scala 2.12.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_131).
Type in expressions for evaluation. Or try :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.
// Java:
int mathFunction(int num) {
int numSquare = num*num;
return (int) (Math.cbrt(numSquare) +
Math.log(numSquare));
}
// Scala: Direct conversion from Java
// no import needed; scala.math
// already imported as `math`
def mathFunction(num: Int): Int = {
var numSquare: Int = num*num
return (math.cbrt(numSquare) + math.log(numSquare)).
asInstanceOf[Int]
}
// Scala: More idiomatic
// Uses type inference, omits `return` statement,
// uses `toInt` method, declares numSquare immutable
import math._
def mathFunction(num: Int) = {
val numSquare = num*num
(cbrt(numSquare) + log(numSquare)).toInt
}
Algunas diferencias sintácticas en este código son:
- Scala no requiere punto y coma al final de las sentencias.
- Los tipos están capitalizados:
Int, Double, Boolean
en vez deint, double, boolean
. - Parámetros y tipos de retorno continúan, como en Pascal, en vez de preceder como en C.
- Los métodos deben ser precedidos por
def
. - Variables locales y de clase deben ser precedidos por
val
(indica una variable inmutable) ovar
(indica una variable mutable). - El operador
return
es innecesario en una función (a pesar de estar permitido); el valor de la última sentencia o expresión ejecutada es normalmente el valor de la función. - En vez del operador cast
(Type) foo
, Scala usafoo.asInstanceOf[type]
, o una función especializada comotoDouble
otoInt
. - En vez de la importación de paquetes de Java
import foo.*;
, Scala usaimport foo._
. - Una función o método
foo()
también puede ser llamado solofoo
; el métodothread.send(signo)
también puede ser llamado solamente comothread send signo
; y el métodofoo.toString()
también puede ser llamado solo comofoo toString
.
Ejemplo con Clases
El siguiente ejemplo contrasta la definición de clases en Java y en Scala.
// Java:
public class Point {
private final double x, y;
public Point(final double x, final double y) {
this.x = x;
this.y = y;
}
public Point(
final double x, final double y,
final boolean addToGrid
) {
this(x, y);
if (addToGrid)
grid.add(this);
}
public Point() {
this(0.0, 0.0);
}
public double getX() {
return x;
}
public double getY() {
return y;
}
double distanceToPoint(final Point other) {
return distanceBetweenPoints(x, y,
other.x, other.y);
}
private static Grid grid = new Grid();
static double distanceBetweenPoints(
final double x1, final double y1,
final double x2, final double y2
) {
return Math.hypot(x1 - x2, y1 - y2);
}
}
|
// Scala
class Point(
val x: Double, val y: Double,
addToGrid: Boolean = false
) {
import Point._
if (addToGrid)
grid.add(this)
def this() = this(0.0, 0.0)
def distanceToPoint(other: Point) =
distanceBetweenPoints(x, y, other.x, other.y)
}
object Point {
private val grid = new Grid()
def distanceBetweenPoints(x1: Double, y1: Double,
x2: Double, y2: Double) = {
math.hypot(x1 - x2, y1 - y2)
}
}
|