
Affordance and Concision - fogus
http://stuartsierra.com/2013/02/04/affordance-concision
======
noelwelsh
Good post.

I tend to think of Lisp/Scheme logical and conditional operators taking an
implicitly defined monad for the type of "useful value" or "nil" (#f in
Scheme). It's just that:

1\. You can't add new instances to the type class. 2\. The language doesn't
check you handle the failure case.

If there was a monad type class you could create a type "useful value" or
"exception" (called Validation or Either in Haskell and Scala) and have the
same concise code. However, without a static type system this kind of system
just gets unmanageable (I know, I've tried it).

Proponents of dynamic typing often wax lyrical about the benefits of escaping
the straight-jacket of static typing. They often don't appreciate the kinds of
programs that are impossible to write without a modern type system. NB: this
post is not one of them.

------
islon
What about a get-or-throw that throws an exception if it can't find the key?
You get the best of both worlds.

    
    
        (defn get-or-throw [m k]
          (or 
            (get m k)
            (throw (RuntimeException. (str "could't find key " k " in map " m)))))
    

I understand most people use the simpler (key map) or (map key) forms instead
of get, but at least you have an option.

~~~
ivank
That exception message would be lying some of the time:

    
    
      user> (get-or-throw {:k nil} :k)
      RuntimeException could't find key :k in map {:k nil}  user/get-or-throw (NO_SOURCE_FILE:4)

~~~
islon
You are right, but that's easily fixable with a (if (contains? map key)

------
sp332
I like this poem linked to in a footnote:
<http://www.apl.jhu.edu/~hall/lisp/Scheme-Ballad.text>

