1

I find the amazing power of scheme in sicp

Exercise 1.4. Observe that our model of evaluation allows for combinations whose operators are compound expressions. Use this observation to describe the behavior of the following procedure:

 #+BEGIN_SRC scheme
(define (a-plus-abs-b a b)
  ((if (> b 0) + -) a b))
(a-plus-abs-b 9 4)
 #+END_SRC

 #+RESULTS:
 : 13

Try to rewrite it as

#+begin_src emacs-lisp :session sicp :lexical t
(defun a-plus-abs-b(a b)
  ((if (> b 0) + -) a b))
(a-plus-abs-b 9 4)
#+end_src

report error "invalid function"

Alternatively with

#+begin_src emacs-lisp :session sicp :lexical t
(defun a-plus-abs-b(a b)
  (funcall (if (> b 0) + -) a b))
(a-plus-abs-b 9 4)
#+end_src

Error reported as

funcall: Symbol’s value as variable is void: +

How could write it correctly in elisp?

Drew
  • 77,472
  • 10
  • 114
  • 243
Wizard
  • 1,251
  • 6
  • 17

1 Answers1

2

funcall takes a function as its first argument, so you need if to return a function symbol. You can do that by sharp-quoting its return value:

(defun a-plus-abs-b (a b)
  (funcall (if (> b 0) #'+ #'-) a b))

(a-plus-abs-b 9 4)                  ; => 13

Elisp is a Lisp-2, which means each symbol can have a function value and a variable value. When you don't quote the return value of if, you're asking it to return the variable value of + or -, which you could actually do if you want to:

(setq - "testing")
(- 1 1)                                 ; => 0
-                                       ; => "testing"
(+ 1 1)                                 ; => 2
+                                       ; => void variable "+"

See:

Dan
  • 32,980
  • 7
  • 102
  • 169