Building a Domain Model in Elixir part 4

The domain model is still developing well. https://github.com/chriseyre2000/pandemic.

The technique of using one line composable functions works well. It also makes the code really readable.

I was surprised how easy it was to enable the “quiet night” card. This can be used at any time and will prevent the next infect city phase from doing anything. It was simple to add a new property to the model, set and unset it. I had expected to have had to build this into the UI (which does not exist yet).

Building a Domain Model in Elixir Part 2

I have now got a bit further with my domain model of the Pandemic game. There are very few complex examples of functional domain models. The problem is that problems that benefit from this approach are normally too complex to make a good example.

Pandemic is a complex cooperative board game. Players race to find cures for 4 diseases. There are lots of ways to lose. It’s a Euro game so it has built in termination options. You lose if:

– You can’t draw from the player deck

– On the 8th outbreak

– If you run out of any one of the 4 disease counters and are unable to place one.

The team wins if all 4 diseases have a cure.

https://github.com/chriseyre2000/pandemic

This now has a model of the cities with the links between them. The this was test driven with some useful checks. I used exhaustive property tests to check the link validity. This includes checks that all links are reversable, that no city links to itself and that there are no orphan cities. These caught a number of cut and paste errors.

The next part is a model of the board state. This includes the initial draw of cards, the infection of new cities and the cascade of an outbreak.

This follows an Elixir pattern of using functions in modules using struts. Every non-query function takes and returns the struct defined in the module. This makes composition much easier.

Experimenting With Elixir in Docker

I am working on my book Elixir Function Guide. Having noticed that there are a lot of mix tasks that I did not know about (and some that my exercism.io students don’t) then I thought that I would add some details at the start of the book.

I started using mix help to list the available functions:

mix                   # Runs the default task (current: "mix run")
mix app.start         # Starts all registered apps
mix app.tree          # Prints the application tree
mix archive           # Lists installed archives
mix archive.build     # Archives this project into a .ez file
mix archive.install   # Installs an archive locally
mix archive.uninstall # Uninstalls archives
mix clean             # Deletes generated application files
mix cmd               # Executes the given command
mix compile           # Compiles source files
mix credo             # Run code analysis (use `--help` for options)
mix credo.gen.check   # Generate a new custom check for Credo
mix credo.gen.config  # Generate a new config for Credo
mix deps              # Lists dependencies and their status
mix deps.clean        # Deletes the given dependencies' files
mix deps.compile      # Compiles dependencies
mix deps.get          # Gets all out of date dependencies
mix deps.tree         # Prints the dependency tree
mix deps.unlock       # Unlocks the given dependencies
mix deps.update       # Updates the given dependencies
mix do                # Executes the tasks separated by comma
mix escript           # Lists installed escripts
mix escript.build     # Builds an escript for the project
mix escript.install   # Installs an escript locally
mix escript.uninstall # Uninstalls escripts
mix format            # Formats the given files/patterns
mix help              # Prints help information for tasks
mix hex               # Prints Hex help information
mix hex.audit         # Shows retired Hex deps for the current project
mix hex.build         # Builds a new package version locally
mix hex.config        # Reads, updates or deletes local Hex config
mix hex.docs          # Fetches or opens documentation of a package
mix hex.info          # Prints Hex information
mix hex.organization  # Manages Hex.pm organizations
mix hex.outdated      # Shows outdated Hex deps for the current project
mix hex.owner         # Manages Hex package ownership
mix hex.publish       # Publishes a new package version
mix hex.repo          # Manages Hex repositories
mix hex.retire        # Retires a package version
mix hex.search        # Searches for package names
mix hex.user          # Manages your Hex user account
mix loadconfig        # Loads and persists the given configuration
mix local             # Lists local tasks
mix local.hex         # Installs Hex locally
mix local.phx         # Updates the Phoenix project generator locally
mix local.public_keys # Manages public keys
mix local.rebar       # Installs Rebar locally
mix new               # Creates a new Elixir project
mix phx.new           # Creates a new Phoenix v1.4.0 application
mix phx.new.ecto      # Creates a new Ecto project within an umbrella project
mix phx.new.web       # Creates a new Phoenix web project within an umbrella project
mix profile.cprof     # Profiles the given file or expression with cprof
mix profile.eprof     # Profiles the given file or expression with eprof
mix profile.fprof     # Profiles the given file or expression with fprof
mix release           # Assembles a self-contained release
mix release.init      # Generates sample files for releases
mix run               # Starts and runs the current application
mix test              # Runs a project's tests
mix xref              # Prints cross reference information
iex -S mix            # Starts IEx and runs the default task

It was only then that I realised that I have a number of mix extensions installed.

I need to start with what comes out of the box.
At this point I have three choices:

  • Uninstall the extensions (these are usefull .)
  • Manually edit out the extensions (error prone)
  • Use docker

The docker option is appealing as it will allow me to test using different versions of Elixir.

Here is the simple option that allows the use of docker:

docker run -it elixir:1.10 /bin/bash

This downloads the image and runs up the container. Note that this starts with bash, rather than the default iex.

From this mix help gives the more useful list:

mix                   # Runs the default task (current: "mix run")
mix app.start         # Starts all registered apps
mix app.tree          # Prints the application tree
mix archive           # Lists installed archives
mix archive.build     # Archives this project into a .ez file
mix archive.install   # Installs an archive locally
mix archive.uninstall # Uninstalls archives
mix clean             # Deletes generated application files
mix cmd               # Executes the given command
mix compile           # Compiles source files
mix deps              # Lists dependencies and their status
mix deps.clean        # Deletes the given dependencies' files
mix deps.compile      # Compiles dependencies
mix deps.get          # Gets all out of date dependencies
mix deps.tree         # Prints the dependency tree
mix deps.unlock       # Unlocks the given dependencies
mix deps.update       # Updates the given dependencies
mix do                # Executes the tasks separated by comma
mix escript           # Lists installed escripts
mix escript.build     # Builds an escript for the project
mix escript.install   # Installs an escript locally
mix escript.uninstall # Uninstalls escripts
mix format            # Formats the given files/patterns
mix help              # Prints help information for tasks
mix loadconfig        # Loads and persists the given configuration
mix local             # Lists local tasks
mix local.hex         # Installs Hex locally
mix local.public_keys # Manages public keys
mix local.rebar       # Installs Rebar locally
mix new               # Creates a new Elixir project
mix profile.cprof     # Profiles the given file or expression with cprof
mix profile.eprof     # Profiles the given file or expression with eprof
mix profile.fprof     # Profiles the given file or expression with fprof
mix release           # Assembles a self-contained release
mix release.init      # Generates sample files for releases
mix run               # Starts and runs the current application
mix test              # Runs a project's tests
mix xref              # Prints cross reference information
iex -S mix            # Starts IEx and runs the default task

Installing Lumen

Lumen is an alternative BEAM Implementation.
Warning that this is still at a very early stage. It promises the ability to build WebAssembly

I am not currently interested in using Rust to build it from sources, but there are now images published here

https://github.com/lumen/lumen/releases

I used the following to install the tarball (I use a mac):

sudo tar xf lumen-0.1.0-nightly-x86_64-apple-darwin.tar.gz -C /opt

This deploys the bundle to: /opt/lumen

The compiler is now available at: /opt/lumen/bin/lumen

Here are more details on lumen: https://getlumen.org/

On having a Useless Superpower

I am going to admit to having a minor superpower. I can hear high pitch sounds that most people can’t.

This is not at all useful as it results in me getting a headache in lots of shops or museums (and in one especially annoying instance a job interview). It’s typically a 50hz signal.