(get client :phone)
(:phone client)
(client :phone)
It takes some getting used to, but I already came to expect (and enjoy) that any symbol I use can be a function.
(defmacro deftable (name)
`(progn
(defparameter ,name (make-hash-table))
(defun ,name (k)
(gethash k ,name))
(defsetf ,name (k) (v)
`(setf (gethash ,k ,',name) ,v))))
now you can do:
(deftable client), which creates the hashtable, and then(client 'phone) will retrieve the value,
(setf (client 'phone) '4444444) will set the value.
(defun all (test seq)
(funcall (notfn #'some) (complement (testify test)) seq))
doesn't seem that bad.One thing that does however bother me about Clojure is the interaction of dynamic binding and lazy evaluation. Allow me to illustrate:
=> (def *test* 0)
#'user/*test*
=> (binding [*test* 2]
(map #(* % *test*) '(1 2 3)))
(0 0 0)
The call to map is lazy, and the returned seq is only evaluated once it hits the 'P' of REPL, which is outside the dynamic binding of test. If you surround the map call with (doall and ), the result is (2 4 6).This is of course a trivial case, but I've been bitten by this in practice where the binding, lazy sequence and var evaluation were a few call steps apart, and it's always been very unpleasant. Most of the time, it's involved vars which don't have a root binding, so it throws an error, but in other cases it's a lot more serious.
I guess the same problem can be provoked in both Clojure and CL by returning a closure evaluating that var to back outside the dynamic binding, but since you'd be explicitly invoking the closure, it's a lot more obvious what's going to happen than the "magic" that is lazy evaluation.
(let [#^int a 2
#^int b 3]
(cons a b))
a and b are not hinted to be primitive types. Type hinting is purely for objects. Use hinting to make it clear to the compiler what sort of objects you are passing into something (e.g. a constructor that takes a String). If there is confusion, clojure will do reflection.The right thing to do in this case, is the second thing that the author mentions:
(let [a (int 2)
b (int 3)]
(cons a b))
a way to see that a and b are really primitive is: (let [x (int 5)]
(.shortValue #^Integer x)) ; exception: "can't type hint primitive..."
There's a post on the mailing list that goes over this much better than I did (and where I drew the examples): http://groups.google.com/group/clojure/browse_thread/thread/...I understand that this is really beside the point, that the author finds type hinting syntax unattractive, but I just wanted to clear up confusion (if there was any).
EDIT: clarity