% -*- mode: latex; -*- mustache tags:  
\ifx\wholebook\relax\else

	\documentclass[10pt,twoside,english]{root/support/latex/sbabook/sbabook}
  \usepackage{import}
  \subimport{root/support/latex/}{common.tex}

  \hypersetup{pdfinfo = {
    Title = {{Pharo Mooc}},
    Author = {},
    Keywords = {pharo, smalltalk}}}
  \begin{document}
\fi

\chapter{Crafting a Simple Embedded DSL with Pharo}
In this tutorial we develop a simple Domain Specific Language (DSL) for rolling dice. Players of games such as Dungeon and Dragons are familiar with the DSL we implement. An example of such DSL is
\textcode{2 D20 + 1 D6}.  This example means that we should roll two 20-faces dice and one time a 6 faces die. This tutorial shows how we can (1) simply reuse traditional operator such as \textcode{+}, (2) develop an embedded DSL and (3) use class extensions (aka open classes).
\section{Getting Started}
Using the code browser (click on the background to open the \textcode{World menu} and select \textcode{System Browser}), define a package named \textcode{Dice} (contextual menu, \textcode{Add package}).
\subsection{Defining the Class Die}
In this package, define a class \textcode{Die} with an instance variable \textcode{faces} (contextual menu, \textcode{Add class}).

\begin{displaycode}{smalltalk}
Your code here
\end{displaycode}

Add an \textcode{initialize} protocol, and define a method \textcode{initialize} that simply sets the default number of faces to 6. Save this method (\textcode{ctrl s})

\begin{displaycode}{smalltalk}
Your code here
\end{displaycode}
\subsection{Creating a Test}
It is always empowering to verify that the code we write is always working as we defined it. For this purpose we create a unit test. So we define the class \textcode{DieTest} as a subclass of \textcode{TestCase}.

\begin{displaycode}{smalltalk}
TestCase subclass: #DieTest
    instanceVariableNames: ''
    classVariableNames: ''
    package: 'Dice'
\end{displaycode}

We add a new test \textcode{testInitializeIsOk} to make sure we can create a new dice.

\begin{displaycode}{smalltalk}
DieTest >> testInitializeIsOk
    self shouldnt: [ Die new ] raise: Error
\end{displaycode}

When this method is saved, you can click on the gray icon in front of the method name in the methods pane to execute the test. The icon should become green.
\section{Rolling a Die}
To roll a die we use the method  \textcode{atRandom} from \textcode{Number}. This method randomly chooses a
number between one and the receiver. For example \textcode{10 atRandom} draws a number between 1 and 10.
Now, define the \textcode{roll} method of the class \textcode{Die} class so that it returns a random number between 1 and the number of faces.

\begin{displaycode}{smalltalk}
Your code here
\end{displaycode}

Now we can create a new instance of \textcode{Die}, send it the message  \textcode{roll}, and get a result.
Open a workspace (\textcode{World menu}, \textcode{Workspace}). Write \textcode{Die new inspect} and execute the expression (\textcode{ctrl d}). You should get an inspector like the one shown in Figure \ref{figDiceNoDetail}. With it you can interact with the die by writing expressions in the bottom pane. In this pane, type \textcode{self roll} and print the result (\textcode{ctrl p}). You should get a random number.


\begin{figure}

\begin{center}
\includegraphics[width=0.5\textwidth]{figures/DiceNoDetail.png}\caption{Inspecting and interacting with a Die.\label{figDiceNoDetail}}\end{center}
\end{figure}

\subsection{Creating Another Test}
We define a test that verifies that rolling a new created dice (with 6 faces by default) only returns values comprised between 1 and 6. This is what the following test method is actually specifying.

\begin{displaycode}{smalltalk}
DieTest >> testRolling
    | d |
    d := Die new.
    1000 timesRepeat: [ self assert: (d roll between: 1 and: 6) ]
\end{displaycode}

Execute the test to make sure it runs fine.
\section{Instance Creation Interface}
Now, we would like to get a simpler way to create \textcode{Die} instances. For example we want to create a 20-faces dice as follows: \textcode{Die faces: 20}. Let us define a test for it. When you save this method, you might get a warning message saying that \textcode{faces:} is an unknown method name (aka., selector). Just confirm the name to validate.

\begin{displaycode}{smalltalk}
DieTest >> testCreationIsOk
    self shouldnt: [ Die faces: 20 ] raise: Error
\end{displaycode}

Execute the test and you should get an error message because the class \textcode{Die} does not have a method \textcode{faces:}. The message \textcode{faces:} is sent to the class \textcode{Die} and not to an instance of this class. Such methods are called class methods or class-side methods; this is equivalent to static methods in Java. To add such a method to a class from the code browser, you have to tick the \textcode{class} checkbox.

Another way to create this method is to do it right from the debugger that pops up when a method does not exist. Just click the \textcode{Create} button in the debugger, select the \textcode{Die} class, and the \textcode{instance creation} protocol. The method first creates an instance, then sends it the message \textcode{faces:}, and returns the instance. You can implement the method right in the debugger.

\begin{displaycode}{smalltalk}
Die class >> your code here
\end{displaycode}

To implement this method, you will have to send the message \textcode{new} to the class: \textcode{self} is the current class when implementing a class method.

\begin{note}
If your implementation of the method uses a temporary variable, you may want to simplify it by using the cascade operator \textcode{;} and the \textcode{yourself} message. Look at the implementation of \textcode{Object \textgreater{}\textgreater{} yourself} and its senders (contextual menu, \textcode{Senders of}) to get examples on how to do this.
\end{note}

This method can not yet be executed because you first have to implement the instance-side method \textcode{faces:} (the setter for the variable) that configure a new die with a number of faces passed as an argument. In Java, you would not have to do that because constructors can access instance variables. In Pharo, a class method only knows about the class variables not the instance variables. You can keep on using the debugger to do that or you can go back to the code browser.

\begin{displaycode}{smalltalk}
Your code here
\end{displaycode}

Now, all your tests should pass and this is good moment to save your code (\textcode{World menu}, \textcode{Save}).

So even if the class \textcode{Die} could implement more behavior, we are ready to implement a dice handle.
\section{First Specification of a Dice Handle}
Let us define a new class \textcode{DiceHandle} that represents a dice handle.

Here is the API that we would like to offer for now. We create a new instance of the handle then add some dice to it.

\begin{displaycode}{smalltalk}
DiceHandle new
    addDie: (Die faces: 6);
    addDie: (Die faces: 10);
    yourself
\end{displaycode}
\subsection{Testing a Dice Handle}
Of course we define a test for this new class. We define the class \textcode{DiceHandleTest} as follow.

\begin{displaycode}{smalltalk}
TestCase subclass: #DiceHandleTest
    instanceVariableNames: ''
    classVariableNames: ''
    package: 'Dice'
\end{displaycode}

We define a new test method as follows.

\begin{displaycode}{smalltalk}
DiceHandleTest >> testCreationAdding
    | handle |
    handle := DiceHandle new.
    handle addDie: (Die faces: 6);
    handle addDie: (Die faces: 10).
    self assert: handle diceNumber equals: 2.
\end{displaycode}

When you save the method, the code browser will offer to create the class and may warn you that \textcode{addDice} and \textcode{diceNumber} are unknown method names.

With another test, we can make sure we can add two times a similar dice.

\begin{displaycode}{smalltalk}
DiceHandleTest >> testAddingTwiceTheSameDice
    | handle |
    handle := DiceHandle new.
    handle addDie: (Die faces: 6);
    self assert: handle diceNumber equals: 1.
    handle addDie: (Die faces: 6).
    self assert: handle diceNumber equals: 2.
\end{displaycode}
\subsection{Defining the DiceHandle class}
The \textcode{DiceHandle} class defines one instance variable named \textcode{dice} to hold a collection of dice. Add this variable to the class now.

When an instance is initialized, the instance variable \textcode{dice} must contain an empty \textcode{OrderedCollection}. Implement the corresponding \textcode{initialize} method.

\begin{displaycode}{smalltalk}
Your code here
\end{displaycode}

Then we define a simple method (\textcode{addDie:}) to add a dice to the list of dice of the handle. You can do that from the code browser or from a debugger after having run a failing unit test.

\begin{displaycode}{smalltalk}
Your code here
\end{displaycode}

Now you can execute the code snippet and inspect it (\textcode{ctrl i}):

\begin{displaycode}{smalltalk}
DiceHandle new
    addDie: (Die faces: 6);
    addDie: (Die faces: 10);
    yourself
\end{displaycode}

You should get an inspector as shown in Figure \ref{diceHandleNoDetail}.


\begin{figure}

\begin{center}
\includegraphics[width=0.5\textwidth]{figures/DiceHandleNoDetail.png}\caption{Inspecting a dice handle\label{diceHandleNoDetail}}\end{center}
\end{figure}


Finally we should add the method \textcode{diceNumber} to the \textcode{DiceHandle} class to get the number of dice of the handle. The method returns the size of the \textcode{dice} collection.

\begin{displaycode}{smalltalk}
Your code here
\end{displaycode}

Now your tests should pass and this is good moment to save your code.
\section{Improving Programmer Experience}
When you open an inspector on a dice handle (such as the one in Figure \ref{diceHandleNoDetail}) you cannot see the details of the dices that compose the dice handle. Click on the \textcode{dice} instance variable and you only get a list of \textcode{\symbol{34}a Die\symbol{34}} without further information as you can see in Figure \ref{diceHandleNoDetail}.

Enhance the \textcode{printOn:} method of the \textcode{Die} class to provide more information: simply add the number of faces surrounded by parenthesis to make the result look like the one in Figure \ref{diceHandleDetail}.

\begin{note}
You may want to have a look at all the implementors of \textcode{printOn:} (contextual menu of the \textcode{printOn:} method, \textcode{Implementors of}) to get examples.
\end{note}

\begin{displaycode}{smalltalk}
Your code here
\end{displaycode}

Now in your inspector you can see the number of faces a dice has as shown by Figure \ref{diceDetail} and it is now easier to check the dice contained inside a handle (see Figure \ref{diceHandleDetail}).


\begin{figure}

\begin{center}
\includegraphics[width=0.5\textwidth]{figures/DiceDetail.png}\caption{Die details.\label{diceDetail}}\end{center}
\end{figure}



\begin{figure}

\begin{center}
\includegraphics[width=0.5\textwidth]{figures/DiceHandleDetail.png}\caption{Dice Handle with more information.\label{diceHandleDetail}}\end{center}
\end{figure}

\section{Rolling a Dice Handle}
Now we can define the rolling of a dice handle by simply summing the dice rolls. Implement the \textcode{roll} method of the \textcode{DiceHandle} class. This method must collect the results of rolling each dice of the handle and sum them.

\begin{note}
You may want to have a look at the method \textcode{sum} in the class \textcode{Collection}.
\end{note}

\begin{displaycode}{smalltalk}
Your code here
\end{displaycode}

We can now send the message \textcode{roll} to a dice handle.

\begin{displaycode}{smalltalk}
handle := DiceHandle new
    addDie: (Die faces: 6);
    addDie: (Die faces: 10);
    yourself.
handle roll
\end{displaycode}
\section{Role Playing Syntax}
We are ready to offer a syntax following practice of role playing game, i.e., using \textcode{2 D20} to create a handle of two 20-faces dice.  For this purpose we use class extensions: we define methods in the class \textcode{Integer}. We want these methods to only be available when the package \textcode{Dice} is loaded.

First let us specify what we would like to obtain by writing a new test in the class \textcode{DiceHandleTest}. Remember to always take  any opportunity to write tests.  When we execute \textcode{2 D20} we  should get a new handle composed of two dice and can verify that. This is what the method \textcode{testSimpleHandle} is doing.

\begin{displaycode}{smalltalk}
DiceHandleTest >> testSimpleHandle
    self assert: 2 D20 diceNumber equals: 2.
\end{displaycode}

Verify that the test is not passing! It is much more satisfactory to get a test running when it was not working before. Now define the method \textcode{D20} with a protocol name \textcode{*Dice}. The \textcode{*} (star) prefixing the protocol name indicates that the protocol belongs to another package. You can define this method either from the debugger resulting from the execution of the failed test or in the code browser.

The method \textcode{D20} simply creates a new dice handle, adds the correct number of dice to this handle, and returns the handle.

\begin{displaycode}{smalltalk}
Your code here
\end{displaycode}

Your test should pass and this is probably a good moment to save your work.

We could do the same for  different face numbers: 4, 6 and 10. But we should avoid duplicating logic and code. We first introduce a new method \textcode{D:} in the \textcode{Integer} class and, based on it, we define all the others.

\begin{displaycode}{smalltalk}
Your code here
\end{displaycode}

The \textcode{D20} method should now look like:

\begin{displaycode}{smalltalk}
Integer >> D20
    ^ self D: 20
\end{displaycode}

We have a compact form to create dice and we are ready for the last part: the addition of handles.
\subsection{Adding Handles}
Now we can simply support the addition of handles. Let us write a test first.

\begin{displaycode}{smalltalk}
DiceHandleTest >> testSumming
    | handle |
    handle := 2 D20 + 3 D10.
    self assert: handle diceNumber equals: 5.
\end{displaycode}

We define a \textcode{+} method on the \textcode{DiceHandle} class. In other languages this is often not possible or is based on operator overloading. In Pharo \textcode{+} is just a message as any other. Therefore we can define the \textcode{+} method on the classes we want.

What is the semantics of adding two handles? Should we modify the receiver of the expression or create a new handle? In this tutorial we choose the functional style and decide that a new handle should be created. As a result, the method \textcode{+} first creates a new handle then adds to it to the dice of the receiver and the ones of the handle passed as argument. Finally, \textcode{+} must return the newly created handle. To access the dice of the dice handle passed as a parameter, you will have to add a dedicated accessor.

\begin{displaycode}{smalltalk}
Your code here
\end{displaycode}

Now we can execute \textcode{(2 D20 + 1 D6) roll} and start playing games, of course.
\section{Conclusion}
This tutorial illustrates how to create a small DSL based on the definition of some domain classes (here \textcode{Die} and
 \textcode{DiceHandle}). We used class extension (on \textcode{Integer}) to simplify the instanciation of these classes.
This tutorial shows that in Pharo we can use standard operators to express natural models.


\ifx\wholebook\relax\else
\end{document}
\fi