% -*- 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 chapter we will develop a simple domain specific language (DSL) for rolling dice. Players of games such as Dungeon and Dragons are familiar with the DSL we will implement. An example of such DSL is \textcode{2 D20 + 1 D6} which means that we should roll two 20-faces dice and one 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, define a package named \textcode{Dice} or any name your like.
\subsection{Defining the class Die}
\begin{displaycode}{smalltalk}
Object subclass: #Die
	instanceVariableNames: 'faces'
	classVariableNames: ''
	package: 'Dice'
\end{displaycode}

In the \textcode{initialization} protocol, define the method \textcode{initialize} as follows. It simply sets the default number of faces to 6. 

\begin{displaycode}{smalltalk}
Die >> initialize 
	super initialize.
	faces := 6
\end{displaycode}

Do not hesitate to add a class comment. 
\subsection{Creating a test }
It is always empowering to verify that the code we write is always working as we defining it. For 
this purpose we will create a unit test. Remember unit testing was promoted by K. Beck first in Smalltalk the ancestor of Pharo. Nowadays this is a common practice but this is always useful to remember our roots!

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}

\begin{displaycode}{smalltalk}
DieTest >> testInitializeIsOk
    self shouldnt: [ Die new ] raise: Error
\end{displaycode}
\section{Rolling a die}
To roll a die we will use the method from Number \textcode{atRandom} which draws randomly a 
number between one and the receiver. For example \textcode{10 atRandom} draws number between 1 to 10. 
Therefore we define the method \textcode{roll} as follows.

\begin{displaycode}{smalltalk}
Die >> roll
    ^ faces atRandom
\end{displaycode}

Now we can create an instance \textcode{Die new} and send it the message  \textcode{roll} and get a result.
Do \textcode{Die new inspect} and then type in the bottom pane \textcode{self roll}.
You should get an inspector like the one shown in Figure \ref{figDiceNoDetail}. With it you can interact with a die by writing expression in the bottom pane.


\begin{figure}

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


 
\subsection{Creating another test}
We will define a test that verifies that rolling a new created dice with a default 6 faces only returns 
value comprised between 1 and 6. This is what the following test method is actually specifying.
 

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

Note that often it is better to define the test even before the code it tests. Why? Because you can think about the API of your objects and a scenario that illustrate their correct behavior. It helps you to program your solution.
\section{Instance creation interface}
We would like to get a simpler way to create Dice. For example we want to create a 20-faces die as follows: \textcode{Dice faces: 20}. Let us define a test for it.

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

We define the class method \textcode{faces:} as follows. It creates an instance then send the message \textcode{faces:} to it and returns the instance.

\begin{displaycode}{smalltalk}
Die class >> faces: aNumber

	| instance |
	instance := self new.
	instance faces: aNumber.
	^ instance
\end{displaycode}

This method is strictly equivalent to the one below. The trick is that \textcode{yourself} is a simple method defined on \textcode{Object} class. \textcode{yourself} returns the receiver of a message and the use of \textcode{;} sends the message to the receiver of the previous message (here \textcode{faces:}), therefore \textcode{yourself} is sent to the object resulting from the execution of the expression \textcode{self new} (which returns a new instance of the class \textcode{Dice}). 

\begin{displaycode}{smalltalk}
Die class >> faces: aNumber
	
	^ self new faces: aNumber; yourself
\end{displaycode}

If you execute it will not work since we did not create yet the method \textcode{faces:} this is now the time to define it.

\begin{displaycode}{smalltalk}
Die >> faces: aNumber

	faces := aNumber
\end{displaycode}

Now your tests should run. 

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}

Of course we will 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}
\subsection{Testing a Dice Handle}
We define a new test method as follows. 

\begin{displaycode}{smalltalk}
DiceHandleTest >> testCreationAdding

	| handle |
	handle := DiceHandle new 
			addDie: (Die faces: 6);
			addDie: (Die faces: 10);
			yourself.
	self assert: handle diceNumber = 2.
\end{displaycode}

In fact we can do it better and add a new test method that verifies that we can even add
two dice having the same number of faces. 

\begin{displaycode}{smalltalk}
DiceHandleTest >> testAddingTwiceTheSameDice

	| handle |
	handle := DiceHandle new. 
	handle addDie: (Die faces: 6).
	self assert: handle diceNumber = 1.
	handle addDie: (Die faces: 6).
	self assert: handle diceNumber = 2.
\end{displaycode}
\subsection{Defining the DiceHandle class}
This class defines one instance variable to hold dice it contains. 

\begin{displaycode}{smalltalk}
Object subclass: #DiceHandle
	instanceVariableNames: 'dice'
	classVariableNames: ''
	package: 'Dice'
\end{displaycode}

We simply initialize it so that its instance variable \textcode{dice} contains an \textcode{OrderedCollection}.

\begin{displaycode}{smalltalk}
DiceHandle >> initialize
	super initialize.
	dice := OrderedCollection new.
\end{displaycode}

Then we define a simple method to add a die to the list of dice of the handle.

\begin{displaycode}{smalltalk}
DiceHandle >> addDie: aDie 
	dice add: aDie
\end{displaycode}

Now you can execute the code snippet and inspect it. You should get an inspector as shown in Figure \ref{diceHandleNoDetail} 

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


\begin{figure}

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


Finally we should add the method \textcode{diceNumber} to the \textcode{DiceHandle} class to be able to get the number of dice of the handle. We just return the size of the dice collection.

\begin{displaycode}{smalltalk}
DiceHandle >> diceNumber  

	^ dice size
\end{displaycode}

Now your tests should run and this is good moment to save and publish your code. 
\section{Improving programmer experience}
Now when you open an inspector you cannot see well the dice that compose the dice handle. Click on the \textcode{dice} instance variable and you will only get a list of \textcode{a Dice} without further information. 

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

So we will enhance the \textcode{printOn:} method of the \textcode{Die} class to provide more information. Here we simply add the number of faces surrounded by parenthesis.

\begin{displaycode}{smalltalk}
Die >> printOn: aStream

	super printOn: aStream.
	aStream nextPutAll: ' (', faces printString, ')'
\end{displaycode}

Now in your inspector you can see effectively the number of faces a dice handle 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.6\textwidth]{figures/DiceDetail.png}\caption{Die details\label{diceDetail}}\end{center}
\end{figure}
 


\begin{figure}

\begin{center}
\includegraphics[width=1.0\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 handle of dice by simply summing the dice rolls.

\begin{displaycode}{smalltalk}
DiceHandle >> roll
	
	| res |
	res := 0.
	dice do: [ :each | res := res + each roll ].
	^ res
\end{displaycode}

Now we can 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}
Now 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 will define class extensions: we will define methods in the class \textcode{Integer} but these methods will be only available when the package Dice will be loaded. 

But 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 = 2.
\end{displaycode}

Verify that the test is not working! It is much more satisfactory to get a test running when it was not working before. Now define the method \textcode{D20} with a category name that is '*Dice' (if you named your package Dice). This method simply creates a new dice handle, add the correct number of dice to this handle and return it.

\begin{displaycode}{smalltalk}
Integer >> D20
	
	| handle |
	handle := DiceHandle new.
	self timesRepeat: [ handle addDie:  (Die faces: 20)].
	^ handle
\end{displaycode}

Now you test should pass and this is probably a good moment to save your work either by publishing your package to SmalltalkHub and to save your image. 

Now we could do the same for the default dice with different faces number: 4, 6, 10, and 20.
But we should avoid duplicating logic and code. So first we will introduce a new method \textcode{D:} and based on it we will define all the others

\begin{displaycode}{smalltalk}
Integer >> D: anInteger
	
	| handle |
	handle := DiceHandle new.
	self timesRepeat: [ handle addDie:  (Die faces: anInteger)].
	^ handle
\end{displaycode}

\begin{displaycode}{smalltalk}
Integer >> D4
	
	^ self D: 4
\end{displaycode}

\begin{displaycode}{smalltalk}
Integer >> D6
	
	^ self D: 6
\end{displaycode}

\begin{displaycode}{smalltalk}
Integer >> D10
	
	^ self D: 10
\end{displaycode}

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

We have now a compact form to create dice and we are ready for the last part: the addition of handles. 
\subsection{Handle's addition}
Now we can simply support the addition of handles. But of course let's write a test first.

\begin{displaycode}{smalltalk}
DiceHandleTest >> testSumming

	| handle |
	handle := 2 D20 + 3 D10.
	self assert: handle diceNumber = 5.
\end{displaycode}

We will define a method \textcode{+} on the HandleDice 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 it on the classes we want.

Now we should ask ourself what is the semantics of adding two handles. Should we modify the receiver of the expression or create a new one. We preferred a more functional style and choose to create a third one. 

The method \textcode{+} creates a new handle then add to it the dice of the receiver and the one of the handle passed as argument to the message. Finally we return it. 

\begin{displaycode}{smalltalk}
DiceHandle >> + aDiceHandle

	| handle |
	handle := self class new.
	self dice do: [ :each | handle addDie: each ].
	aDiceHandle dice do: [ :each | handle addDie: each ].
	^ handle
\end{displaycode}

Now we can execute the method \textcode{(2 D20 + 1 D6) roll} nicely and start playing role playing games, of course.
\section{Conclusion}
This chapter illustrates how to create a small DSL based on the definition of some domain classes (here \textcode{Dice} and  
 \textcode{DiceHandle}) and the extension of core class such \textcode{Integer}.
It shows that in Pharo we can use usual operators to express natural models.


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