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 |