OK, after some thought, here is my present position on the
nodes application. Don't fool with the macro. Once I started getting down the road of basically having to design my own evaluation scheme, e.g. making the second argument (
in_list) eager, I was staring at a total lose. You don't want to do that because, in general, you can't anticipate all the usages of such a thing that will break your application. Better to go with a scheme that has easy semantics that can cover all your bases. I believe that going back to your function representation will get us back into winnage.
That said, you might be surprised to see what I am suggesting now:
Code: Select all
(define (nodes beneath_name in_list)
(or (lookup "nodes"
(or (ref (list '* (list "name" beneath_name) '*)
in_list match true)
'()))
'()))
So, I'm giving you something more complex, and now
ref's first argument is noisy again. Oh well. On the other hand, you don't have to worry about special evaluation schemes.
So, what is the business with the added
(or ... '()) wrappers? The answer is that it's a typing thing and designed to avoid runtime typing errors.
lookup is expecting to see a list in its second argument; however, if
ref ever fails to match, it will return nil, not a list. So, the
or wrapper is in there to ensure a list comes out of that puppy.
The same typing issue is true for
nodes, which also expects a list in its second argument. But also,
nodes's return value should always be a list. If this typing scheme holds, this means that you can now safely do nested
node calls — as in your code sample — not being concerned about tripping a runtime typing error like "ERR: list expected : nil".
I hope that helps a little, and sorry about leading you astray earlier; however, I too learned a valuable lesson. Let's see if I'll remember it though. :)