On Wed, 21 Jun 2000, Dirk Herrmann wrote:
> On Wed, 21 Jun 100, J C Fitzgerald wrote:
>
> > I am just learning Scheme, so this is probably my error rather than
> > Guile's, but the following appears to give inconsistant results:
Over trying to figure out the problem within guile (which actually has a
bug) I completely forgot to explain what's going on to you, sorry.
> > (display "2. ") (display (reduce and #t bb)) (newline)
Even if guile will be fixed, your code will not work. The reason is, that
you are passing 'and' to reduce. 'and' is not a function, it is a macro.
(In my following explanations I will probably not use the correct
terminology. Thus, just take this as an attempt to explain what is going
on). Macros are 'rewrite rules', i. e. they specify rules, how a certain
piece of code has to be rewritten to achieve a special behaviour. You can
take the word 'rewriting' literally: The input code is actually
transformed.
Looking at the 'and' macro, this macro specifies something like the
following set of rules (--> means 'rewrite to').
(and) --> #t
(and x) --> x
(and x <rest>) --> (let ((temp x)) (if temp (and <rest>) #f))
If 'and' were a function, all parameters of and would be evaluated,
because that is scheme's general rule: Before a function is called all
of it's parameters have to be evaluated. But, since 'and' is a macro
which works as described above, parameters are only evaluated up to the
point when a false value is detected. This is the benefit of macros: You
can use them to get around the rule that all parameters have to be
evaluated.
Now it becomes clear, why it is an error to pass macros to functions as
parameters: If you pass a macro as a parameter to some function (like you
did with reduce), this would require that the function, when trying to
'apply' that macro, had to be rewritten according to the macro rewrite
rules. But, rewriting an already existing function is rubbish for a
couple of reasons: a) The function may have been compiled into assembly
language. Then it would not be possible to 'rewrite' it any more, because
the structure of the scheme code would be lost. b) What about subsequent
calls? should they use the freshly rewritten function, or the original
one? c) there are probably a bunch of other reasons why rewriting
existing functions is a bad idea.
Thus, you see, guile should not have accepted that macro as a parameter
for reduce. However, stupidly, guile accepted it and then 'rewrote' that
function in memory. Thus, (procedure-source reduce) before and after
passing that macro looked different.
Thanks for pointing out this bug!
Dirk