Re: returning a nodelist

Subject: Re: returning a nodelist
From: Brandon Ibach <bibach@xxxxxxxxxxxxxx>
Date: Thu, 10 Dec 1998 15:49:09 -0600 (CST)
Mike Sosteric said:
> anyway, so steal a procedure from brandon ibach, modify it, and get 
> the following code which is supposed to return a nd. if i do
> (gi nd), i can verify that I'm at the right location. 
> (define (named-nl node name)
>   (let* ((gr (node-property 'grove-root node))
>          (de (node-property 'document-element gr)))
>     (let loop ((nl (node-property 'content de)))
>       (if (node-list-empty? nl) #f
>           (let ((nd (node-list-first nl)))
>             (or (and (equal? 'element (node-property 'class-name nd))
>                      (if (string=? name (gi nd))
>                          (nd) ; <<<<----return the nodelist
>                          (loop (node-property 'content nd))))
>                 (loop (node-list-rest nl))))))))
> but when I try to return just (nd) I get 
> C:\USR\LOCAL\JADE1.2\JADE.EXE:tortf.dsl:45:25:E: call of non-function
> object "#<unknown object 10629356>"
> which suggests to my untrained eye that JADE is interpreting nd as a
> function and finding that it isn't one. 
> So my question is, how do I return a nodelist so I can process it further?
   Well, Norm gave you the answer (drop the parens around "nd").  So,
I'll just give you a little more background on why this works.
   Basically, everything in DSSSL/Scheme/Lisp is an expression to be
evaluated.  The first part of chapter 8 of the DSSSL spec covers this
fairly clearly and in good detail, but I'll give a quick summary.  (If
I didn't have other obligations, I'd be very tempted to just get it
over with and try to write a book on DSSSL... *sigh*).
   Some things, most notably constants (or "literals") evaluate to
themselves.  So, something like 89 or "hello" becomes just that: a
numeric or string literal.  A symbol, such as "nd", above evaluates to
whatever value has been "bound" to it, either via a (define) or in a
"let" construct.  A list (a series of values, possibly including other
lists, in parens), unless in a special context (such as an item in the
list of bindings for a "let" construct) will be evaluated as a
procedure call.  In this case, the first item in the list should
evaluate to a procedure, and the rest of the items will be passed as
arguments to that procedure.
   You can keep something from being evaluated by "quoting".  You can
do this via (quote) or by the single quote mark.  An example of this
is in the second line of the procedure above: 'grove-root  If I had
not "quoted" this "symbol", Jade would have tried to look up a value
that had been bound to this name.  Instead, it just passes the symbol
(one of the primitive data types in Scheme) to the node-property
procedure as-is.  Quoting, I should warn, can be obnoxiously difficult
to master, and is usually the concept that people learning Scheme have
the most difficulty with.  There is also "quasi-quoting", which is
even more complicated.  I won't even go into that here (mainly because
I still haven't completely figured it out myself :).
   Realizing that procedure calls are just a list of expressions can
lead to very interesting possibilities.  The most immediately useful
of these is creating "aliases" for functions.  For instance, you may
decide that "node-property" is just way too long of a name, so you
could:  (define node-p node-property)
   Having done this, you can then do: (node-p 'grove-root node)
because the procedure that is bound to the symbol "node-property" is
now bound to "node-p", as well.
   So, in short, by putting the parens around "nd", you're telling
Jade to invoke the procedure bound to "nd".  The problem, of course,
is that there isn't a procedure bound to "nd"... it's a node list.
So, just putting "nd" by itself will return the node list which is
bound to it.

-Brandon :)

 DSSSList info and archive:

Current Thread