Lisp, differences in assignment functions

I'm new to lisp, so I apologize for what might be a simple question,

So far I understand the difference between DEFVAR and DEFPARAMETER (defvar sets only undefined variables) and LET is used only for the local scope, what is the use of SETF unlike the other destination functions mentioned earlier?

+4
source share
2 answers

DEFVAR and DEFPARAMETER define and set global special (dynamically linked) variables.

SETF and SETQ define variables (global or local, special or lexical), but do not define them.

SETF has more features than SETQ, since it can set "places" (for example, items in lists, arrays, object slots, ...).

Edit:

Paul says a variable is set in CLISP SETF. This is not exactly what he is doing. Let's get a look:

We have the following program:

(defun foo (a) (setf baz (* aa)) a) (defun bar (a) (setf baz (* aa)) a) 

Now let's see what CLISP says if we compile this program:

 [1]> (compile-file "/tmp/test.lisp") ;; Compiling file /tmp/test.lisp ... WARNING in FOO in lines 2..4 : BAZ is neither declared nor bound, it will be treated as if it were declared SPECIAL. WARNING in BAR in lines 6..8 : BAZ is neither declared nor bound, it will be treated as if it were declared SPECIAL. ;; Wrote file /tmp/test.fas 0 errors, 2 warnings 

In both functions, CLISP warns us that the BAZ variable has not been declared unbound. Instead of discarding the code, CLISP processes the BAZ variable as it was declared special.

Does this change if we download and run the code?

 [1]> (load "/tmp/test") ;; Loading file /tmp/test.fas ... ;; Loaded file /tmp/test.fas T [2]> (foo 2) 2 [3]> (bar 3) 3 [4]> baz 9 [5]> (compile-file "/tmp/test.lisp") ;; Compiling file /tmp/test.lisp ... WARNING in FOO in lines 2..4 : BAZ is neither declared nor bound, it will be treated as if it were declared SPECIAL. WARNING in BAR in lines 6..8 : BAZ is neither declared nor bound, it will be treated as if it were declared SPECIAL. 

No, even after executing SETF statements, CLISP considers that the BAZ variable is not declared.

The SBCL compiler has this to say:

 ; in: DEFUN BAR ; (SETF BAZ (* AA)) ; ==> ; (SETQ BAZ (* AA)) ; ; caught WARNING: ; undefined variable: BAZ ; in: DEFUN FOO ; (SETF BAZ (* AA)) ; ==> ; (SETQ BAZ (* AA)) ; ; caught WARNING: ; undefined variable: BAZ 

The LispWorks compiler has the following:

 ;;;*** Warning in FOO: BAZ assumed special in SETQ ; FOO ;;;*** Warning in BAR: BAZ assumed special in SETQ ; BAR 
+5
source

SETF affects an existing binding or "place". You can use it to change the value of any of the things you created with LET or DEF...

In Common Lisp, SETF is a "generic place that affects the macro." See CLHS 5.1.1 - Site Overview and Generic Link .

+3
source

Source: https://habr.com/ru/post/1307295/


All Articles