Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the use of Maybe/Option not so pervasive in Clojure?

Why does Clojure, despite such an emphasis on functional paradigm, not use the Maybe/ Option monad to represent optional values? The use of Option is quite pervasive in Scala, a functional programming language I use regularly.

like image 352
missingfaktor Avatar asked Apr 30 '11 05:04

missingfaktor


2 Answers

Clojure is not statically typed, so doesn't need the strict this/that/whatever type declarations that are necessary in haskell (and, I gather, Scala). If you want to return a string, you return a string; if you return nil instead, that's okay too.

"Functional" does not correspond exactly to "strict compile-time typing". They are orthogonal concepts, and Clojure chooses dynamic typing. In fact, for quite some time I couldn't imagine how you could implement many of the higher-order functions like map and still preserve static typing. Now that I have a little (very little) experience with Haskell, I can see that it's possible, and indeed often quite elegant. I suspect that if you play with Clojure for a while, you will have the opposite experience: you'll realize the type declarations aren't necessary to give you the kind of power you're used to having in a functional language.

like image 193
amalloy Avatar answered Oct 18 '22 02:10

amalloy


In Clojure, nil punning provides most of the functionality that Scala & Haskell get from Option & Maybe.

**Scala**                **Clojure** Some(1) map (2+_)        (if-let [a 1] (+ 2 a))  Some(1) match {          (if-let [a 1]   case Some(x) => 2+x      (+ 2 a)   case None    => 4        4) } 

Scala's Option & Haskell's Maybe are both instances of Applicative. This means that you can use values of these types in comprehensions. For example, Scala supports:

for { a <- Some(1)       b <- Some(2) } yield a + b 

Clojure's for macro provides comprehensions over seq. Unlike monadic comprehensions, this implementation allows mixing instance types.

Though Clojure's for can't be used for composing functions over multiple possible nil values, it's functionality that's trivial to implement.

(defn appun [f & ms]   (when (every? some? ms)     (apply f ms))) 

And calling it:

(appun + 1 2 3)    #_=> 6 (appun + 1 2 nil)  #_=> nil 
like image 41
agarman Avatar answered Oct 18 '22 01:10

agarman