2 macros and passing gensyms around



Hello all,

I have a question that will require quite a bit of an explanation. I hope
this won't be too long =P

I have this table object that holds column objects, and a collection of
records.
Each record is an array of values.

I need to access specific fields of these records.

So here goes the standard code :
(defun field-value (record column-name)
(aref (data record) (get-column-index (table record) column-name)))

(field-value record 'day) ;retreives the value of the day field on this
record

This is fine, but i have lots of records and need to make it as fast as
possible.
It seems that i can achieve double performances by doing a direct array
access, bypassing the column lookup.

So i made these two macros :

(defmacro with-bindable-columns ((&rest var-and-column-names) table-or-index
&body body)
(let ((table (gensym "TABLE-OR-INDEX")))
`(let* ((,table ,table-or-index)
,@(loop for var-and-column-name in var-and-column-names
when (listp var-and-column-name)
collect (list (conc-symbol (first var-and-column-name)
"-idx")
`(get-column-index ,table ',(second
var-and-column-name)))
when (symbolp var-and-column-name)
collect (list (conc-symbol var-and-column-name "-idx")
`(get-column-index ,table
',var-and-column-name))))
,@body)))

(defmacro bind-vars ((&rest vars) data &body body)
`(let ,(loop for var in vars
collecting `(,var (aref ,data ,(conc-symbol var "-idx"))))
,@body))

Here is a sample usage :

(defun get-first-date ()
(let ((lowest nil))
(with-bindable-columns (day)
*stats-table*
(do-table-records (*stats-table* record)
(bind-vars (day)
(data record)
(when (or (null lowest)
(< day lowest))
(setf lowest day)))))
lowest))

My problem here is the name to give to those -idx variables.
In order to avoid variable capture, i would like to give these a GENSYM
name.
The name would be created in the with-bindable-columns macro and used in the
bin-vars macro.
And of course, i'm clueless as how to do this.
Would it be possible to tell the compiler sometyhing like : "hey ! this
_compiler_ variable holds some data that will only be available within the
lexical scope of that macro expansion" ?

Thanks in advance,
Sacha


.



Relevant Pages

  • Re: defmacro
    ... (defmacro doloop (vars &body body) ... To write a macro, ...
    (comp.lang.lisp)
  • Re: 2 macros and passing gensyms around
    ... when (listp var-and-column-name) ... (defmacro bind-vars ((&rest vars) ... data &body body) ... The name would be created in the with-bindable-columns macro and used in the ...
    (comp.lang.lisp)
  • Re: A "killer" macro
    ... uses a weak "macro" language to express these solutions. ... (defun hello-world () ... On-exit is supposed to queue the formto run on scope exit; ... (defmacro in-scope (&body body) ...
    (comp.lang.lisp)
  • Re: is using WITH-SLOTS with structs portable?
    ... ((NULL OPT) ... (CAR OPTION)) ... DO: Define a macro: (WITH-object &body body) ...
    (comp.lang.lisp)
  • Re: Macro expansion semantics
    ... (defmacro foo (&body body &environment env) ... What you could do is shadow all macro-defining forms and create your own custom macro environment. ...
    (comp.lang.lisp)

Loading