Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can lisp functions return references or receive arguments by reference?

Tags:

reference

lisp

I want to know how this works:

(setf (car x) 42)

Does (car x) return an assignable reference to setf? Or is it all just macro magic? How does setf or car work?

I know passing by reference would be a terrible sin in functional programming, but I want to know how the above is done.

like image 829
salvador p Avatar asked Dec 07 '22 22:12

salvador p


1 Answers

It's macro magic. The form (setf place value) is nothing but a specialised macro expansion. For example, (setf (car x) 42) would be translated into something like this: (rplaca x 42).

You can see how your Lisp implementation expands a SETF form using MACROEXPAND, like so (my example is using SBCL, other implementations may have completely different expansions):

CL-USER> (macroexpand '(setf (aref foo 10) 1234))
(SB-KERNEL:%ASET FOO 10 1234)
T

You can also define your own expansions:

CL-USER> (defvar *value* 0)
*VALUE*
CL-USER> (defun get-value () *value*)
GET-VALUE
CL-USER> (defun (setf get-value) (x) (setq *value* x))
(SETF GET-VALUE)
CL-USER> (setf (get-value) 42)
42
CL-USER> (get-value)
42
CL-USER> (macroexpand '(setf (get-value) 23))
(LET* ()
  (MULTIPLE-VALUE-BIND (#:NEW1058) 23 (FUNCALL #'(SETF GET-VALUE) #:NEW1058)))
T
like image 110
Elias Mårtenson Avatar answered Jun 09 '23 20:06

Elias Mårtenson