Skip to content
swannodette edited this page Apr 14, 2011 · 25 revisions

Order

Could Logos help us determine equivalent terms elegantly? Perhaps that's what Rich Hickey meant about implication? We don't want to pay for a runtime logic engine though. For example, the following in Standard ML would be problematic.

(defm precip
  ([n] :guard [(integer? n)] (/ 1 n))
  ([0] 0))

We could use the guard to test the literal to reorder the statements. Guards are not functions. They are predicates that must be declared. This simplifies a lot of things. Undeclared predicates will raise an error.

Using rules to optimize predicate dispatch

(?- complement even? odd?)
(?- complement odd? even?)

(defm record-match [a b]
  ([(A. 0) 1])
  ([(A. x) 3] :guard [(even? x)])
  ([(A. 1) b])
  ([(A. x) b] :guard [(odd? x)]))

There's no way normally to know that two predicates are complementary. By making users to define their predicates we get correctness and the most efficient decision tree.

Why stop?

(defpred even? even?)                ; declare the predicate even? maps to even? fn
(defpred number? number?)            ;
(defpred integer? integer?)          ;

(?- even? x :- number? x integer? x) ; anything that is even is an integer
(?- integer? x :- number? x)         ; anything that is an integer is a number

Now we can can error-check defm - we know what predicates are subsumed.

Expressiveness + Correctness + Performance

(defm gf2
  ([a] (gf2 (transient! [])))
  ([[] v] (persistent! v))
  ([[a & r] v] :guard [(even? a) (integer? a)]
    (recur r (conj v {:even-int a})))
  ([[a & r] v] :guard [(odd? a) (float? a)]
    (recur r (conj v {:odd-float a})))
  ([[a & r] v]
    (recur r v))
  :where [(vector? v)])
Clone this wiki locally