Is Clojure is pervasively Monoidic? – nil checks are Bad Code Smell

Is Clojure pervasively monodic?

A monoid is…

  1. A set, S
  2. An operation, : S × S -> S
  3. An element of S, e : 1 -> S

…satisfying these laws:

  1. (a • b) • c = a • (b • c), for all a, b and c in S
  2. e • a = a = a • e, for all a in S

Consider concat:

(concat (concat [1] [2]) [3]) => [1 2 3]
(concat [1] (concat [2] [3])) => [1 2 3]
(concat [1] []) => [1]
(concat [] [1]) => [1]
(concat [] []) => []

For some operations, nil can be used as an empty seq:

(concat [1] nil) => [1]
(concat nil [1]) => [1]

… and with car-position key lookups:

(:key {:key 1}) => 1
(:key nil) => nil

However, this is not true for car-position map or set applications:

({:key 1} :key) => 1
(#{:key} :key) => :key
(nil :key) => ERROR

Map is not strictly monoidic, but empty seqs can be substituted for nil:

(map even? [1 2]) => [false true]
(map even? nil)   => ()

 

Leave a Reply

Your email address will not be published. Required fields are marked *

*