[elephant-devel] collecting values from virtual subtree?

Ian Eslick eslick at csail.mit.edu
Mon Apr 23 00:20:35 UTC 2007


The keyword approach can create an annoying collection of keywords,  
although it's easy enough as it's a common operation.

Another approach is to define a macro around each map function that  
does collecting of the output...

(map-index-collecting #'my-fn :value 5)
=>
(let (result)
   (flet ((collector (k v pk)
            (push (funcall #'my-fn k v pk) result)))
     (declare (dynamic-extent collector))
     (map-index (lambda (k v pk) (push (funcall collect-fn k v pk))
                :value 5))
   (nreverse result))

Or a shortcut for inline lambda expressions...

(map-index-collecting (lambda (k v pk) k) :value 5)
=>
(let (result)
   (map-index (lambda (k v pk) (push (progn k) result)) :value 5)
   (nreverse result))

The get-instance-by-xxx functions are a specialized version of map- 
index-collecting
except they only collect values and only work on class indices.  We  
could use that approach
and do the various operations after we've built the list instead of  
while...

So the options are:

macro wrappers
(map-index-collecting #'my-fn :value 5)
(map-index-collecting (lambda (k v pk) k) :value 5)

vs.

keyword option
(map-index #'my-fn :value 5 :collect t)
(map-index (lambda (k v pk) k) :value 5 :collect t)

vs

list-oriented extractors
(mapcar #'my-fn
	(get-index-elements :value 5))
(get-index-elements :value 5)

Anyone have any preferences?

Ian


On Apr 22, 2007, at 6:44 PM, Joe Corneli wrote:

>
> In the discussion of how to build a "virtual subtree",
>
> http://common-lisp.net/pipermail/elephant-devel/2007-April/000949.htm
>
> Ian gave me a tip on how to find all Triples with a certain property:
>
>    [My recipe] will create an index 'triples-first which only indexes
>    triples and does so by the value of the first element.  Thus you
>    can easily retrieve all triples with the first element eq to 5.
>
>    ELE-TESTS> (map-index (lambda (sk v pk) (print v)) (get-index my-
>    things 'triples-first :value 5)))
>
> Just wanted to point out that I want to *collect* these values -- so I
> wrote a function that does this:
>
> (defun match-triples-beginning (beginning)
>   (let ((results (list nil)))
>     (map-index (lambda (k v pk)
>                  (declare (ignore k pk))
>                  (setq results (nconc results (list v))))
>                (get-index *things* 'triples-beginning)
>                :value beginning)
>     (cdr results)))
>
> This makes me think that it would be nice to have a `mapcar'-style
> function built in for mapping across an index and collecting the
> results.  First question is, what would such a function be called!
> (Maybe just add a :collect keyword to `map-index'?)
> _______________________________________________
> elephant-devel site list
> elephant-devel at common-lisp.net
> http://common-lisp.net/mailman/listinfo/elephant-devel




More information about the elephant-devel mailing list