Jan 15, 2009

; As always, I will post when the code is “complete”, but my progress can be followed on Github. Also, this post is executable, just copy and paste into a Clojure REPL.

(comment “

First, let me thank Stuart Halloway for picking up the On Lisp -> Clojure port where I left off. I do not know if that was intentional, but in any case it makes for nice reading to start with my first 5 chapters and then transition right into Mr. Halloway’s posts (which are much higher quality IMO).

“)

; One of my favorite parts from On Lisp is his implementation of an embedded Prolog interpreter based on a simple database and inference system. My main goal for starting the On Lisp -> Clojure series was to eventually have this embedded Prolog system to use in my own applications. I will start out by just talking about a few preliminary structures and functions and then expand on them in future installments.

;

;; ;; The original Lisp make-hash-table function works on a ;; cons-cell structure, however Clojure provides a persistent ;; hash structure instead. I am not going to port the Common ;; Lisp function to Clojure, but instead will modify the Prolog ;; implementation to fit a more idiomatic Clojure approach. ;; (defn make-db [] nil) (def *default-db* (ref (make-db))) (defn clear-db "Takes a db and clears it" ([] (clear-db *default-db*)) ([db] (dosync (ref-set db nil)))) (defn db-query "Takes a db and a key and returns the mapped val" ([key] (db-query *default-db* key)) ([db key] (get @db key))) ;; ;; db-push in Clojure is a bit trickier since it will be working ;; on a referenced persistent hash map. This version is larger ;; than the On Lisp version do to the fact that the database ;; being queried is an in-transaction value. ;; (defn db-push "Stores a value in a the db" ([key val] (db-push *default-db* key val)) ([db key val] (dosync (commute db (fn [the-db key val] (assoc the-db key (cons val (get the-db key)))) key val)))) ;; ;; fact is almost a direct translation save for minor syntax diffs ;; (defmacro fact [pred & args] `(do (db-push '~pred '~args) '~args)) (defn test-pt1 [] (fact painter reynolds joshua english) (fact painter canale antonio venetian) (db-query 'painter)) ;

; There is definitely some room for improvement (suggestions/criticisms always welcome), but these initial functions work the same as the On Lisp originals, so that’s all for now. I’ll come back later for more.

;-m