Reputation: 265
obviously, this code should fail :
(define or 5)
but I was wondering why does this code fail to run :
(define apply
(lambda (x y f)
(f x y)
)
)
(apply #f #t or)
(or #f #t)
, would work as expected.
I'm not defining any new variable with a saved name, only passing the function or
as an argument.
and (apply 1 2 +)
on the other hand works...
Upvotes: 3
Views: 155
Reputation: 15783
When you want to redefine special forms you need to use thunks, otherwise the arguments get evaluated, while the arguments of the special forms are evaluated in the order imposed inside the special form.
Instead, to get the same behavior as the semantics of the special forms you can force and delay the argument evaluation by using thunks. For example,
(define (or-sp-form a b) (if (a) 'ok (b)))
and call such a function like
(or-sp-form (lambda () false) (lambda () true))
Defining a special form like that, it can now be passed as argument to other functions like
(f or-sp-form)
and take care inside f
to pass delayed arguments to or-sp-form
.
Upvotes: 1
Reputation: 74645
or
is a special form. It isn't a function. So it can not be passed like that as an argument. Rather than (apply #f #t or)
, you must use:
(apply #f #t (lambda (a b) (or a b)))
(define or 5)
does not fail. It shadows the or
special form. Some implementations may not allow redefinition either within a module or of given symbols. So when asking about Scheme it is important to specific the implementation.
This is because special forms can only occur in the first position. Special forms are implemented as macro expansions. For example: (or a b)
=> (let ((v a)) (if v v b))
Upvotes: 3