diff --git a/.gitignore b/.gitignore index f4df0be..359a33e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ *.pdf *.html + +bin/ \ No newline at end of file diff --git a/.sdkmanrc b/.sdkmanrc new file mode 100644 index 0000000..58fb857 --- /dev/null +++ b/.sdkmanrc @@ -0,0 +1 @@ +java=22-open diff --git a/build.sh b/build.sh index c7965b0..5e5f5b5 100755 --- a/build.sh +++ b/build.sh @@ -1,4 +1,6 @@ #!/bin/bash +mkdir -p bin && javac -d bin snippets/*.java + marp slides.md -o slides.html marp slides.md -o slides.pdf \ No newline at end of file diff --git a/slides.md b/slides.md index bdee195..09b7290 100644 --- a/slides.md +++ b/slides.md @@ -45,13 +45,6 @@ * [¿Qué versión de Java usáis regularmente?](https://www.jetbrains.com/lp/devecosystem-2023/java/#java_versions) ---- - -# Jetbrains ecosystem survey - -* [¿Qué versión de Java usáis regularmente?](https://www.jetbrains.com/lp/devecosystem-2023/java/#java_versions) - - | Version | Percentage| |---------|-----------| | Java8 | 50% | @@ -120,6 +113,7 @@ * Incluido en Java 16. * Muy esperado por la comunidad. * Inmutables. +* Constructor canónico. --- @@ -174,14 +168,30 @@ # Tipos de datos algebraicos -* AKA ADTs (algebraic data types) +* AKA ADTs (algebraic data types). * Viene de las matemáticas. * Productos y sumas de tipos. + `a + b` `a * b` +* Cardinalidad. * Recursivo. --- -# Tipos de datos algebraicos (II) +# ADTs + +* Tienen propiedades algebraicas: + * Identidad: + `a + 0 <=> a` `a * 1 <=> a` + * Distributiva: + `(a * b) + (a * c) <=> a * (b + c)` + * Conmutativa: + `a * b <=> b * a` `a + b <=> b + a` + * Asociativa: + `a + b + c <=> a + (b + c)` `a * b * c <=> a * (b * c)` + +--- + +# ADTs * ¿Cómo podemos representarlos en Java? * Un `record` es un producto de tipos. @@ -190,40 +200,82 @@ --- -# Tipos de datos algebraicos: List +# ADTs: Identidad Suma + +```java +sealed interface Sum { + record A(String value) implements Sum {} + // uninstantiable, similar to Void type + final class B implements Sum { + private B() {} + } +} +``` +--- + +# ADTs: Identidad Producto + +```java +// just one value +enum Unit { VALUE } +record Product(String value, Unit unit) {} +``` + +--- + +# ADTs: List ```java sealed interface List { + record NonEmpty(T head, List tail) implements List {} + record Empty() implements List {} } ``` --- -# Tipos de datos algebraicos: Tree +# ADTs: Tree ```java sealed interface Tree { + record Node(T value, Tree left, Tree right) implements Tree { } + record Leaf(T value) implements Tree {} } ``` --- -# Tipos de datos algebraicos: Optional +# ADTs: Optional ```java sealed interface Optional { + record Empty() implements Optional { } + record Present(T value) implements Optional {} } ``` --- -# Tipos de datos algebraicos: Json +# ADTs: Either + +```java +sealed interface Either { + + record Left(L left) implements Either { } + + record Right(R right) implements Either {} +} +``` + +--- + +# ADTs: Json ```java sealed interface Json { @@ -238,7 +290,21 @@ --- -# Tipos de datos algebraicos: Errores +# ADTs: Errores + +```java +interface MovieRepository { + MovieResponse create(Movie movie); +} + +sealed interface MovieResponse permits MovieCreated, MovieResponse {} + +record MovieCreated(UUID id) implements MovieResponse {} +``` + +--- + +# ADTs: Errores ```java sealed interface MovieError extends MovieResponse { @@ -255,6 +321,16 @@ --- +# ADTs: Either + +```java +interface MovieRepository { + Either create(Movie movie); +} +``` + +--- + # Próximamente :watch: @@ -414,7 +490,7 @@ a + b + c <=> a + (b + c) a * b * c <=> a * (b * c) - currying: - (a, b) -> c <=> a -> b + (a, b) -> c <=> a -> b -> c meta: - target audience diff --git a/snippets/Either.java b/snippets/Either.java new file mode 100644 index 0000000..bae7adc --- /dev/null +++ b/snippets/Either.java @@ -0,0 +1,36 @@ +package snippets; + +import java.util.function.Function; + +sealed interface Either { + record Left(L left) implements Either { } + record Right(R right) implements Either {} + + default Either map(Function mapper) { + return switch (this) { + case Left(var left) -> new Left<>(left); + case Right(var right) -> new Right<>(mapper.apply(right)); + }; + } + + default Either mapError(Function mapper) { + return switch (this) { + case Left(var left) -> new Left<>(mapper.apply(left)); + case Right(var right) -> new Right<>(right); + }; + } + + default Either flatMap(Function> mapper) { + return switch (this) { + case Left(var left) -> new Left<>(left); + case Right(var right) -> mapper.apply(right); + }; + } + + default T fold(Function leftMapper, Function rightMapper) { + return switch (this) { + case Left(var left) -> leftMapper.apply(left); + case Right(var right) -> rightMapper.apply(right); + }; + } +} diff --git a/snippets/Movie.java b/snippets/Movie.java new file mode 100644 index 0000000..50520f9 --- /dev/null +++ b/snippets/Movie.java @@ -0,0 +1,7 @@ +package snippets; + +import java.util.UUID; + +record Movie(UUID id) { + +} diff --git a/snippets/MovieRepository.java b/snippets/MovieRepository.java new file mode 100644 index 0000000..dd99244 --- /dev/null +++ b/snippets/MovieRepository.java @@ -0,0 +1,5 @@ +package snippets; + +interface MovieRepository { + MovieResponse create(Movie movie); +}