Domanda

I'm curious to learn the reason for this since set seems unique. For instance:

   (set 'nm 3) ;; set evaluates its first argument, a symbol, has to be quoted
   nm ;; ==> evaluates to 3
   (set 'nm 'nn) ;; assigns nn to the value cell of nm
   nm ;; ==> evaluates to nn
   nn ;; ==> ERROR. no value
   (set nm 3) ;; since nm evaluates to nn ...
   nm ;; evaluates to nn
   nn ;; evaluates to 3

To achieve similar behavior, I've only been able to use setf:

   (setq tu 'ty) ;;
   (symbol-value 'tu) ;; returns ty
   (setq (symbol-value 'tu) 5) ;; ERROR. setq expects a symbol
   (setf (symbol-value tu) 5) ;; has to be unquoted to access the value cell
   tu ;; ==> evaluates to ty
   ty ;; ==> evaluates to 3

In other programming languages the reason(s) for demotion are pretty clear: inefficient, bug prone, or insecure come to mind. I wonder what the criteria for deprecation for set was at the time. All I've been able to glean from the web is this, which is laughable. Thanks.

È stato utile?

Soluzione

The main reason set is deprecated is that its use can lead to errors when it is used on bound variables (e.g., in functions):

(set 'a 10)
==> 10
a
==> 10
(let ((a 1))   ; new lexical binding 
  (set 'a 15)  ; modification of the value slot of the global symbol, not the lexical variable
  a)           ; access the lexical variable
==> 1          ; nope, not 15!
a
==> 15

set is a legacy function from the times when Lisp was "the language of symbols and lists". Lisp has matured since then; direct operations on symbol slots are relatively rare, and there is no reason to use set instead of the more explicit (setf symbol-value).

Altri suggerimenti

In your example:

(set nm 'nn)   ;; assigns nn to the value cell of nm
nm ;; ==> evaluates to nn

This is completely wrong and the main reason why it's deprecated. It's the symbol you get when evaluating nm that is bound to nn. Unfortunately in your example that is the number 3 and it will signal an error at run time since you cannot use numbers as variables. If you were to write (setq 3 'nn) the error can be seen at compile time.

With set there is an additional reason. It's very difficult to compile when you don't know what symbol is to be bound and the compiler cannot optimize it.

Scheme didn't have automatic quoting either in it's first version and they didn't even have a quoted macro like setq. Instead it stated that set' would suffice. It's obvious that it didn't since Scheme no longer have set but only define.

I personally disagree that it should be removed (deprecation results in removal eventually) but like eval it should be avoided and only used as a last resort.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top