[iterate-devel] Integration with CL-ENUMERATIONS and ITERATE

Hoehle, Joerg-Cyril Joerg-Cyril.Hoehle at t-systems.com
Fri Mar 11 13:52:29 UTC 2005


Marco Antoniotti wrote:
>I would like to provide an ITERATE extension to leverage the 
>ENUMERATION instances.  I went through the manual but I am a little 
>unclear about how to user DEFMACRO-DRIVER etc.
>Could anybody help me?

Sure, send this to the list.

I admit that I'm also confused by the proliferation of terms and lack of definitions (or hard to find definitions in flowtext), e.g.
defclause
defclause-driver
defmacro-driver
defmacro-clause
defclause-sequence

What's a clause? what's driver? etc.

My finding so far is that a driver comes into play when FOR can be replaced by GENERATE.
defmacro-* is best suited for users writing extensions, drawing from the macro concept, i.e. the body expands to other iterate clauses and CL forms.

C.f. iterate-test.lisp

I'll make a note that the manual should provide a glossary, or at least make the index work
-- where does a TeX .ind file come from?

Also unclear to me is top-level vs. anywhere forms. Why are some clauses (mostly FOR, but not all of them) restricted to the top-level?


As an exercise, I just looked at iterate-pg.lisp. It appears that it cannot currently be written using only names exported from the ITERATE package. The only thing lacking is an interface to add-loop-body-wrapper for the sake of with-pg-cursor.
Other than that, it could be written like

(defmacro-driver (FOR var-spec IN-RELATION query ON-CONNECTION conn)
  (add-loop-body-wrapper `(with-pg-cursor ,cursor ,conn ,query))
  `(for ,var-spec = (first (or (pg-result #) (finish)))) or
  `(for/generate ,var-spec next (first (or (pg-result #) (terminate))))
)

Alternatively, with-pg-cursor might be "inlined" into the expansion using iterate:finally-protected and with clauses.
That would also prevent double evaluation of CONN.

I recommend that you stick to the manual as long as possible and write a macro-clause or -driver. Don't look at the internals, don't use return-driver-code, make-binding etc.

Actually, it may be a worthwhile exercise to rewrite some part of Iterate in a system construction manner, building drivers on top of others. It could make code shorter and possibly easier to maintain.
E.g. FOR ... IN could be written as follows:
(defmacro-driver (FOR var IN list &optional BY (step ''cdr))
  (let ((for/gen (if generate 'generate 'FOR)))
    `(,for/gen (,var) ON ,list BY ,step)))
and the expansion is only slightly worse than now (one temporary let)

Regards,
	Jorg Hohle



More information about the iterate-devel mailing list