Re: newbie needing help (accessing variables within macros)





Kirk Job Sluder wrote:
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.

What is not clear? (identity X) -> X. identity is useful when you are giving the user the option of a callback (in your case KEY) and you want to avoid: (let ((thing (if callback (funcall callback stuff) stuff)))...
ie, it just makes things a little easier on the tool author.




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))?



I believe this is in the spirit of something like FIND-IF, which also accepts a :key parameter: it is just a little convenience, and arguably overkill, but (a) Lisp is sometimes like that and (b) consider:


     (find-if 'oddp people :key 'age)

vs

     (find-if (lambda (p) (oddp (age p))) people)

Way too many parentheses. :)

In your case, the tool author is guessing that (a) in a sufficient number of cases the user will want some preprocessing of each line and (b) that it can safely be expressed as a standalone parameter to be inflexibly applied just as the macroexpansion decides. ie, if it was the kind of thing that would sometimes have to go this way and sometimes have to go that way, then there would be few cases where the option could be used, so why bother?

kenny

--
Cells? : http://www.common-lisp.net/project/cells/
Cello? : http://www.common-lisp.net/project/cello/
Cells-Gtk? : http://www.common-lisp.net/project/cells-gtk/
Why Lisp? http://lisp.tech.coop/RtL%20Highlight%20Film

"Doctor, I wrestled with reality for forty years, and I am happy to state that I finally won out over it." -- Elwood P. Dowd

.



Relevant Pages

  • Re: newbie needing help (accessing variables within macros)
    ... > consider lisp over python. ... Not that I'm highly wedded to the macro concept, ... > I'm not exactly clear on using the function identity here. ...
    (comp.lang.lisp)
  • newbie needing help (accessing variables within macros)
    ... consider lisp over python. ... Not that I'm highly wedded to the macro concept, ... I'm not exactly clear on using the function identity here. ...
    (comp.lang.lisp)
  • Re: Three questions
    ... of the functionality you are doing here already exists in lisp. ... Another way to implement this macro, ... really understand all of the binding forms in Common Lisp and also make ... often KEY for properly implementing control structures. ...
    (comp.lang.lisp)
  • Re: [OPINION] - does language really matter if they alldothe samething?
    ... 'choose-random' selected. ... 'choose-random' is a macro. ... ESPECIALLY on a Python list. ... In Lisp, you could use things that are macros and never ...
    (comp.lang.python)
  • [OT] PostLisp, a language experiment
    ... IMHO the worst thing in Lisp is its many parentheses. ... The worst thing about Forth IMHO is the stack clutter. ... And while I could write a macro like (with bla ... The ret is the explicit return continuation. ...
    (comp.lang.lisp)