Log in

No account? Create an account

(deftype) was cool... but (declare) is kicking my butt...

I was about to add some new features to my n-dimensional raytracer when I realized that I was going to be jumping through a ton of hoops that one needn't jump through (or, more precisely, that Lisp could jump through for me). So, I started tinkering with doing optimized vector math.

In order to keep my options open about which type of numbers to use, I tried this sort of stuff for quite awhile:

(defconstant float-type  'double-float)
(defconstant vector-type `(vector ,float-type))

But, (defconstant) and (defvar) and (defparameter) all ran into troubles. Lots of places that I tried to use them, sbcl was yelling at me that they were undefined variables. It wanted their values at compile time, but it wasn't assigning them values until run time. Fair enough.

So, I finally just looked in the CLHS Index for all of the (def...) macros in search of one that would be in effect at compile time. Lo and behold, there was (deftype). Not only would it be effective when I wanted it to be, it would actually work as a type! (Okay, small victory.)

I should have searched through the CLHS sooner, but it's horrendously formatted and something there tries to make a connection back to my browser from time to time.

Anyhow, rather than littering my code with stuff like:

(declare (type vector-type v1 v2))

I was hoping to do the following:

(defmacro declf (&rest vars)  "declare something as being a float"
    `(declare (type float-type ,@vars)))
(defmacro declv (&rest vars)  "declare something as being a vector"
    `(declare (type vector-type ,@vars)))
(defmacro thef  (&rest what)  "declare something as resulting in a float"
    `(the float-type ,@what))

(defun vector-scale (alpha vec)
    (declf alpha)
    (declv vec)
    (map 'vector-type #'(lambda (x) (declf x) (thef (* x alpha))) vec))

But, I'm getting no love. (Actually, I think the (thef) is working fine.) You see, sbcl has already forgotten about the possibility of (declare) directives by the time it is done expanding the macro. So, it thinks I'm trying to call a function (type) using some variable float-type and passing the result to some function (declare).

Is there some other (def...) I'm missing that might come in handy here? Should I just use (defgeneric) and (defmethod) and make it search every time from my list of one method for each generic? Or, should I make some nasty macro for making functions with typed arguments?

Only for those with no fear of rearranging s-expressions...Collapse )