La idea de la charla e incluso el abstract de la charla se pensó antes que...
Java Language update By Brian Goetz ( Devoxx Belgium 2023)
El nombre de "Algebraico" proviene de las matemáticas discretas.
Se define estructuras de manera recursiva, indicando los distintos casos de definición y un axioma de clausura (formulando lo que queda fuera de lo definido)
En esencia son combinación de otros tipos, es decir, no son tipos de datos atómicos.
AND
. Se asocian con Tuplas y Records.OR
. Enumerados y también Sealed Class/Interfaces.Los "operadores del producto" son los tipos de sus campos.
Los valores que pueden contener es el producto cartesiano de todos los valores de sus campos. Se representan con tuplas.
Se puede establecer una equivalencia con el concepto de "conjunción lógica" (AND
).
El caso más sencillo es la tupla (tipo par) A x B
que contiene todas las parejas de elementos del tipo A
y del tipo B
. El orden es importante A x B ≠ B x A
class A {
boolean type1;
int type2;
}
Se puede establecer una equivalencia con el concepto de "unión disjunta" (OR
).
Un tipo que puede tomar diferentes valores pero estos son fijos.
Una de las ventajas es que permite comprobar los valores en tiempo de compilación.
Los enumerados son un caso especial de tipo suma(constructores sin argumentos).
enum TrafficLight {
GREEN, YELLOW, RED;
}
Los valores de los tipos algebraicos son analizados con Pattern Matching (Concordancia de patrones) para identificar el tipo de dato y extraer sus valores. A menudo este análisis es recursivo.
Esta es una característica clave para aprovechar los tipos de datos algebraicos realizando verificaciones en tiempo de compilación.
Los records son tuplas (tipos producto), simplemente los valores son accedidos por "nombre". En Java todo es semántico y se accede por nombre y además es menos error prone.
En Java desde la versión 16, (funcionalidad preliminar en java 14) (JEP 395) . Es el soporte que da Java a los tipos productos. Son inmutables y tienen predefinidos los métodos getters
, equals
, hasCode
y toString
No es equivalente a Lombock, tiene un carácter semántico en Java.
record MyRecord(boolean type1, int type2){}
En java desde la versión 17 (preliminar en Java 15). (JEP 409)
También tienen un carácter semántico.
Son los tipos suma, enumerados con esteroides.
sealed interface MyError{
int getCode();
final class IOHttpCodeError extends RuntimeException implements MyError {
public int getCode() { return 1; }
public String getSource() { return "HTTP"; }
}
final class RageValidationError extends RuntimeException implements MyError {
public int getCode() { return 2; }
public String getType() { return "Range"; }
}
}
class ExamplePatterMatching {
public static String getError( MyError error ){
return switch( error ) {
case MyError.IOHttpCodeError ioe ->
"IO MyError code: %d, source: %s"
.formatted(ioe.getCode(), ioe.getSource());
case MyError.RageValidationError ve ->
"Validation error code:%d, type:%s"
.formatted(ve.getCode(), ve.getType());
};
}
}
Tanto los records como los sealed class/interfaces tienen un carácter semántico y es la nueva representación del concepto de Data en Java.
Con ellos el sistema de tipos de Java es más rico y robusto.
El uso de Pattern Matching, con el remoledado comando switch
, permite explotar de manera eficiente los tipos algebraicos, permitiendo:
Domain Specific Language Crear nuestros propios lenguajes para un dominio específico.
En este caso es un lenguaje interpretado donde existe unos "comandos o instrucciones" y uno o varios interpretes, y donde:
El api de Immutable Collection que Java no se atrevió hacer
"El Optional que Java no quiso hacer"
"La gestión de errores que estaría genial que Java lo tuviera"
Muchas gracias.