Sunday, June 28, 2015

Leap Year kata OR How TDD Does Not Mean No Forethought

"Hence! home, you idle creatures, get you home:
Is this a holiday? What, know you not,
Being mechanical, you ought not walk

Upon a labouring day without the sign
Of your profession? Speak, what trade art thou?
"
-- Shakespeare, Julius Caesar
Act I, Scene I, Lines 1-5

The Leap Year kata is interesting.  The real trick to the kata is not the leap year algorithm.  No, it is picking the test cases in such a way as to not cause you to have to write the whole thing at once.

Let us look at an implementation in Clojure.



We see that the key to picking test cases is to have an idea of the order in which you plan on writing your code.  How so?  In the first test case we pick leap years divisible by 400, then we pick non-leap years divisible by 100, then leap years divisible by 4, and then years which are not leap years.

Does setting up your test case with the algorithm in mind violate TDD?  I say no.  In fact I think Uncle Bob would say no.



TDD does not mean no architecture.  TDD does not mean no forethought.  No, TDD means no production code is written without a test and that only as much production code is written as what is needed to pass the current failing test.

In other words, TDD would want you to think about the leap year algorithm a head of time and pick test cases which will move along the algorithm.

Sunday, June 14, 2015

Combining Maps in JavaScript and Clojure

"Thy knotted and combined locks to part,
And each particular hair to stand an end
Like quills upon the fretful porpentine.
"-- Shakespeare, Hamlet
Act I, Scene V, Lines 18-20

Intro


Sometimes in life you want to combine different things together to make something that is even better than the things by themselves.

"Within the same school, the idea was that
We'd later combine both styles, unify the techniques
But still, we were too young
Too full of ignorant pride in our own succulent sorrow
"
-- Rancid, Crane Fist


JavaScript


In Lodash we can use the Merge and Assign functions to combine Map Data Structures.



In the code above we see the big difference, based on the examples given, between Merge and Assign is around combining the internal Map Data Structures.  We see that the result from Merge will combine them together whereas Assign will just overwrite them.

Clojure


Clojure also has a Merge function.



In the code above we see that merge in Clojure works like Assign in Lodash but we can use merge-wtih along with conj to get the similar results to Merge in Lodash.

Fin


"As all things come to an end, even this story."
-- J. R. R. Tolkien, The Hobbit

Sunday, June 7, 2015

One Data Structure to Rule Them All

"Mark Antony, shall we give sign of battle?"
-- Shakespeare, Julius Caesar
Act V, Scene I, Line 23

Intro


For decades the battle cry of the LISP family of languages has been:

"It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures."
-- Alan J. Perlis
Epigrams on Programming, #9

What is this one data structure to rule them all?  The list?  Well yes and no.  In practice I would say, at least in Clojure, it would be the Map data structure (not to be confused with the Higher Order Function called Map).

Say we have the following data structure:


We can say that a Hobbit is made up of a mappings of name, age, family, and past time to values.

JavaScript


With ECMAScript 6 using Lodash we can use the pick and get functions to work with objects like they were Maps.


In the example above we see that with the pick we can obtain a new Map by selecting the attributes that we want.  If it is not found then it simply want be placed in the resulting Map.

If all that is wanted is one value from the Map then we can use the get function to obtain the value. 

The get function let's us provide default values.

_.get(bilbo, 'none', 'not found')
.should.equal('not found');

_.pick(bilbo, 'none')
.should.eql({});
This helps in being able to tell if the value of the attribute is null or if the attribute does not exist.

Clojure


With Clojure we can use the keyword, get, and select-keys functions (to name a few) to work with Map data structures.


In the example above we see that we can use keywords as functions and that the Map data structure its self can be used as a function.

(is (= "Bilbo" (:name bilbo)))
(is (= "Bilbo" (bilbo :name)))

Like the Lodash get function, the get function let's us provide default values.

(is (= nil (get bilbo :none)))
(is (= :not-found (get bilbo :none :not-found)))

This again helps us in being able to tell if the keyword is not found or if the value of associated with the keyword is nil.

(is (= nil (bilbo :none)))
(is (= nil (:none bilbo)))

While using the keyword as a function for an association that does not exist will return nil.

We see also that select-keys acts much like Lodash's pick, in that it returns a new Map with the keyword associations selected.

Clojure's select-keys

(is (= {:name "Bilbo"}
(select-keys bilbo [:name])))
(is (= {:name "Bilbo" :family ["Baggins" "Took"]}
(select-keys bilbo [:name :family])))

Lodash's pick

_.pick(bilbo, 'name')
.should.eql({name: 'Bilbo'});
_.pick(bilbo, ['name', 'family'])
.should.eql({name: 'Bilbo', family: ['Baggins', 'Took']});

Fin

There you have it, Map,  the one data structure to rule them all.