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?

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:

| improve this answer | |
  • It's more like a brain teaser. So function is not named as the first-class citizen in elisp? – Calculus Dec 24 '19 at 10:56
  • 1
    It is a first-class citizen. It's just that symbols can hold a function and variable value. See this SO thread: What is the difference between Lisp-1 and Lisp-2? – Dan Dec 24 '19 at 11:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.