## Stateful Commands for the Mars Rover

Following up on the chapter "A mini DSL", I would like to include two new features in our DSL today:

• command expressions like `move rover 20 meters forward` that read like plain english and

• a sequence of such commands for the same rover

### Step 1: Command Expressions

Command expressions make code read like plain english, which is helpful (or just cool) in many DSLs. They require that we get rid of all punctuation and this can be really difficult in many languages. Luckily, it is a piece of cake in Frege. Let’s find out how we could implement the following example:

A single command expression
``move rover 20 meters forward``

Now, this is just a simple `move` function with four arguments! Done.

Well, almost done. We need to find out what type `rover` should be and what the other arguments are. Here is a proposal: just make `rover` a Position with some nice record syntax and use Double for all remaining arguments. The return value is the new position.

Making the command expression work
``````data Position = Pos { x, y :: Double }
derive Show Position

rover   = Pos 0 0
meters  = 1.0
forward = 1.0

move :: Position -> Double -> Double -> Double -> Position
move position distance unit direction =
position.{x <- (+ distance * unit * direction) }  -- ➊``````

This should all be familiar, where at ➊ we modify the x position in a fashion that we already encountered in "The Power of the Dot".

Homework I

The energetic reader may want to improve the solution by re-using the type-safe units of length that we defined in "Enhancing the DSL for Type Safety".

Ok, this works nicely, but as soon as we try to do multiple moves in sequence, the code becomes rather unwieldy. We would have to pass the updated position around such that the result of the last move becomes an argument to the next move.

``````pos1 = move rover ...
pos2 = move pos1  ...``````

It would all be so much easier if we could just modify the position…​

### Step 2: Introducing State

Luckily, there is a State type in Frege and it perfectly fits our needs.

• We can use a `State Position` type, meaning "state for a Position type".

• `State` has a `modify` operation that takes a high-order function, which knows how to update a position. Ha, this will be our new `move`!

• `State` also has an `execState` that runs our stateful computations (doing the moves) starting from an initial position. Perfect.

"bind" again

Running stateful computations technically means that we provide many move functions. These functions must be called in strict sequence and `execState` must bind the result position from one move function to the next.

When there is "bind" (in the form of the `>>=` operator) then we can also use the do-nation and we will do so in the final solution. Here it is.

Moving the rover by command expressions
``````module CommandExpressionRover where

data Position = Pos { x, y :: Double }
derive Show Position

rover   = Pos 0 0
feet    = 0.305
meters  = 1.0
forward = 1.0
back    = -1.0

move ∷ Double -> Double -> Double -> State Position ()  -- ➊
move distance unit direction = State.modify update where
update pos = pos.{x <- (+ distance * unit * direction) }

with start f = State.execState f start   -- ➋

main = do
endPosition = with rover do
move 20 meters forward           -- ➌
move 10 feet back
println \$ "moved the rover around, ending at " ++ show endPosition``````

This code prints

`moved the rover around, ending at Pos 16.95 0.0`

A few remarks about the code where it is not entirely obvious:

At ➊ we see in the type signature `State Position ()`. Why the "()" unit? Well, in full generality, `State` has not only one type parameter but two: `State s a`, where `s` is the type of the managed state - in our case `Position` - and `a` is the type that stateful computations can evaluate to. We make no use of `a` in our solution since we are only interested in the state change. If you ever use `runState` or `evalState` you will see the differences.

➋ introduced the small convenience function `with` to flip the parameter positions of `execState` just because that makes the do-notation easier to use. I think it also reads nicer. There is a `flip` function to do this in-place but I found it distracting.

At ➌ we see that `rover` has gone! It is now in the state. This is even more compelling as a DSL! And this works 100% typesafe without implicit delegates (this is for the language geeks).

Homework II

Add functions to change the direction of the next move, e.g. `turn 90 degrees`. For the geeks: check out FregeFX and paint the moves on a canvas.

### Stateless State

Many people claim that using state in a purely functional language is hard - and I concede that it takes a bit more consideration than just writing `position.x += distance * unit * direction`. However, the code above is reasonably legible.

On the other hand: isn’t state undermining our purity goals? Have we silently converted to the dark side? No!

Staying pure

Even though the code above looks like it would operate on mutable state, that really isn’t the case. `State` transfers immutable values from one function to the next but never ever mutates any state! Using `State` is still purely functional.

You may also have recognized that we got the plain `endPosition` without the `State` context as a result value. This is only possible because `State` is pure.

### References

 Haskell Wikibook https://en.wikibooks.org/wiki/Haskell/Understanding_monads/State Frege Language Reference http://www.frege-lang.org/doc/Language.pdf , section 3.2 "Primary Expression" Groovy Mars Rover DSL http://www.infoq.com/presentations/groovy-dsl-mars