diff --git a/slides/sources/enum-1.md b/slides/sources/enum-1.md
new file mode 100644
index 0000000000000000000000000000000000000000..2a94488ec178839824beb317508b7bb62bf9428e
--- /dev/null
+++ b/slides/sources/enum-1.md
@@ -0,0 +1,328 @@
+% Enums
+%
+%
+
+Enums: Motivation
+=================
+
+We have seen that case classes *aggregate several values* into a single abstraction.
+For instance, the `Rational` case class aggregates a numerator and a denominator.
+
+Conversely, how could we define an abstraction *accepting alternative values*?
+
+\example
+
+Define a `Paradigm` type that can be either `Functional` or `Imperative`.
+
+Enums
+=====
+
+We can define an abstraction accepting alternative values with an \red{enum}:
+
+~~~
+enum Paradigm
+  case Functional, Imperative
+~~~
+
+This definition introduces:
+
+- A new \red{type}, named `Paradigm`.
+- Two possible \red{values} for this type, `Paradigm.Functional` and
+  `Paradigm.Imperative`.
+
+Enumerate the Values of an Enumeration
+======================================
+
+It is possible to enumerate all the values of an enum by calling the
+`values` operation on the enum companion object:
+
+\begin{tabular}{ll}
+ \verb@Paradigm.values@              \wsf Array(Functional, Imperative) \\
+ \verb@val p = Paradigm.Functional@  \wsf p: Paradigm = Functional \\
+ \verb@p == Paradigm.values(0)@      \wsf true
+\end{tabular}
+
+Discriminate the Values of an Enumeration
+=========================================
+
+You can discriminate between the values of an enum by using a \red{match}
+expression:
+
+~~~
+def isReferentiallyTransparent(paradigm: Paradigm): Boolean =
+  paradigm match
+    case Paradigm.Functional => true
+    case Paradigm.Imperative => false
+~~~
+
+->
+
+And then:
+
+\begin{tabular}{ll}
+ \verb@val p = Paradigm.Functional@   \wsf p: Paradigm = Functional \\
+ \verb@isReferentiallyTransparent(p)@ \wsf true
+\end{tabular}
+
+Match Syntax
+============
+
+_Pattern matching_ is a generalization of `switch` from C/Java
+to class hierarchies.
+
+It’s expressed in Scala using the `match` keyword.
+
+- `match` is followed by a sequence of \red{cases}, `case value => expr`.
+- Each case associates an \red{expression} `expr` with a
+  \red{constant} `value`.
+
+We will see in the next slides that pattern matching can do more
+than discriminating enums.
+
+Enumerations Can Have Methods
+=============================
+
+Alternatively, we can define `isReferentiallyTransparent` as a method:
+
+~~~
+enum Paradigm
+  case Functional, Imperative
+
+  def isReferentiallyTransparent: Boolean = this match
+    case Functional => true
+    case Imperative => false
+~~~
+
+->
+
+And then:
+
+\begin{tabular}{ll}
+ \verb@val p = Paradigm.Functional@  \wsf p: Paradigm = Functional \\
+ \verb@p.isReferentiallyTransparent@ \wsf true
+\end{tabular}
+
+Enumerations Values Can Take Parameters
+=======================================
+
+Consider the following definition of a data type modeling students
+following a lecture:
+
+~~~
+enum Student
+  case Listening
+  case Asking(question: String)
+~~~
+
+This definition introduces a `Student` type consisting of two cases,
+`Listening` or `Asking`. The `Asking` case is parameterized with a
+value parameter `question`. Since `Listening` is not parameterized,
+it is treated as a normal enum value.
+
+Matching on Constructors
+========================
+
+Since `Asking` is not a constant, we match on it using
+a _constructor pattern_:
+
+~~~
+student match
+  case Student.Listening => "Student is listening"
+  case Student.Asking(q) => s"Student is asking: $q"
+~~~
+
+A constructor pattern allows us to _extract_ the value of
+the `question` parameter, in case the `student` value is
+indeed of type `Asking`.
+
+Here, the `q` identifier is bound to the `question` parameter
+of the `student` object.
+
+Evaluating Match Expressions
+============================
+
+An expression of the form
+$$\btt
+e\ match\ \{\ case\ p_1 => e_1\ ...\ case\ p_n => e_n\ \}
+$$
+matches the value of the selector $\btt e$ with the patterns
+$\btt p_1, ..., p_n$ in the order in which they are written.
+
+The whole match expression is rewritten to the right-hand side of the first
+case where the pattern matches the selector $e$.
+
+References to pattern variables are replaced by the corresponding
+parts in the selector.
+
+Forms of Patterns
+=================
+
+Patterns are constructed from:
+
+ -  _constructors_, e.g. `Rational`, `Student.Asking`,
+ -  _variables_, e.g. `n`, `e1`, `e2`,
+ -  _wildcard patterns_ `_`,
+ -  _constants_, e.g. `1`, `true`, `Paradigm.Functional`.
+
+Variables always begin with a _lowercase letter_.
+
+The same variable name can only appear _once_ in a pattern.
+
+Names of constants begin with a capital letter,
+with the exception of the reserved words `null`, `true`,
+`false`.
+
+What Do Patterns Match?
+=======================
+
+- A constructor pattern $\btt C(p_1 , ..., p_n)$ matches
+  all the values of type $\btt C$ (or a subtype) that have been
+  constructed with arguments matching the patterns $\btt p_1, ..., p_n$.
+- A variable pattern $\btt x$ matches any value, and
+  \red{binds} the name of the variable to this value.
+- A constant pattern $\btt c$ matches values that are equal to
+  $\btt c$ (in the sense of `==`)
+
+Matching on Case Classes
+========================
+
+Constructor patterns also works with case classes:
+
+~~~
+def invert(x: Rational): Rational =
+  x match
+    case Rational(0, _) => sys.error("Unable to invert zero")
+    case Rational(n, d) => Rational(d, n)
+~~~
+
+Relationship Between Case Classes and Parameterized Enum Cases
+==============================================================
+
+Case classes and parameterized enum cases are very similar.
+
+When should you use one or the other?
+
+- Parameterized enum cases should be used to define a type
+  that is part of a set of alternatives,
+- If there are no alternatives, just use a case class.
+
+Enumerations Can Be Recursive
+=============================
+
+A list of integer values can be modeled as either an empty list,
+or a node containing both a number and a reference to the remainder
+of the list.
+
+~~~
+enum List
+  case Empty
+  case Node(value: Int, next: List)
+~~~
+
+A list with values `1`, `2`, and `3` can be constructed as follows:
+
+~~~
+List.Node(1, List.Node(2, List.Node(3, List.Empty)))
+~~~
+
+Enumerations Can Take Parameters
+================================
+
+~~~
+enum Vehicle(val numberOfWheels: Int)
+  case Unicycle extends Vehicle(1)
+  case Bicycle  extends Vehicle(2)
+  case Car      extends Vehicle(4)
+~~~
+
+- Enumeration cases have to use an explicit `extends` clause
+
+Exercise: Arithmetic Expressions
+================================
+
+Define a datatype modeling arithmetic expressions.
+
+An expression can be:
+
+- a number (e.g. `42`),
+- a sum of two expressions,
+- or, the product of two expressions.
+
+`Expr` Type Definition
+======================
+
+~~~
+enum Expr
+  case Number(n: Int)
+  case Sum(lhs: Expr, rhs: Expr)
+  case Prod(lhs: Expr, rhs: Expr)
+
+->
+
+\begin{tabular}{ll}
+ \verb@val one = Expr.Number(1)@  \wsf one: Expr = Number(1) \\
+ \verb@val two = Expr.Number(2)@  \wsf two: Expr = Number(2) \\
+ \verb@Expr.Sum(one, two)@        \wsf Sum(Number(1), Number(2))
+\end{tabular}
+
+
+Exercise
+========
+
+Is the following match expression valid?
+
+~~~
+expr match
+  case Expr.Sum(x, x) => Expr.Prod(2, x)
+  case e              => e
+~~~
+
+     O         Yes
+     O         No
+
+Exercise
+========
+
+Implement an `eval` operation that takes an `Expr` as parameter and
+evaluates its value:
+
+~~~
+def eval(e: Expr): Int
+~~~
+
+Examples of use:
+
+\begin{tabular}{ll}
+ \verb@eval(Expr.Number(42))@  \wsf 42 \\
+ \verb@eval(Expr.Prod(2, Expr.Sum(Expr.Number(8), Expr.Number(13))))@  \wsf 42
+\end{tabular}
+
+Exercise
+========
+
+Implement a `show` operation that takes an `Expr` as parameter and
+returns a `String` representation of the operation.
+
+Be careful to introduce parenthesis when necessary!
+
+~~~
+def show(e: Expr): String
+~~~
+
+Examples of use:
+
+\begin{tabular}{ll}
+ \verb@show(Expr.Number(42))@  \wsf "42" \\
+ \verb@show(Expr.Prod(2, Expr.Sum(Expr.Number(8), Expr.Number(13))))@  \wsf "2 * (8 + 13)"
+\end{tabular}
+
+Summary
+=======
+
+In this lecture, we have seen:
+
+- how to define data types accepting alternative values using
+  `enum` definitions,
+- enumeration cases can be discriminated using pattern matching,
+- enumeration cases can take parameters or be simple values,
+- pattern matching allows us to extract information carried by an object.
diff --git a/slides/sources/enum-2.md b/slides/sources/enum-2.md
new file mode 100644
index 0000000000000000000000000000000000000000..348950bd3af6c4e92e0150db6d8ca56d950a71f3
--- /dev/null
+++ b/slides/sources/enum-2.md
@@ -0,0 +1,115 @@
+% Business Domain Modeling
+%
+%
+
+Business Domain Modeling
+========================
+
+Enums and case classes together provide basic building blocks
+for defining data types.
+
+They are typically used to **model the business domain** of a program.
+
+How to Model Things?
+====================
+
+Modeling consists of translating concepts from the real world
+into data type definitions in the Scala world.
+
+Modeling requires you to think about what details of the real
+world are relevant for your program.
+
+> The purpose of abstraction is not to be vague, but to create
+> a new semantic level in which one can be absolutely precise.
+> 
+> Edsger W. Dijkstra
+
+
+Modeling Methodology (1)
+========================
+
+There is no systematic methodology: often, a same set of concepts
+can be modeled in multiple ways.
+
+But here are some advice.
+
+->
+
+- Identify the concepts (in general, nouns) that you are interested in
+- Identify the relations between them
+    - Does a concept _belong to_ another one?
+        - e.g. “a rational number _has_ a numerator and a denominator”
+        - e.g. “a sum _has_ a left summand and a right summand”
+    - Does a concept _generalize_ another one?
+        - e.g. “‘functional programming’ _is_ a possible programming paradigm”
+        - e.g. “an arithmetic operation can either _be_ a product or a sum”
+
+Modeling Methodology (2)
+========================
+
+- Translate each concept into a type definition
+    - Concepts belonging to others become **fields** of case classes
+      or of enumeration cases
+    - Concepts generalizing others become **enumerations**
+- Check that you can construct meaningful objects from your model
+
+Example: Painting Application
+=============================
+
+An image is made of a shape, a stroke width and a color.
+
+Possible shapes are a square or a circle. A square has a side length.
+A circle has a radius.
+
+A color has a blue component, a red component and a green component.
+Each component of a color is an integer value (between 0 and 255).
+
+->
+
+~~~
+case class Image(shape: Shape, strokeWidth: Int, color: Color)
+
+enum Shape {
+  case Square(side: Double)
+  case Circle(radius: Double)
+}
+
+case class Color(red: Int, green: Int, blue: Int)
+~~~
+
+Example: Painting Application
+=============================
+
+~~~
+case class Image(shape: Shape, strokeWidth: Int, color: Color)
+
+enum Shape
+  case Square(side: Double)
+  case Circle(radius: Double)
+
+case class Color(red: Int, green: Int, blue: Int)
+~~~
+
+A blue circle:
+
+~~~
+val blue = Color(0, 0, 255)
+val blueCircle = Image(Circle(10), 1, blue)
+~~~
+
+Data Types Define a Space of Possible States
+============================================
+
+The domain model defines the rules for constructing
+objects representing a possible state of a program.
+
+The more possible states, the more risks to have bugs
+or to reach illegal states.
+
+Hint: restrict the space of possible states to the minimum.
+
+Summary
+=======
+
+In this lecture we have seen how to model the business domain
+of a program using enumerations and case classes.