|
Subject: Re: How to Collect Sosofos? From: Dave Love <d.love@xxxxxxxx> Date: 09 Sep 1997 18:34:52 +0100 |
>>>>> "Eliot" == W Eliot Kimber <eliot@xxxxxxxxxx> writes:
Elliot> What I think I want to do is iterate over a node list
I presume you don't mean a node-list type? (Doesn't look so.)
Elliot> and generate a bunch of sosfos (using make
Elliot> formatting-instruction in this case). My puzzle is how to
Elliot> end the iteration and also return the appended sosofos.
Rule no. 1: Try to avoid explicit recursion. Common patterns of
computation should be abstracted into higher-order functions (ones
that take functions as arguments). This makes things re-usable and
more comprehensible (pace Richard Gabriel); if the abstractions are
primitives in the system the result will probably be more efficient
too.
There's a bunch of such functions defined on node-lists in the
standard; analogues for normal lists should follow through
replacements of functions like `node-list' by their normal list
equivalents like `cons' if necessary.
Elliot> (define (process-props node
Elliot> (let ((propnames (split (node-property 'allpns node))))
Elliot> (sosofo-append
Elliot> (let loop ((propnames propnames))
Elliot> (if (null? propnames)
Elliot> (what do I return here?)
Elliot> (sosofo-append
Elliot> (process-property (car propnames))
Elliot> (loop (cdr propnames))))))))
The inner `let' looks as though it wants to apply `process-property'
to each member of a list and append the resulting sosofos:
(apply sosofo-append
(map process-property propnames))
[`(apply <function> <list>)' corresponds to `(<function>
<list-element-1> <list-element-1> ...)'.]
Elliot> What I can't figure out is what I return for the IF inside
Elliot> the loop--my understanding is that the result of this loop
Elliot> would always be the empty sosofo, not the sosofos appended by
Elliot> the false branch.
Such recursions bottom out at some sort of `zero' or `unit' value _of
the appropriate type_, sometimes a useful clue `(empty-sosofo)' in
this case, by the looks of it.
Elliot> I guess what I'm looking for is some kind of "for-each"
Elliot> function that can return a list of sosofos
Here's a `map' -- unfortunately not in Jade -- though in this case
(iterating over a single list) the `map1' it contains is sufficient:
(define (map f #!rest l)
(let ((map1 (lambda (f l)
(let loop ((l l))
(if (null? l)
'()
(cons (f (car l))
(loop (cdr l))))))))
(cond ((null? l)
'())
((null? (cdr l))
(map1 f (car l)))
(else
(let loop ((l l))
(if (null? (car l))
'()
(cons (apply f (map1 car l))
(loop (map1 cdr l)))))))))
Elliot> or a way to accumulate sosofos explicitly.
See also `reduce'-like functions for combining elements of lists.
To test/understand things it's useful to have a system in which to
evaluate expressions interactively. Presumbly DSC is a good choice
(I've not installed it), but the current versions of the Bigloo and
Gambit Scheme systems (see the comp.lang.scheme FAQ) understand the
DSSSL keyword and lambda syntax and could define a dummy lazy
node-list type, for instance.
After evaluating the above definition in Gambit from this Emacs buffer
I can test it and follow execution, perhaps even without having to
insert expressions to display local variables:
> (map + '(1 2) '(3 4))
(4 6)
> (trace +)
> (map + '(1 2) '(3 4))
|(+ 2 4)
|6
|(+ 1 3)
|4
(4 6)
>
HTH.
--
``Abstraction, abstraction and abstraction.''
This is the answer to the question ``What are the three most
important words in programming?'' -- Paul Hudak
DSSSList info and archive: http://www.mulberrytech.com/dsssl/dssslist
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| Re: How to Collect Sosofos?, Paul Prescod | Thread | A few question about SENG/DSSSL env, Ubik Sven |
| Re: How to Collect Sosofos?, Paul Prescod | Date | Re: Problem with Jade and Hytime 2, Jordi Mulet-Albiach |
| Month |