Boolean combinators
In the Clojure Tip above, I described a kind of Boolean combinator that lets us build complex rules out of simpler rules. Your task is to build those combinators. Please define:
(defn rule-and
([])
([rule])
([rule1 rule2])
([rule1 rule2 & rules]))
(defn rule-or
([])
([rule])
([rule1 rule2])
([rule1 rule2 & rules]))
(defn rule-not [rule])
Note that rule-and
and rule-or
are monoids and so they
follow the monoid
pattern.
For a bonus, write the functions rule-if
(that implements
the logical if arrow operator) and rule-iff
(that
implements the logical if and only if double-arrow
operator). Not that rule-if
is different from the
programming if
since it returns true
if the condition is
false
.
Please submit your solutions as comments on this gist.
Very interesting comments and elegant solutions above! I was working on a macro as well. Since
rule-and
andrule-or
are the only ones where sugar-coating is handy, I ended up adding a number of combinators (rule-xor
,rule-oneof
,rule-count
etc) to try and push the idea further.I remember writing a logical rule-based system in Java years ago, due to complex specifications written in tabular form, where the outcome was predicated on some 30 rules, some of which required and some optional etc....The naive approach of spaghetti style nested if-else junk would have been a nightmare. This exercise reminds me of that experience (but much more fun and less work:)
EDITS: some refactoring and shameless copy of better ideas: passing
and
/or
directly to the macro from @miner (passing a macro to a fn is a no-no but a macro will take anything), and usingcomplement
forrule-not
from @steffan-westcott