I sense already that I'm going to annoy people with this post, but
hear me out - I do have something significant to say.
I've been trying as a learning exercise to implement a subset of
Portable Standard Lisp in Clojure, enough to get some non-trivial
programs to run. I'm not talking about REDUCE here... This means, of
course, I'm going to have to redefine quite a lot of the language.
;; create a namespace
(create-ns 'psl)
;; and use it
(in-ns 'psl)
;; t is trivial, but useful to have it defined early
(def t true)
;; Need to map names which we will overwrite;
;; in some cases this is all that's needed
(clojure/refer 'clojure :rename
'{
;; cdr and friends; just remap (trivial; car is mildly
;; more complex)
rest cdr
ffirst caar
frest cadr
rfirst cdar
rrest cddr
;; note that macros that expand to things which we have
;; redefined are probably going to fail (e.g. cond,
;; which refers to itself)
cond cljcond
+ plus
- difference
* times
;; can't implement PSL divide because Clojure doesn't
;; have dotted pairs.
/ quotient
})
;; In Clojure, 'nil?' looks as if it might be the same as 'null',
;; but it significantly isn't. (nil? ()) => false, because
;; (= nil ()) => false. 'empty?' is more like null, but it isn't
;; either, because it throws an exception if its arg is not a
;; collection.
(clojure/defn
#^{:arglists '([any x])
:doc "true if x is an empty list or nil - in Clojure these are NOT
the same - else false."}
null [x]
(if (= x nil) t
(if (= x false) t
(if (and (coll? x)(empty? x)) t
nil)))
)
What's with all those untidy nested 'if's? Wouldn't a cond have been
more elegant? Well, I've moved the Clojure cond aside, and not yet
defined my own. But, the glory of namespaces is that I should have
been able to write
(clojure/cond
(= x nil) t
(= x false) t
(and (coll? x)(empty? x)) t
:else nil)
So why didn't I?
psl=> (clojure/cond 'a 'b)
java.lang.Exception: Unable to resolve symbol: cond in this context
Hang on, I didn't type 'cond', I typed 'clojure/cond'. So where's the
unprotected 'cond' coming from?
psl=> (macroexpand '(clojure/cond 'a 'b 'c 'd))
(if (quote a) (quote b) (cond (quote c) (quote d)))
And this in turn is because, in core.clj
(defmacro cond
"Takes a set of test/expr pairs. It evaluates each test one at a
time. If a test returns logical true, cond evaluates and returns
the value of the corresponding expr and doesn't evaluate any of the
other tests or exprs. (cond) returns nil."
[& clauses]
(when clauses
(list 'if (first clauses)
(second clauses)
(cons 'cond (rest (rest clauses))))))
Could I suggest that macros defined in the 'clojure' namespace, which
refer to other things in the clojure namespace, do so explicitly, so
that this should be:
(defmacro cond
"Takes a set of test/expr pairs. It evaluates each test one at a
time. If a test returns logical true, cond evaluates and returns
the value of the corresponding expr and doesn't evaluate any of the
other tests or exprs. (cond) returns nil."
[& clauses]
(when clauses
(list 'clojure/if (first clauses)
(second clauses)
(cons 'clojure/cond (rest (rest clauses))))))
In passing I note that 'cond' is actually defined in the namespace
'clojure.core' so that that should possibly be
(defmacro cond
"Takes a set of test/expr pairs. It evaluates each test one at a
time. If a test returns logical true, cond evaluates and returns
the value of the corresponding expr and doesn't evaluate any of the
other tests or exprs. (cond) returns nil."
[& clauses]
(when clauses
(list 'clojure/if (first clauses)
(second clauses)
(cons 'clojure/cond (rest (rest clauses))))))
But I think it's fair that anyone who modifies stuff in the clojure
namespace does so at their own risk. It ought, however, to be possible
to override stuff safely in private namespaces... or else, what's the
point of having namespaces?
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---