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.

Redundancy

Will add something here

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 allowing users to define logical rules we can alway emit the most optimized 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. Like type hints these can be purely optional, but you'll want to use them for correctness with the added benefit that very optimized decision trees can be produced.

Expressiveness

(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