Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PyLisp: The best of both worlds... Lisp *in* Python

0 views
Skip to first unread message

William Annis

unread,
May 16, 2001, 12:12:41 PM5/16/01
to

Ok, perhaps this isn't the *best* of any world. :)

In response to the recent discussion on Lisp here, I thought
I'd make available for perusal a little library of mine, alpha code
though it is.

I have implemented a small lisp (lisp-1) interpreter in
Python. I didn't set out to do this, but I ended up with one and I
think it's sort of cute:

http://www.biostat.wisc.edu/~annis/creations/PyLisp/

Surprisingly, implementing macros was reasonably
straightforward. Due to the idiosyncratic way I handle evaluation --
functions and macros both are responsible for deciding when their
arguments are evaluated -- you can meaningfully treat macros as
first-class objects and get away with it, though it is by no means
clear to me yet what it means to map a macro over a list.

Some examples (after the colon is the result value):

;;; standard list processing
(first '(a b c)) : a ; or (car '(a b c))
(rest '(a b c)) : (b c) ; or (cdr '(a b c))
(cons 'a '(b c d)) : (a b c d)
(setq fred '(a b c)) : (a b c)

;;; all logic operations are fuzzy:
(logic 0.5) : (logic 0.5)
(logic 1.0) : *true*
(not (logic 0.0)) : *true*
(not (logic 0.35)) : (logic 0.65)
(and *true* (not *true*)) : *false*
(or *true* (not *true*)) : *true*
(setq *true* (logic .95)) : (logic 0.95)
(and *true* (not *true*)) : (logic 0.05)
(or *true* (not *true*)) : (logic 0.95)
(setq *true* (logic 1.0)) : *true* ;; the default

;;; lambdas, of course
(lambda (x y) (* x y)) : (lambda (x y) (* x y))
((lambda (x y) (* x y)) 5 2) : 10

;;; let is useful
(let ((x 5) (y 3)) (+ x y)) : 8
(let ((x 5) (y 3) z) (+ x y)) : 8

;;; for macros, you want the back-tick and interpolation:
`a : a
`(a b ,fred) : (a b (a b c))
`(a b ,@fred) : (a b a b c)
`(a (b (c (d (e (f ,@fred)))))) : (a (b (c (d (e (f a b c))))))

;;; macros
((macro (x) `(+ ,x 5)) 4) : 9
(def incf (macro (x) `(setq ,x (+ ,x 1)))) : (macro (x) (i-quote (setq , x (+ , x 1))))
(setq whee 33) : 33
(incf whee) : 34
(print whee) : 34

;;; Recursion works just fine:
(def foo
(lambda (x y)
(if (<= y 0)
x
(begin
(print x y (<= y 0))
(foo (cons y x) (- y 1))))))

I actually set out to write a wrapper around the holmes expert
system code which had a syntax that was easier to parse and which
would allow trivial evaluation of small bits of code. This little
lisp interpreter is the result, though I have yet to hack in the logic
stuff.

--
William Annis - System Administrator - Biomedical Computing Group
an...@biostat.wisc.edu PGP ID:1024/FBF64031
Mi parolas Esperanton - La Internacian Lingvon www.esperanto.org

0 new messages