[postmodern-devel] Building s-sql on the fly

Phil zaries at global.co.za
Thu Dec 11 18:58:27 UTC 2008


On Thu, 2008-12-11 at 17:03 +0100, Maciek Pasternacki wrote:
> Phil <zaries at global.co.za> writes:
> 
> >> > I am looking for an example of how to create a s-sql query on the fly. I
> >> > am sure I saw something like that along the line on some website but I
> >> > cant find it again.
> >> 
> >> Take a look at http://repo.or.cz/w/cl-trane.git?a=blob;f=src/taxonomy.lisp;h=5776b2b42dde277f9478c0df621ffa9742106c06;hb=HEAD
> >> 
> >> Query building takes place e.g. on lines 274-304 and 365-394.  Second
> >> example may be interesting: it's a way to generate CASE statement from
> >> list of values (it may be generalized to receive alists, I just needed
> >> the order), to effectively make an inline-dictionary without writing
> >> the CASE statement by hand.
> >
> > Firstly thanx for the example.
> >
> > Secondly, this might be a stupid question but being new to lisp I would
> > have expected those functions to be macro's you are using the `. Could
> > you please explain the reasoning behind them being functions.
> 
> Let's start from macros.  Macros are just functions that are called
> after reading in the code (in macroexpansion time, to be exact), that
> take literal parts of code as arguments, and return other piece of
> code code in form of list as a return value.
> 
> Let's take trivial macro:
> 
> (defmacro add-two (form)
>   `(+ 2 ,form))
> 
> (add-two (* 5 foo)) gets a list '(* 5 foo) as its argument, and
> macroexpands to (is equivalent to) (+ 2 (* 5 foo)).
> 
> And macro definition is equivalent to building the resulting list by hand:
> 
> (defmacro add-two (form)
>   (list 'plus 2 form))
> 
> (actually, backtick would be more efficient, as ` is able to reuse
> some conses, but these are details now).
> 
> I do the other way around: often I do need to construct a list from
> template, e.g. '(1 2 (4 3) <something>).  I could write (list 1 2
> (list 4 3) something), but I can use backtick as well: `(1 2 (3 4)
> ,something).  Try to evaluate backtick-and-comma forms in REPL, play
> around and see yourself how it works.  Backtick is "quasi-quote": it
> quotes everything that is not preceded by comma, or comma-at (,@), and
> it's most widely used in macros (since these are usually templates -
> but don't actually need to be), but it can be used to build
> complicated nested lists from templates inside functions as well.
> 
> Hope this helps,
> regards,
> Maciej.
> 


And all the behaviorists chorused AH_HAAAAA!!

Here is what how I understand this:

1. ` creates a list

2. Where the reader finds a , it evalutes what follows before the list
is build, thus the result/value of what follows  the , is passed into
the list.

;Example not using a ,
CL-USER> `(1 2 3 4 (format nil "5"))
(1 2 3 4 (FORMAT NIL "5"))

;Example using a ,
CL-USER> `(1 2 3 4 ,(format nil "5"))
(1 2 3 4 "5")

;The following is the equavilant of the preceding but it uses list and
not the shorthand `
CL-USER> (list 1 3 4 (format nil "5"))	       
(1 3 4 "5")

3. The difference between using ` in a macro and a function is the
timing of when the list is build and thus the time that stuff after a ,
is evaluated.

In a macro the list is build at compile time and the evaluation of stuff
after a , is also done at compile time.

CL-USER> (defmacro test-macro () `(+ 1 2 3 4 ,(parse-integer "5")))
TEST-MACRO

;Simulate at compile time
CL-USER> (macroexpand '(test-macro))
(+ 1 2 3 4 5)
T
;When run
CL-USER> (test-macro)
15






More information about the postmodern-devel mailing list