From: ········@gmail.com
Subject: keyword argument name suggestions
Date: 
Message-ID: <1155507568.298736.259870@i42g2000cwa.googlegroups.com>
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

From: M Jared Finder
Subject: Re: keyword argument name suggestions
Date: 
Message-ID: <FsKdnRZHRMJYJkLZnZ2dnUVZ_o-dnZ2d@speakeasy.net>
········@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
From: ········@gmail.com
Subject: Re: keyword argument name suggestions
Date: 
Message-ID: <1155524250.679156.247620@i3g2000cwc.googlegroups.com>
> 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
From: Ken Tilton
Subject: Re: keyword argument name suggestions
Date: 
Message-ID: <a9SDg.17775$G_1.7965@newsfe12.lga>
········@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