Skip to content

Instantly share code, notes, and snippets.

@schmalz
Last active September 6, 2017 09:47
Show Gist options
  • Save schmalz/2cc2843f6255417b28ab3de32a9b8e9e to your computer and use it in GitHub Desktop.
Save schmalz/2cc2843f6255417b28ab3de32a9b8e9e to your computer and use it in GitHub Desktop.
Designing for Scalability with Erlang/OTP - Ch 6 - Coffee FSM - Pure LFE
(defmodule coffee
(export
(tea 0)
(espresso 0)
(americano 0)
(cappuccino 0)
(pay 1)
(cup-removed 0)
(cancel 0)
(start_link 0)
(init 0)))
(defun start_link ()
(tuple 'ok (spawn_link (MODULE) 'init '())))
(defun init ()
(register (MODULE) (self))
(hw:reboot)
(hw:display "make your selection" '())
(selection))
(defun tea ()
(! (MODULE) (tuple 'selection 'tea 100)))
(defun espresso ()
(! (MODULE) (tuple 'selection 'espresso 150)))
(defun americano ()
(! (MODULE) (tuple 'selection 'americano 100)))
(defun cappuccino ()
(! (MODULE) (tuple 'selection 'cappuccino 150)))
(defun cup-removed ()
(! (MODULE) 'cup-removed))
(defun pay (coin)
(! (MODULE) (tuple 'pay coin)))
(defun cancel ()
(! (MODULE) 'cancel))
(defun selection ()
(receive
(`#(selection ,type ,price)
(hw:display "please pay ~w" `(,price))
(payment type price 0))
(`#(pay ,coin)
(hw:return-change coin)
(selection))
(_other
(selection))))
(defun payment (type price paid)
(receive
(`#(pay ,coin)
(let ((paid (+ paid coin)))
(cond
((>= paid price)
(dispense type price paid)
(remove))
('true
(hw:display "please pay ~w" `(,(- price paid)))
(payment type price paid)))))
('cancel
(hw:display "make your selection" '())
(hw:return-change paid)
(selection))
(_other
(payment type price paid))))
(defun remove ()
(receive
('cup-removed
(hw:display "make your selection" '())
(selection))
(`#(pay ,coin)
(hw:return-change coin)
(remove))
(_other
(remove))))
(defun dispense (brew price paid)
(hw:display "preparing drink" '())
(hw:return-change (- paid price))
(hw:drop-cup)
(hw:prepare brew)
(hw:display "remove drink" '()))
(defmodule hw
(export all))
(defun display (str args)
(io:format (++ "display:" str "~n") args))
(defun return-change (change)
(io:format "machine:returned ~w in change~n" (list change)))
(defun drop-cup ()
(io:format "machine:dropped cup~n"))
(defun prepare (brew)
(io:format "machine:prepare ~p~n" (list brew)))
(defun reboot ()
(io:format "machine:reboot hardware~n"))
@schmalz
Copy link
Author

schmalz commented Sep 6, 2017

I am working through "Designing for Scalability with Erlang/OTP", translating to LFE as I go.
This is my first attempt at the pure LFE version of the Coffee FSM from Chapter 6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment