I have a function ALL-SUBCOMPONENTS that takes a component object and
returns a list of all its subcomponents. I want it to take an optional
keyword argument that, if supplied, is a function that is applied to
each subcomponent before it is added to the list and its subcomponents
in turn are recursively examined by ALL-SUBCOMPONENTS.
the reason for this to enable constructs like:
(all-subcomponents c
:keyword #'(lambda (x)
(if (lazy-component-p x)
(compute-lazy-component x c)
x))
Initially I called this arg :KEY, but
(remove "A" '(A A B B)
:key #'string
:test #'string=)
returns '(BB) not '("B" "B") so it seems like this wouldn' be inline
with the semantics of :key already established by the HyperSpec...
Nick
········@gmail.com wrote:
> I have a function ALL-SUBCOMPONENTS that takes a component object and
> returns a list of all its subcomponents. I want it to take an optional
> keyword argument that, if supplied, is a function that is applied to
> each subcomponent before it is added to the list and its subcomponents
> in turn are recursively examined by ALL-SUBCOMPONENTS.
>
> the reason for this to enable constructs like:
>
> (all-subcomponents c
> :keyword #'(lambda (x)
> (if (lazy-component-p x)
> (compute-lazy-component x c)
> x))
>
> Initially I called this arg :KEY, but
>
> (remove "A" '(A A B B)
> :key #'string
> :test #'string=)
>
> returns '(BB) not '("B" "B") so it seems like this wouldn' be inline
> with the semantics of :key already established by the HyperSpec...
That's odd, it should return (B B), not (quote (BB)). I'll assume
that's a typo.
Based on your description, It sounds like you want to be able to write a
more efficient version of:
(all-subcomponents (mapcar (lambda (x)
(if (lazy-component-p x)
(compute-lazy-component x c)
x))
c))
Actually, I have a few suggestions for you. In the order I'd do things:
1. Use something like ITERATE <http://common-lisp.net/project/iterate/>
and define a way to iterate over a component. This would require
learning the iterate library (which I have not used, but looks perfect
for this situation). Then your code would be something like:
(iterate (for-subcomponents subc in c)
(collect (if (lazy-component-p subc)
(compute-lazy-component subc c)
x)))
2. Define iterator functions FIRST-SUBC and NEXT-SUBC and just use LOOP
(part of the ANSI standard). You'd write exactly this:
(loop for subc = (first-subc c) then (next-subc subc)
until (null subc)
collect (if (lazy-component-p subc)
(compute-lazy-component subc c)
x))
3. Stick with your current ALL-COMPONENTS function and call the keyword
:MAPPER.
-- MJF
> That's odd, it should return (B B), not (quote (BB)). I'll assume
> that's a typo.
yup, typo
> Based on your description, It sounds like you want to be able to write a
> more efficient version of:
>
> (all-subcomponents (mapcar (lambda (x)
> (if (lazy-component-p x)
> (compute-lazy-component x c)
> x))
> c))
err, not really c is not a list, it's an object with a list of
subcomponents, each with a list of subcomponents that probubly overlap
with each other. I should have more clearly stated the problem...
ALL-SUBCOMPONENTS is like a cheap version of
(labels ((rfn (c)
(when c
(list* c (mapcan #'rfn (direct-subcomponents-of c))))))
(remove-duplicates (rfn c)))
where DIRECT-SUBCOMPONENTS-OF gets you a fresh copy of that list
> Actually, I have a few suggestions for you. In the order I'd do things:
>
> 1. Use something like ITERATE <http://common-lisp.net/project/iterate/>
> and define a way to iterate over a component. This would require
> learning the iterate library (which I have not used, but looks perfect
> for this situation).
I'll start using ITERATE if you start using IF* and stop using LOOP :-)
> 3. Stick with your current ALL-COMPONENTS function and call the keyword
> :MAPPER.
:-)
thanks
Nick
>
> -- MJF
········@gmail.com wrote:
> I have a function ALL-SUBCOMPONENTS that takes a component object and
> returns a list of all its subcomponents. I want it to take an optional
> keyword argument that, if supplied, is a function that is applied to
> each subcomponent
:applying? :filter?
Actually, I am surprised lazy components do not get computed
automatically by the accessor to that slot, or by some bottleneck
function (ensure-component...) that calls the accessor and does the
compute iff necessary. In which case modify all-components to use
'ensure-component.
kt
--
Cells: http://common-lisp.net/project/cells/
"I'll say I'm losing my grip, and it feels terrific."
-- Smiling husband to scowling wife, New Yorker cartoon