Re: newbie needing help (accessing variables within macros)



Kirk Job Sluder <kirk@xxxxxxxxxxxxx> writes:

> Ok, I think I finally found the stick that is getting me to seriously
> consider lisp over python.
>
> I have to crunch a large amount of logfile data. Generally, this
> process involves:
> 1: parsing a number of log files, each with a slightly different format.
> 2: looking up values in a separate file.
> 3: bean-counting and aggregating something by group (in other words,
> adding or incrementing objects in a hash table.)
> 4: pretty-printing the output in tsv and possibly LaTeX as a bonus.
>
> Rather than continuing my pattern of cut-and-paste between multiple
> python scripts, I thought that this would be a good candidate for a lisp
> macro. Not that I'm highly wedded to the macro concept, just that a
> macro seems easier to work with than some of my alternatives.
>
> After a bit of searching I came up with this little snippit that does
> about %50 of what I want for it to do, and leads the way to %80 of the
> rest. However, after quite a bit of googling, and searching through
> Practical Common Lisp, I don't quite understand all of it. (Taken
> blatantly from http://kantz.com/jason/clim-primer/drawing.htm .)
>
> (defmacro do-file ((path line-variable &key (key #'identity)) &body body)
> "Iterate over the lines of the file, binding the line to the line-variable in each iteration"
> (let ((str (gensym))
> (var (gensym)))
> `(with-open-file (,str ,path :direction :input)
> (do ((,var (read-line ,str nil)
> (read-line ,str nil)))
> ((not ,var))
> (let ((,line-variable (funcall ,key ,var)))
> ,@body)))))
>
>
> Just as example code, this can be invoked with (from memory, so there
> may be a typo):
> (do-file ("tmp.txt" bar) (format t "~a~%" bar))
>
> Some of my issues are:
> 1: I understand the rebinding due to namespace issues. Binding the line
> to a gensym variable seems much safer than the alternatives. However,
> I'm not exactly clear on using the function identity here.
>
> 2: I don't fully grok keyword variables. My best interpretation is that
> this specification permits me to do:
>
> (do-file ("temp.txt" bar :key #'hello-world)...)
>
> This would defeat the purpose of using this macro. Why put this
> function in a place where it can be overwritten, as opposed to the body
> of the macro? Is there an advantage that I'm missing? What would be
> lost by doing (let ((,line-variable (identiy ,var))) or even (let
> (,line-variable ,var))?

It looks like the purpose of the "key" parameter is to allow
extra processing of each line. Examples could be to turn the line into
lowercase, split it into a list of fields, or even to split it into
fields, and then create an object/struct from the fields.

--
Raymond Wiker Mail: Raymond.Wiker@xxxxxxx
Senior Software Engineer Web: http://www.fast.no/
Fast Search & Transfer ASA Phone: +47 23 01 11 60
P.O. Box 1677 Vika Fax: +47 35 54 87 99
NO-0120 Oslo, NORWAY Mob: +47 48 01 11 60
.



Relevant Pages