News for hackers. Stuff that matters.
Re:Clojure: On the importance of recognizing and using maps by arohner on Friday March 13, 2009 @02:24PM (#515136)
"A downside is that the compiler won't warn you if you break some constraint that invalidates the model of whatever the map is meant to represent. For example, if you remove a value from the map necessary for a certain computation (Clojure maps are immutable, but dissoc'ing away a critical piece of data leads to the same problem)."

One feature of clojure that's worth pointing out is the idea of a validator on a reference type. The reference types are boxes that can only be changed in thread-safe ways. For example, a ref is a container that can only be modified inside of a transaction. You could write:

    (def obj (ref {:foo 3 :bar :5} :validator validate-my-model)
That creates a ref that hold a map with two keys, foo and bar. It also will call the function "validate-my-model" whenever you try to modify the map. validate-my-model is a function that takes the new-state as an argument, and throws an exception or returns false if the new state is not acceptable. Let's say the definition of validate-my-model looks like:

    (defn validate-my-model [new-state]
        (assert (map? new-state))
        (assert (int? (new-state :bar)))
        (assert (int? (new-state :foo)))
        (assert (not (= 0 (new-state :bar))
        (assert (> (new-state :bar) (new-state :foo))
        true)

 Now if you want to modify/update that object (for example, to remove the key :foo from the object), you would do
    (dosync 
        (alter obj #(dissoc % :foo)))
Before that change is committed, the validator function is run. In this case, your change would throw an exception because the of line (int? (new-state :foo))

(new-state :foo) returns nil, and (assert (int? nil) will throw an exception.

Vars, refs and agents now support this (and maybe atoms but I'm not sure). I've found the technique extremely powerful. I use it all over my code. What's also nice is that it serves as a form of testing. I know that all of my models have the correct types and relationships, because it's not possible to change the objects without calling the validator.

Re:Clojure: On the importance of recognizing and using maps by adamc on Saturday March 14, 2009 @09:48AM (#515848)
That's very cool; thanks for sharing.