3

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...

4
  • 1
    It is not obvious that (define or 5) fails. It does not make much sense, but it is legit Scheme code. Commented Dec 9, 2019 at 8:06
  • 1
    Also you should not name your function apply, that clashes with a built-in procedure of the same name. Commented Dec 9, 2019 at 8:58
  • Completely off topic: I personally didn't grok Scheme and Lisp until I gave up on the layout habits I had picked up from curly-brace languages. I think it's because they suggest (at least to me) a structure that doesn't fit reality. Commented Dec 10, 2019 at 15:44
  • It's not obvious that it should fail. Eg. (define define 5) is perfectly OK and in the same lexical scope you may not define anymore for anything other then getting the binding 5. Commented Dec 14, 2019 at 1:39

2 Answers 2

3

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))

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.