0

Given a simple list say '(+ 1 2) I am trying to simply evaluate the expression. But it doesn't seem to think the car of the list is a procedure.

(define i '(+ 1 2))
> i (+ 1 2)
(procedure? (car i))
> #f
(procedure? +)
> #t
(car i)
> +
(apply (car i) (cdr i))
; apply: contract violation
;   expected: procedure?
;   given: +
;   argument position: 1st
; [,bt for context]

I was wondering if there is a way to take the car and use it as a procedure or if there is a better way to do it.

Nathan Takemori
  • 139
  • 1
  • 10

2 Answers2

2

The problem is that '(+ 1 2) is short for (list '+ '1 '2). This means the first element of the list is the symbol '+ and not the procedure bound to +.

You can write:

(define i (list + 1 2))

Instead.

Alternatively, you can use quasiquote and unquote:

(define i `(,+ 1 2))
soegaard
  • 30,661
  • 4
  • 57
  • 106
2

The problem is that (car '(+ 1 2)) evaluates to the symbol '+, not the function represented by +. When you create a list using quote, none of the elements are evaluated.

The easiest way to fix this is to use list to create your list instead of quote. Since list is a function, it evaluates its arguments:

scratch.rkt> (define expr (list + 1 2))
scratch.rkt> (car expr)
#<procedure:+>
scratch.rkt> (apply (car expr) (cdr expr))
3
scratch.rkt> ((car expr) 3 4)
7
ad absurdum
  • 19,498
  • 5
  • 37
  • 60