You are on page 1of 19

0  

Más    Siguiente blog» opblanco@gmail.com   Escritorio   Salir

Fun Code
All about having fun with Functional Programming.

FRIDAY, OCTOBER 16, 2015 ABOUT ME
M ark Bastian
My Concern with Concerns I've delved deeply into a
variety of programming
Introduction languages, including (in
In the Computer Science world we often talk about the value of Separation of Concerns rough chronological order)
(SoC). This Wikipedia article on the subject says that well­separated code is more VBA, VB6, C/C++, Java, Scala, and
modular, maintainable, and reusable. The basic idea is that we separate our code into Clojure. I have a preference for JVM
components by their roles so that those pieces can be used and developed independently languages, but most especially Clojure.
as well as assembled into a greater whole. View my complete profile

However, I am concerned with the traditional treatment of concerns. We often look at LIKE THIS BLOG? FOLLOW IT BY
concerns as a breakdown of our application into various interconnected pieces, or ENTERING YOUR EMAIL BELOW:
objects. For example, you might have a game program with a rendering system, an input
Email address... Submit
system, a physics system, and so on. A spreadsheet application might have concerns
regarding computations, persistence, and input. At a high level, and borrowing from the
Wikipedia article, you might have concerns for things like business logic, persistence, ...OR SUBSCRIBE FOR REGULAR UPDATES:
data access, and presentation.
 Posts

Two major flaws with the typical treatment of SoC as described above stand out to me:  All Comments

1.  In many of these systems the various parts require knowing about each other to the
degree that if you use one, you must also use the others. This leads to complected, BLOG ARCHIVE

interconnected systems. Rich Hickey talks all about it here. ▼  2015 (14)
2.  We have jumped past some core fundamental concerns of how we think about ▼  October (1)
computing and moved straight to high level constructs (usually objects, layers, or My Concern with Concerns
systems). This is what I want to talk about.
►  September (1)
These are the three low level concerns I am concerned about: ►  August (2)
►  July (2)
1. Representation: How do you describe the world?
►  June (2)
The first concern to consider is how you represent your world. In a traditional object
oriented approach, the simple solution is objects with their corresponding fields. Even in ►  May (2)
many functional or mostly functional languages like Scala you will use value types to ►  April (2)
represent your world. Consider the following three ways to represent a person: ►  March (2)

Java 

1 package concerns; ?
2  
3 public class Person {
4     private String name;
5     private int age;
6     private double weight;
7  
8     public Person() {
9     }
10  
11     public Person(String name, int age, double weight) {
12         this.name = name;
13         this.age = age;
14         this.weight = weight;
15     }
16  
17     public String getName() {
18         return name;
19     }
20  
21     public void setName(String name) {
22         this.name = name;
23     }
24  
25     public int getAge() {
26         return age;
27     }
28  
29     public void setAge(int age) {
30         this.age = age;
31     }
32  
33     public double getWeight() {
34         return weight;
35     }
36  
37     public void setWeight(double weight) {
38         this.weight = weight;
39     }
40 }

Scala 

1 case class Person(name : String, age : Int, weight : Double) ?

Clojure 

1 { :name "Zaphod" :age 21 :weight 160.0 } ?

Clojure is unique in that practitioners generally represents the world as simple data
structures. Other languages would have you define a class for your data (Often in a
painfully verbose way, I might add), but Clojure simply views everything as data. You can
use gen­class or defrecord, but you generally don't unless you are shooting for Java
interop or feel the need for a defined structural type.

Clojure is relatively unique in that it allows you to flexibly represent anything using a small
number of primitives and heterogeneous, nested data structures. You have a single,
uniform approach to representing anything as data, whether it be simple or extremely
complicated.

Classes, on the other hand, require a new class for any level of modification of
representation. A person with height would need to extend a base Person (e.g.
PersonWithHeight extends Person). This leads to elaborate type hierarchies and an
explosion of representations. Classes also fail disastrously when dealing with temporal
changes. Suppose you want to transition from a Caterpillar to a Butterfly or from an
Employee to a Manger (You got a promotion. Congratulations!). How do you handle
these? Do you pass roles around? Does that work in the caterpillar to butterfly case? Is
there a GoF anti­pattern for that?

This is not to say classes do not have their place. If your representation is well­known at
design time a class can be an excellent fit for your problem. For example, a 3D
mathematical vector is very well defined with fields along 3 axes. However, using classes
to represent things with a wide variety of potential fields or that transition over time can be
a disaster.

Clojure's simple approach to the concern of representation is wonderful, but we are here
to discuss the separation of concerns, so let's talk about another concern that we need to
keep separate...

2. Behavior: How do you modify or use your representation of the world?
The next concern is how you modify the representation of your world, or how you
transition from one representation to another. Tied to this is how you do things with your
objects, even if you don't modify them. In OOP this is done by class methods that operate
on themselves or objects they are familiar with. This seems natural, as most verbs tend
to operate on some noun. For example, a rename method clearly must rename
something. What is that thing? For an object, it logically is the thing rename is attached
to.

However, this complects the concerns of representation and behavior.

Consider the trivial situation of managing named objects. What if I want to rename a
person, car, dog, or file? In OOP, I need to add a method to every object (e.g. setName or
rename) that is nameable. You might argue for a common base class (e.g.
AbstractRenameable), but now everything must extend this class, and you don't want to
waste your one­shot inheritance on something so trivial. Instead, maybe you implement
IName and proxy a DefaultName. In any event, you are complected up the wazoo for
something so simple as the ability to rename an object. And you have to do this every
time, for every field on every object.

Wouldn't it be better to have some independent function that renames every structurally
similar piece of data? I can do this trivially in Clojure like this:

1 (defn rename[o name](assoc o :name name)) ?
2  
3 (pp/pprint
4   (rename
5     { :name "Zaphod Beeblebrox"
6      :age 21
7      :weight 160.0 }
8     "Ford Prefect"))
9  
10 (pp/pprint
11   (rename
12     { :type :spaceship
13      :name "Heart of Gold"
14      :color :red }
15     "Millenium Falcon"))

This produces the following output:

1 {:name "Ford Prefect", :age 21, :weight 160.0} ?
2 {:type :spaceship, :name "Millenium Falcon", :color :red}

One function that works on any structurally similar object. Compare this to putting a
rename method on every named object in existence. This is what I call a separation of
concerns.

Let's look at a slightly less trivial example. Suppose you are writing a sprite­based game
and have a variety of scene elements that you want to render. Each element must have
information for its location and the image to be drawn. Let's look at how you might render
a sprite­based image in our three languages using Java 2D:

Java
Here is what you would add to the above class:

1 public void render(Graphics2D g){ ?
2     g.drawImage(getImage(), getX(), getY(), null);
3 }

This, of course, assumes you have also added fields and methods to manage the image
and the item's location. You've now fundamentally intertwined your class with the Java 2D
library, some AWT classes for handing images, and whatever else you've done to make
this work.

Scala
Scala suffers from the same problem as Java because it still complects the concerns of
representation and behavior. In Scala's defense, it does have duck typing, structural
typing, and traits that allow you to do a variety of things to repeat yourself a lot less. It's a
better situation, but it does add complexity to your solution and you have to go to a lot of
effort to separate your behavior from your representation.
Este sitio emplea cookies de Google para prestar sus servicios,
para personalizar anuncios y para analizar el tráfico. Google recibe
Clojure 
información sobre tu uso de este sitio web. Si utilizas este sitio
Clojure completely separates the concerns of representation and behavior by using pure
web, se sobreentiende que aceptas el uso de cookies.
data structures to represent data and functions to represent behavior. The only required
MÁS INFORMACIÓN ENTENDIDO
interface is correct structural inputs to functions.

1 (defn render [g {:keys [image x y]}] ?
2   (.drawImage g image x y nil))

In this example, any data conforming to the required interface (Having entries for the
:image, :x, and :y keys) can be rendered. The data has no knowledge of Graphics2D and
is only loosely coupled to AWT by having a field entry referencing an image. This data can
be removed from the map entirely if not needed as opposed to an object which would
have a null field that still references a foreign API. 

We're now double­complected in OOP­land and have complete separation with Clojure.
Let's throw another concern into the mix...

3. Management: How do you keep track of the current state of the world?
Separate from the idea of how you represent and act in your world is how you keep track
of your current (and perhaps historical) view of the world. This includes not just a handle
to the current value of the world, but a mechanism for watching for changes and
responding accordingly.

In Java this is accomplished via a fully implemented Java Bean, with getters, setters,
property change support, property change listeners, and so on. Your bean class will have
a mechanism to wire up things that listen for changes and changes are fired when
change occurs. Again, we've further tied another concern to the object. We're now
complected x3.

Scala doesn't address this concern directly, but you've got options. You can create Java
Beans in Scala, but beans are an ugly, complicated mess that should be avoided if
possible. You can use the Akka library, but in my experience Akka is too heavyweight and
complicated for most problems.

Clojure, on the other hand, has atoms, agents, and refs. These concurrency primitives
are designed exactly for the concern of state management. These 3 items each hold a
value as their current state and have methods for performing safe modification
synchronously, asynchronously, uncoordinated, or coordinated, depending on which
primitive you need. All have the same API for dereferencing, watching for changes, and
validating state. These primitives completely separate the concern of state management
from the other concerns described in this post. You can read more about these primitives
here.

One really great thing about Clojure concurrency primitives is that they are easy to use
from any other JVM language, so you can leverage them in your Java or Scala projects to
separate this concern if desired.

Summary and Conclusions
The following table summarizes what I have discussed in this post.

Concern OOP FP

State Object Fields Values/Data

Behavior Object Methods Functions

Management Object References Concurrency Primitives

Separation Level Complected Separated

The key takeaway is that objects fundamentally complect all concerns by their very
nature. Clojure's separation of data, functions, and state management allow for a clean
separation of these concerns as part of the language design. So, rather than beginning to
design the world as objects, layers, and systems start with data, functions, and state.
The former solution automatically puts you on the road to complexity while the latter
allows you to keep your concerns separated all the way down.

Posted by Mark Bastian at 6:00 AM  No comments: 
+2   Recommend this on Google

Labels: clojure, clojurescript, functional programming, java, scala

THURSDAY, SEPTEMBER 24, 2015

Clojure State Management by Example

Introduction
One of my favorite features of Clojure is the way changes in application state are
handled. In Clojure we separate the concerns of our data (which is stored as values) and
the management of how that data might change over time. Contrast this to most other
languages that have mutable state tied to their object model at some level.

There are four state management primitives. Here's a very simple example of each and
how they behave.

Vars
Vars are what you get when you use def. def simply defines a value. If you declare the
def'd value as dynamic, you can rebind it on a per­thread basis. Meaning, within your
current scope you can rebind the value of the previously def'd value. Here's the example:

1 (def ^:dynamic *a* 0) ;Note the *earmuff* ?
2 (def ^:dynamic *b* 1) ;Clojure uses them for things mean to be rebound
3  
4 (prn (str "(original) a, b = " *a* "," *b*))
5  
6 (future
7   (binding [*a* 1 *b* 0]
8     (prn (str "(rebinding) a, b = " *a* "," *b*))
9     (binding [*a* 11 *b* 45]
10       (prn (str "(another binding) a, b = " *a* "," *b*)))
11     (prn (str "(exiting scope) a, b = " *a* "," *b*)))
12   (prn (str "(exiting scope) a, b = " *a* "," *b*)))
13  
14 (prn (str "(original ns value) a, b = " *a* "," *b*))

The above produces this output:

1 "(original) a, b = 0,1" ?
2 "(rebinding) a, b = 1,0"
3 "(original ns value) a, b = 0,1"
4 "(another binding) a, b = 11,45"
5 "(exiting scope) a, b = 1,0"
6 "(exiting scope) a, b = 0,1"

As you can see, every time I rebind a and b in a new form, the old value are replaced
within that scope. As soon as the form is exited, we are back to the previous binding.
Finally, you can see that the last prn statement that prints the original binding value is
unaffected by the future since the future is in a different thread. I don't find vars particularly
useful or interesting, but for completeness's sake, there you have it. Our next three
concurrency primitives are much more interesting.

Atoms
Atoms provide synchronous, uncoordinated state management. These are the workhorse
of Clojure state management. Here's how it works using a simple example that updates
two atoms and dumps out their results. A built­in delay is added to each update for
illustration's sake.

1 (def a (atom 0)) ?
2 (def b (atom 1))
3  
4 (defn slow [f] (Thread/sleep 300) f)
5 (defn slower [f] (Thread/sleep 400) f)
6  
7 (future
8   (do
9     (swap! a (comp slow inc))
10     (swap! b (comp slower dec))))
11  
12 (future
13   (loop [i 10]
14     (when (pos? i)
15       (do
16         (prn (str "a, b = " @a "," @b))
17         (Thread/sleep 100)
18         (recur (dec i))))))

Output:

1 "a, b = 0,1" ?
2 "a, b = 0,1"
3 "a, b = 0,1"
4 "a, b = 1,1"
5 "a, b = 1,1"
6 "a, b = 1,1"
7 "a, b = 1,1"
8 "a, b = 1,0"
9 "a, b = 1,0"
10 "a, b = 1,0"

The above output illustrates that atoms are synchronous since it took 300ms for slow to
execute on a and an additional 400ms for slower to execute on b. Also, the functions are
uncoordinated ­ There is a time when slow has completed its work and slower has not.
There is no connection between the two swap! operations.

Refs
Refs provide synchronous, coordinated state management. Use a ref when you need a
transaction to be performed correctly. For example, you could use Refs to track funds in
a bank account. To transfer funds from one Ref'd account to another, put the transaction
in a synchronized ref block. The following example is identical to the above, except that
now we are altering a and b in a synchronized code block.

1 (def a (ref 0)) ?
2 (def b (ref 1))
3  
4 (defn slow [f] (Thread/sleep 300) f)
5 (defn slower [f] (Thread/sleep 400) f)
6  
7 (future
8   (dosync
9     (alter a (comp slow inc))
10     (alter b (comp slower dec))))
11  
12 (future
13   (loop [i 10]
14     (when (pos? i)
15       (do
16         (prn (str "a, b = " @a "," @b))
17         (Thread/sleep 100)
18         (recur (dec i))))))

Output:

1 "a, b = 0,1" ?
2 "a, b = 0,1"
3 "a, b = 0,1"
4 "a, b = 0,1"
5 "a, b = 0,1"
6 "a, b = 0,1"
7 "a, b = 0,1"
8 "a, b = 1,0"
9 "a, b = 1,0"
10 "a, b = 1,0"

Unlike the previous example, no change occurred in a or b until both the slow and slower
functions were applied to a and b. Since the operations were synchronous, it took the
entire compute time of both functions to pass before both a and be were concurrently
updated.

Agents
Agents provide asynchronous, uncoordinated state management. If you want reactive
behavior, use agents. As before, we are using the same example to illustrate agent
behavior.

1 (def a (agent 0)) ?
2 (def b (agent 1))
3  
4 (defn slow [f] (Thread/sleep 300) f)
5 (defn slower [f] (Thread/sleep 400) f)
6  
7 (future
8   (do
9     (send a (comp slow inc))
10     (send b (comp slower dec))))
11  
12 (future
13   (loop [i 10]
14     (when (pos? i)
15       (do
16         (prn (str "a, b = " @a "," @b))
17         (Thread/sleep 100)
18         (recur (dec i))))))

Output:

1 "a, b = 0,1" ?
2 "a, b = 0,1"
3 "a, b = 0,1"
4 "a, b = 1,1"
5 "a, b = 1,0"
6 "a, b = 1,0"
7 "a, b = 1,0"
8 "a, b = 1,0"
9 "a, b = 1,0"
10 "a, b = 1,0"

In this case, we see that both slow and slower executed concurrently, since a was
updated after 300ms and b was updated only 100ms later.

Summary
Clojure's concurrency primitives are very easy to use and make it simple to manage
program state. However, it is important to know when to use which. Hopefully this simple
set of examples will give you a clear idea as to the behaviors of each so that you'll know
when to use them.

Posted by Mark Bastian at 7:00 AM  No comments: 
+4   Recommend this on Google

Labels: clojure, concurrency, functional programming

FRIDAY, AUGUST 21, 2015

A Clojure Snake Game

Introduction
I recently decided to write a Snake game in Clojure as a small project. In the game you
have a snake that grows as it consumes food. The goal of the game is to make the snake
as long as possible without self­intersecting. I got the idea to do it on a Saturday morning
and by that night I was done. Most of the coding was done in the evening since I was
doing family activities all day. All told, this was probably a 3 hour project. The entire
program is 75 lines of code. That's awesome! This includes both the JVM and JavaScript
targets via Clojure and ClojureScript.
Here's the game:

Here's how you play:
Use your arrow keys or w, a, s, d to change the snake's direction. Note that
you probably will need to click on the canvas first to gain focus.
When the snake hits a green "food" pill it grows one unit longer.
When the snake intersects itself it resets to its original length.
Your score is the length of your snake.
The Program
Here's the program. Read past it for my observations and comments.

1 (ns snake.core ?
2   (:require [quil.core :as q #?@(:cljs [:include‐macros true])]
3             [quil.middleware :as m]))
4  
5 (def world { :width 100 :height 100 :food‐amount 1000 })
6  
7 (defn gen‐food [] [(rand‐int (world :width)) (rand‐int (world :width))])
8  
9 (defn replenish‐food [initial amount]
10   (loop [food initial] (if (>= (count food) amount) food (recur (conj food (gen‐food))))))
11  
12 (defn wrap [i m]
13   (loop [x i] (cond (< x 0) (recur (+ x m)) (>= x m) (recur (‐ x m)) :else x)))
14  
15 (defn grow‐snake [{:keys [snake velocity] :as state}]
16   (let [[px py] (map + (peek snake) velocity)]
17     (assoc state :snake (conj snake [(wrap px (world :width)) (wrap py (world 
18  
19 (defn eat [{:keys [snake food] :as state}]
20   (if‐let [pellet (food (peek snake))]
21     (‐> state (update :food disj pellet))
22     (‐> state (update :snake subvec 1))))
23  
24 (defn reset? [{:keys [snake] :as state}]
25   (if (apply distinct? snake)
26     state
27     (assoc state :snake [(peek snake)])))
28  
29 (defn setup []
30   (do (q/smooth)
31       (q/frame‐rate 30)
32       {:snake [[50 50]] :velocity [1 0] :food (replenish‐food #{} (world :food
33  
34 (defn draw [{ :keys [snake food] }]
35   (let [w (/ (q/width) (world :width))
36         h (/ (q/height) (world :height))]
37     (do
38       (q/smooth)
39       (q/stroke‐cap :round)
40       (q/stroke‐join :round)
41       (q/background 0 0 0)
42  
43       (q/fill 0 255 0)
44       (q/stroke 0 255 0)
45       (doseq [[x y] food](q/rect (* w x) (* h y) w h))
46  
47       (q/fill 255 0 0)
48       (q/stroke 255 0 0)
49       (doseq [[x y] snake](q/rect (* w x) (* h y) w h))
50  
51       (q/fill 0 255 255)
52       (q/text (str "Score: " (count snake)) 10 15))))
53  
54 (defn launch‐sketch [{:keys[width height host]}]
55   (q/sketch
56     :title "Snake"
57     :setup setup
58     :update #(‐> % grow‐snake eat (update :food replenish‐food (world :food‐amount)) reset?)
59     :draw draw
60     :key‐pressed
61     (fn [{ :keys [velocity] :as state} { :keys [key key‐code] }]
62       (case key
63         (:a :left) (if (not= [1 0] velocity) (assoc state :velocity [‐1 0]) state)
64         (:d :right) (if (not= [‐1 0] velocity) (assoc state :velocity [1 0]) state)
65         (:w :up) (if (not= [0 1] velocity) (assoc state :velocity [0 ‐1]) state)
66         (:s :down) (if (not= [0 ‐1] velocity) (assoc state :velocity [0 1]) state)
67         state))
68     :middleware [m/fun‐mode]
69     :size [width height]
70     #?@(:cljs [:host host])))
71  
72 ;#?(:clj (launch‐sketch { :width 400 :height 400 }))
73  
74 #?(:cljs (defn ^:export launch‐app[host width height]
75            (launch‐sketch { :width width :height height :host host})))

Observations and Comments
The state in this program is represented by a simple data structure containing a vector
describing the snake, a vector representing the snake's velocity, and a set of coordinates
representing the locations of food. You can see where I create this at the end of the setup
function.There are also some constants in the world def.

To update the state, this program makes use of the common Clojure pattern of "threading
state." Basically, you write your functions so that program state is passed in as an
argument and a modified, updated version of the program state is returned. Functions
with a single action or concern are written in this manner and then chained to form more
complicated behaviors. It makes your program very easy to reason about. In this program
you can see where this is done in the update method:

1 #(‐> % grow‐snake eat (update :food replenish‐food (world :food‐amount)) res
?et?)

For those unfamiliar with Clojure, I am using the "thread first" macro (The arrow). The #
creates an anonymous function with the % as the passed in argument. The arrow takes
the argument and feeds it through each function in succession (grow­snake, then eat,
then updating food, and so on.).

At the program level, the Quil library handles passing state to each relevant function for
processing. In "fun­mode" (functional mode), Quil functions hand you the initial state for
modification in methods for program setup, update, and input. For drawing, state is
passed in and there is no function output since you will draw your state to the screen. In
other applications you can follow this same pattern of state management using Clojure's
amazing concurrency primitives (atoms, agents, and refs). In fact Quil is just using an
atom under the hood.

Other minor details:
There's a commented out form (;#?(:clj (launch­sketch { :width 400 :height
400 }))) towards the end. Uncomment this if you want to launch the file from a
REPL. I leave it commented so that it doesn't launch when I do a cljsbuild.
For some reason, the (:gen­class) directive doesn't seem to have any effect
in the cljc file, so I have a separate launcher.clj that defines a main method for
uberjar builds. Clone the project if you want to see what I mean.
You can clone the project here. 

Conclusion
Clojure continues to amaze me by repeatedly enabling me to do so much in such a small
amount to time and code. Simple ideas, such as representing your domain as data
structures vs. classes and the ability to thread your state throughout your program via
functions make development in Clojure rapid and productive. Nowadays, whenever I get
an itch to try out a new program or concept, I just sit down and model the domain as data
and then start writing functions to manipulate the data. Before I know it, I end up with a
complete program. It's a very powerful and fun way to write applications. 
Posted by Mark Bastian at 6:30 AM  No comments: 

+3   Recommend this on Google

Labels: clojure, clojurescript, functional programming

THURSDAY, AUGUST 6, 2015

Clojure is Homoiconic, Java is Not

Introduction
Recently I was reading this article regarding what is (or was) new in Java 8 and took an
interest in the following section on Lambdas:

Lambda Expressions, a new language feature, has been introduced in this
release. They enable you to treat functionality as a method argument, or
code as data. Lambda expressions let you express instances of single­
method interfaces (referred to as functional interfaces) more compactly.

I did a quick Google search on "java lambdas" and this tutorial was the first hit. Once
again, the same type of statement is made:

One issue with anonymous classes is that if the implementation of your
anonymous class is very simple, such as an interface that contains only one
method, then the syntax of anonymous classes may seem unwieldy and
unclear. In these cases, you're usually trying to pass functionality as an
argument to another method, such as what action should be taken when
someone clicks a button. Lambda expressions enable you to do this, to treat
functionality as method argument, or code as data.

The thing that struck me about these articles is the consistent statement that that Java
Lambdas (a.k.a. anonymous instances of single method interfaces) are "code as
data" because the function can be passed as an argument. I guess if you define data as
"instances of classes or functions" then this description is fine, but when I read these
articles this is what comes to mind:
Technically, the ability to assign a function to a variable or pass a function as an
argument to another function means that your functions are "first class" which is a good
thing. However, I would not call this "code as data." Another related term is "higher order
functions." These are functions that take functions as their arguments or return functions
as their results. Again, this is a very powerful language feature that Java now sort of does,
but this is not "code as data."

What do I think of when I think of "code as data?" I think of "Homoiconicity." Google
seems to agree, since when I type "code as data" into a search box the first thing that
comes up is this Wikipedia article on Homoiconicity. Let's explore the concept in more
detail.

What is Homoiconicity?
Often homoiconicity is defined one the following ways:
The code is written in the data structures of the language.
Code as data.
Those more familiar with the concept seem to use "Code as data" more, but I think the
first definition is a bit more clear if you are getting started with the idea. Either way, I am
going to illustrate the concept by showing how Clojure code is actually written as Clojure
data structures. To contrast, I'll also show what "homoiconic Java" would look like. Finally,
I'll show you a simple Clojure macro in which we rearrange our code/data.

Homoiconic Clojure
To start, consider the following core Clojure data structures:
() is an empty List.
{} is an empty Map.
[] is an empty Vector.
#{} is an empty Set.
When we write code in Clojure, it is expressed in terms of the above data structures.
Here is a very simple example that applies the str function (it's kind of like .toString) to the
number 42:

1 user=> (str 42) ?
2 "42"

You might look at this and think this is the same as the following Java code:

1 public static String str(Integer i){ ?
2     return i.toString();
3 }
4  
5 str(42);

The only difference is the location of the parenthesis, right? Wrong! (str 42) not actually
the function str with the argument of 42, but is a list containing two elements, the str
symbol and the value 42. When the Clojure evaluator sees a list it attempts to resolve the
first symbol (str in this case) and calls that function with the remaining elements of the list
as arguments. While this may seem like splitting hairs at the moment, this is very
important when you get to macros. It is also crucial to the point that Clojure code is data.

Here's another one:

1 (defn add [a b](+ a b)) ?

Again, you might think this is the same thing as this Java function:
1 public static int add(int a, int b){ ?
2     return a + b;
3 }

As before, they are not the same. The above Clojure add function is actually built up with
two lists (one nested) and a vector of arguments. The inner list contains three symbols
(+, a, and b) and the outer list contains the defn symbol, a symbol naming your function
("add"), a vector of arguments, and our inner list.

Here's another example:

1 (merge‐with + { :x 1 :y 2 :z 3 } { :x 9 :y 2 :z 4 }) ?

By this point you should see that we have a list, two maps, and a bunch of symbols and
values as opposed to a function that adds two maps. Yes, the evaluator will merge the
maps, but the code itself is data (as in the native data structures of the language).

You can do this type of structural breakdown with any Clojure code. Clojure programs are
literal data structures consisting of nested literal data structures, values, and symbols.
For more details, read this. The key takeaway is that we are indeed writing our code as a
bunch of data (literal data structures containing nested data structures, values, and
symbols).

Homoiconic Java
What if you wanted to write Java in its own data structures?

Here are our Java collection interfaces that correspond to the Clojure ones above:
java.util.List
java.util.Map
java.util.Vector
java.util.Set
Java, for some inexplicable reason, does not yet have collection literals, so this will be a
very verbose exercise. My apologies up front.

Ok, now let's write some Java code in the data structures of the language:

1 List add = new LinkedList(); ?
2 add.add("+");
3 add.add(1);
4 add.add(1);

Sadly, I have no way to evaluate this code, but, hey, it's data. I chose to use a String to
represent the + operation because Java doesn't have symbols, either.

Here's another attempt at how I might construct some code as data in Java. I realize that
this will be an utter failure, but you're just going to have to follow along as I write a ton of
code to make my point.

1 Map a = new HashMap(); ?
2 a.put("x", 1);
3 a.put("y", 2);
4 a.put("z", 3);
5  
6 Map b = new HashMap();
7 b.put("x", 9);
8 b.put("y", 2);
9 b.put("z", 4);
10      
11 List mergemaps = new LinkedList();
12 add.add("merge‐with");
13 add.add("+");
14 add.add(a);
15 add.add(b);

Again, this can't be evaluated, but it's about as close as you can get to homoiconicity in
Java.

Why Homoiconicity? ­ Macros
Consider this question: "What can you do with data?" Think about an Excel spreadsheet,
a simple comma separated value file, or some JSON data. These are things you can
easily sort, manipulate, and transform.

In the same way, Clojure code can be manipulated and transformed as data. In Clojure
there is a facility for this called a macro. When Clojure evaluates macros, it does not
evaluate the arguments as with a regular function. Rather, it passes the unevaluated
arguments into the macro to be manipulated. Once this is done, the result is returned and
evaluated.

Here's an example:

1 (defmacro bizzaro‐math ?
2   "Do everything the opposite of normal"
3   [[op & rest]]
4   (conj rest (case op
5                + ‐
6                ‐ +
7                * /
8                / *
9                op)))

This macro takes its arguments and inverts the first argument if it is a basic arithmetic
operator. Note that this would not be possible if the arguments were evaluated rather than
treated as data. Here are some examples of it in use:

1 (bizzaro‐math (+ 2 3)) ?
2 => ‐1
3 (bizzaro‐math (‐ 2 3))
4 => 5
5 (bizzaro‐math (* 2 3))
6 => 2/3
7 (bizzaro‐math (/ 2 3))
8 => 6
9 (bizzaro‐math (rem 2 3))
10 => 2

The most important thing to note here is that the inner forms (e.g. (+ 2 3)) are not
evaluated, but are manipulated by the macro, then evaluated. This is the ultimate
demonstration that we do, indeed, have code as data.

A more in­depth discussion of macros is beyond the scope of this post, but the main
takeaway is that macros allow you to manipulate code. This is a feature unique to
homoiconic languages.

Parting Thoughts
Code as data, a.k.a. homoiconicity, is the ability to write your code in the data structures
of your language. This goes way beyond the simple ability to pass a function as an
argument. If that's all you are looking for, Java might be all you need. If you want full on FP
on the JVM, you've got better options. Scala is a great bridge language that has first class
functions, higher order functions, partial evaluation, composition, and all the other things
you'd expect from a functional language. Clojure, however, is King if want it all. Not only is
it functional, it is truly homoiconic.

Further Reading:
Beating the Averages
Clojure For the Brave and True
Clojure Macros
Posted by Mark Bastian at 7:00 AM  1 comment: 

+3   Recommend this on Google

Labels: clojure, clojurescript, functional programming, java, scala

WEDNESDAY, JULY 22, 2015

Three Reasons You May Not Want to Learn Clojure

Introduction
I've been coding in Clojure for over a year now and not everything is unicorns and
rainbows. Whatever language you choose will affect how you think and work and Clojure
is no different. Read on to see what some of these effects are and why you might want to
reconsider learning Clojure.

1. You will write at least 10X less code than your Java counterparts
Often, the measure of a library or project is its size. Programmers like to compare the
size of their projects, just like muscle car people like to compare the size of their engines.
Here are some situations where this might happen:
Lunch with buddies
Job interview
Internal performance evaluation
Here's a typical conversation:

You: "Yeah, I just finished delivering the Awesome 2000."
Them: "Oh, yeah? Tell me about it."
You: "Well, it is this software product that simultaneously creates world peace, solves
world hunger, and saves the environment. Zero carbon footprint, too."
Them: "Cool, how many lines of code was that?"
You: "Oh, like 2 million."
Them: "Wow, awesome."

You will now get a high five, a job offer, or a big raise depending on who you are talking
with. However, if you stated that the number of lines of code in your product was 200 then
the response might be more along the lines of "Oh, a toy program written in a toy
language." For some reason, probably because it is easy, many people like to equate
lines of code with programming ability rather than some other metric like, oh, I don't know,
the actual features of the programs you've developed. Clojure, sadly, excels at
implementing features but is very poor at being verbose about it.

If you want to demonstrate your ability to code by writing lots of it, Clojure is a terrible,
horrible, no­good language. I can't think of another language that is worse in this respect.
You will never be able to brag again, in an circumstance, about how big your code base is
compared to someone else's.

2. You won't be marketable for certain jobs
True Story: Once upon a time I was at a job interview and the interview panel asked me to
go up to the board and code up a Fibonacci sequence generator. I asked what language
they wanted it in and they said they didn't care, but they were a C++ shop. Since they
didn't care, I wrote a very short tail­recursive Scala version which I am sure they found
incomprehensible. I used to program in C++ and at one time I think I was quite good at it.
However, I am just not that interested in C++ any more. It was a great job interview
because I didn't get the job. I am sure that the story would have ended the same had I
done the exercise in Clojure, except for the parenthesis would have been in the right
place.

If you want to be a professional Clojure programmer, there will be a smaller number of job
openings for someone of your skills and interests than for the standard Java or C#
developer. If you are interested in being part of a clone army doing widely­available boring
work, Clojure is not for you.

3. You will get things done faster
Clojure makes you productive, really productive. So, if you can get a product to market 3­
10 times faster than you once could, what does your employer do with all that extra time
you just bought them? Fire you and pocket the savings, that's what! Just kidding. Mostly.
While it is true that a company might take advantage of their newfound savings in cost
and time by eliminating the software team that just bought them the savings, the more
likely scenario is that 1) they will reapply you to something else; or 2) if they are trimming
fat, you aren't part of it. Often you will become the new go­to person for getting things
done because you've demonstrated an ability to get things done. This does lead to
problem 3a: You have too much work to do because you are a productivity magnet.

While you can't predict what your employer will do in a given situation, one constant you
can be sure of in the current software job market is that you must be agile. If you
demonstrate value you can be sure that will have the opportunity to continue to
demonstrate value. If, on the other hand, you resist change you will eventually be phased
out by your own employer or by another company that displaces yours entirely.

Conclusion
Yes, Clojure is an enabling and empowering language, but this is not without its down
sides. I didn't even get into some of the other issues, like not having the opportunity to
rewrite your Java code in JavaScript because Clojure compiles both ways. If these are
the kinds of problems you like to deal with, you just might want to give Clojure a try.

Shameless Plug
Like this blog? Please share, subscribe, or follow it (just enter your email at the top right).
Posted by Mark Bastian at 9:02 AM  No comments: 

+2   Recommend this on Google

Labels: clojure, clojurescript, functional programming, scala

TUESDAY, JULY 14, 2015

Quil, Clojure, and WORA

Introduction
Since my last post, I've been playing with the excellent Quil library, a
"Clojure/ClojureScript library for creating interactive drawings and animations." Prior to
this, I was writing demonstrations using the following scheme:

1.  Develop all logic using cljc files (cljx before Clojure 1.7). In general, application logic
is pretty platform­independent and can be wholly or nearly­wholly written in
whatever language you are working in (Clojure in our case). Any slight variances
(e.g. having to create a java.util.Date or a JavaScript Date) can easily be handled
by Clojure's new Reader Conditionals.
2.  Decide on a UI technology (likely Java Swing with Java2D or HTML Canvas
depending on what type of demo I wanted) and implement a front end using that
particular choice.
3.  Optionally implement the "other" solution from #2 so that I now have a Java and
JavaScript solution.

This strategy works pretty well, but I still have duplication of effort when it comes to the
user experience. The awesome thing about Quil is that it allows you to launch your UI as
either a Clojure or ClojureScript application targeting the JVM or JavaScript­enabled
browser, respectively. Now, I can pretty much write everything as cljc files with a few
reader conditionals and easily produce targets that run on the JVM or in a browser.

To get my feet wet with Quil, I re­implemented the renderer for my Lunar Lander project in
Quil. I was so happy with the results that I removed the Canvas/ClojureScript renderer
completely and now just use a single renderer for both the JVM and JS versions of the
project.

Results
By the time I was done with my new rendering code and refactoring of everything else, all
of the cljs files were gone. I now have a single clj file that is nothing more than a (:gen­
class) macro and a main function calling the application entry point in the cljc code.
Everything else is written as cljc files. Only a small number of reader conditionals were
used to make any Clojure or ClojureScript specific changes as required. Rather than go
over every example of how I used reader conditionals, take a look at this file that
demonstrates how to create a single Quil "Sketch" that works with both host platforms.
Aside from the above linked file, the only other conditionals required were a couple
java.util.Date vs. JavaScript Date conditionals used in the simulation namespace. The
vast majority of the code was identical for all hosts.

Conclusion
I've been developing code for the JVM for over 10 years and have always liked the "Write
once, run anywhere" (WORA) aspect of JVM languages, and have found that WORA
works for the most part. However, you can't always rely on your host machine having a
modern JVM, especially in the era of mobile devices. The browser is really the most
ubiquitous host platform, and the ability to write a single application that can be compiled
to run as a JVM app or a JavaScript app with very little effort is a huge advantage for
Clojure and Clojurists.

Afterthoughts
The complete application described in this blog can be found here. Note that you will need
to build and install my numerics project as well. Once numerics is installed, cd over to
lander and type lein run for the Clojure version of the game. You can play the web version
right here (Note that you will need a keyboard or some way to emulate the 'f' key and left
and right arrow keys.).

Posted by Mark Bastian at 6:00 AM  No comments: 

Recommend this on Google

Labels: clojure, clojurescript, functional programming, quil

WEDNESDAY, JUNE 24, 2015

A Lunar Lander Game in Clojure

Introduction
In a prior post, I spent a great deal of time talking about Predator­Prey systems, ordinary
differential equations, and solving these equations in Clojure. In this post, I describe a
recent project I did that uses the same ODE solver to do something much more fun ­
implement a physics­based lunar lander game.

Here are the rules and operations for the game:
To win, you must land the lander on the terrain with a rotation of 0 and an
absolute vertical velocity less than 10 m/s.
To engage the lander's thruster, press the 'f' key or space bar.
To turn the lander, press the left and right arrow keys.
If you go off the edge of the screen, land too fast, or land at an angle, you lose.
Press enter to start/restart the game.
The simplest solution is to just press the space bar when you get pretty close to the
ground and carefully tap it so that you land very slowly. To give yourself a little challenge,
turn the lander and give yourself some horizontal thrust. Then try to land it. I may later
enhance the game with landing zones so you can't just land anywhere, but for now you
can land anywhere you want.

Without further ado, here's the game:

If you are reading this blog via an aggregator that doesn't pick up the .js content, this is
what the game looks like:

Implementation/Clojure Details
Now that you've had some fun trying the game out, here are a few high points. I won't go
into a lot of detail in most of these sections since each could be a post in and of itself, but
I will spend a good amount of time on multimethods, which were a big win in this
application. If you want to build it, the entire project is available at
https://github.com/markbastian/lander. Note that you will need to clone my numerics
library for the Runge­Kutta solver and lein install it.

Platform Compatibility
Clojure 1.7 (Currently RC2) has the new cljc extension, which makes cross­compiling
Clojure and ClojureScript a breeze. It is much easier and faster than the old cljx solution. I
didn't make a JVM­based solution in parallel this time, but it would be pretty easy.

Game Physics
This was one of the easiest parts of the game since I just modeled the lander using
differential equations and stepped forward using a Runge­Kutta integrator at each
simulation step. The differential equations are:
dp
= v
dt
dv
= −9.81 + thrust
dt
Thrust is only applied when the user turns it on and the actual solution breaks the position
(p) and velocity (v) vectors up into their x and y components.

And here's the code:

1 (defmethod sim :live [state‐ref] ?
2   (let [{:keys [theta thrust time state]} @state‐ref
3         t (.getTime (js/Date.))
4         dt (* (‐ t time) 1E‐3)
5         dvx #(‐> theta (* Math/PI) (/ ‐180) Math/sin (* thrust))
6         dvy #(+ ‐9.81 (‐> theta (* Math/PI) (/ ‐180) Math/cos (* thrust)))
7         new‐states (rk/rk‐step [#(% 3) #(% 4) dvx dvy] state dt tableaus/classic‐fourth‐order)
8     (swap! state‐ref into { :state new‐states :time t })))

Terrain
Terrain is generated using the midpoint displacement method (source). Read about it
here. Every new game procedurally generates a new terrain profile. There's a good
chance I'll do a full on 3D terrain generation algorithm for a future blog post.

State
State is held in a single atom. As usual, when writing Clojure apps, I just modeled my
problem as a data structure held by a Clojure concurrency primitive and everything else
fell into place. The values tracked were game state (discussed later in the multimethods
section), physical simulation state, time, theta (the lander's rotation), thrust (toggled on
and off by user input), and terrain. All of this was easily managed in a single atom. One of
the most beautiful things about Clojure is the simplicity of modeling your domain. When
you stop thinking in objects and start thinking in terms of data and functions on data, life
becomes much simpler.

Project Size
The project is ~200 LOC. Not too shabby for a complete game. There are certainly areas
where I could have further reduced the amount of code, such as in the rendering section,
but there comes a point where everything works fine and there's no need to mess with it
further. Although I don't believe in brevity for brevity's sake, I do believe less code is easier
to maintain and navigate than more code, so I always appreciate a concise solution.

Multimethods ­ The Big Win
In a computer game, you will have different stages of play, or game states (not to be
confused with the physics state being maintained in the sim loop). For example, when
you start a game there is a setup stage. Once everyone has joined there is a main game
phase in which most play occurs. Finally, when someone wins there is usually some sort
of congratulatory display or an option to play again. Each stage or game state entails a
different set of rules regarding what input is received, what is rendered, and so on.
However, each state has common functions such as receiving input and rendering. This
is where Clojure multimethods come into play ­ they allow you to call the same overall
game logic, but dispatch different functions based on some custom function.

In this game, the game is in one of four states:

1.  :before ­ The state of being before any game has been played.
2.  :live ­ A game is currently being played.
3.  :win ­ A game has been played and you won.
4.  :lose ­ A game has been played and you lost.

Depending on the state of the lander game, different logic is executed for the input,
rendering, and simulation functions. For example, in :before, :win, and :lose state the
game only allows you to start/restart a game, where in :live state the game accepts input
to control the lander. In :live state the game renders the lander, terrain, and stats. In
:before state the game only renders its directions.

The cool thing about all of this is that in Clojure I only have one main game loop (shown
below). It repeatedly calls game­state, state, and render. At the same time, input is taken
via the handle­keydown and handle­keyup methods. What happens when these methods
are invoked depends on the current game state, with the right logic being dispatched via
multimethods.
?
1 (defn ^:export init[canvas]
2   (set!
3     (.‐onload js/window)
4     (let [state (atom { :game‐state :before })]
5       (do
6         (js/setInterval #(do
7                           (gs/game‐state state)
8                           (sim/sim state)
9                           (render/render state canvas)) 1)
10         (set! (.‐onkeydown js/document) (fn [e] (in/handle‐keydown state e)))
11         (set! (.‐onkeyup js/document) (fn [e] (in/handle‐keyup state e)))))))

Here is how it is done. I have 5 methods that I am invoking polymorphically based on the
current game state (Note that they are shown together here, but are in separate files in
the project):

1 ;Watch the actual game state and transition to a new state based?
 on the current physical state.
2 (defmulti game‐state (fn [state] (@state :game‐state)))
3  
4 ;Simulate the physics of the game based on the game state.
5 (defmulti sim (fn [state] (@state :game‐state)))
6  
7 ;Draw to the screen based on the game state.
8 (defmulti render (fn [state _] (@state :game‐state)))
9  
10 ;Handle input based on the game state.
11 (defmulti handle‐keydown (fn [state _] (@state :game‐state)))
12 (defmulti handle‐keyup (fn [state _] (@state :game‐state)))

The actual function dispatched when a defmulti is called depends on the dispatch
function. In this case the dispatch function is (fn [state] (@state :game­state)). Now that
I've defined the multimethods and their dispatch functions, I need to create methods that
dispatch based on the right game state. Here's how it works for the render multimethod:

1 (defmulti render (fn [state _] (@state :game‐state))) ?
2  
3 (defmethod render :before [_ canvas] (intro‐screen canvas))
4  
5 (defmethod render :win [state canvas]
6   (do
7     (draw canvas @state)
8     (win‐screen canvas)))
9  
10 (defmethod render :lose [state canvas]
11   (do
12     (draw canvas @state)
13     (lose‐screen canvas)))
14  
15 (defmethod render :live [state canvas] (draw canvas @state))

So, given the state of the game, different render methods are called based on the state of
the game. The same is true for all of the other multimethods defined above. For example,
the :live method for the sim multi method was shown earlier. When the game is not in a
live state, it simply calls the method show below, which conveniently makes the lander
stop wherever it was when the game ended.

1 (defmethod sim :default [state‐ref] ()) ?

I won't go through all of the methods I defined, but you should get the idea from what I've
posted. Multimethods provide a very effective and powerful way to dynamically dispatch
different behaviors based on a custom defined function.

Finally, I could have defined my multimethods in one common namespace and provided
implementations in another. Had I chose to provide both HTML Canvas and
Swing/Graphics2D versions of this application, I could have implemented a single game
loop that performs all logic in terms of multimethods and defined implementations in
separate namespaces. Depending on which version of the application I wanted to run I
would require the corresponding namespaces.

Conclusion
In this post, I presented a lunar lander game written in Clojure along with some
observations about the code. As with my other Clojure projects, I am impressed by how I
can make a non­trivial application with such a small amount of code. Various aspects of
Clojure contributed to this, but the thing that most impressed me with this particular
application was the use of multimethods to easily transition between game states and
manage which functions should be dispatched under what conditions.
Posted by Mark Bastian at 7:00 AM  No comments: 

+2   Recommend this on Google

Labels: clojure, clojurescript

Home Older Posts

Subscribe to: Posts (Atom)

Picture Window template. Powered by Blogger.

You might also like