¿Cuál es la diferencia entre "set", "setq" y "setf" en Common Lisp?
common-lisp
Richard Hoskins
fuente
fuente
Respuestas:
Originalmente, en Lisp, no había variables léxicas, solo dinámicas. Y no había SETQ o SETF, solo la función SET.
Lo que ahora se escribe como:
fue escrito como:
que finalmente se abrevió a SETQ (SET Citado):
Luego sucedieron las variables léxicas, y SETQ también se usó para asignarles, por lo que ya no era un simple envoltorio alrededor de SET.
Más tarde, alguien inventó SETF (campo SET) como una forma genérica de asignar valores a estructuras de datos, para reflejar los valores l de otros lenguajes:
se escribiría como
Por simetría y generalidad, SETF también proporcionó la funcionalidad de SETQ. En este punto, habría sido correcto decir que SETQ era una primitiva de bajo nivel y SETF una operación de alto nivel.
Entonces sucedieron las macros de símbolos. Para que las macros de símbolos pudieran funcionar de forma transparente, se dio cuenta de que SETQ tendría que actuar como SETF si la "variable" a la que se asignaba era realmente una macro de símbolos:
Así que llegamos en la actualidad: SET y SETQ son restos atrofiados de dialectos más antiguos, y probablemente serán arrancados de los sucesores sucesivos de Common Lisp.
fuente
f
realmente representa la función , no el campo (o la forma , para el caso), y proporciona referencias, por lo que si bien el setf para el campo tiene algún sentido, parece que podría no ser correcto.set
es una función. Por lo tanto, no conoce el medio ambiente.set
No se puede ver la variable léxica. Solo puede establecer el valor de símbolo de su argumento.setq
ya no se "establece entre comillas". El hecho de quesetq
sea una forma especial, no una macro, lo demuestra.fuente
(setq ls '(((1))))
,(setf (car (car (car ls))) 5)
es un comportamiento indefinido, porque el valor dels
es constante (como modificar un literal de cadena en C). Después(setq ls (list (list (list 1))))
,(setf (car (car (car ls))) 5)
funciona igual quels->val->val->val = 5
en C.setq
es igual queset
con un primer argumento citado,(set 'foo '(bar baz))
es como(setq foo '(bar baz))
.setf
, por otro lado, es sutil de hecho, es como una "indirección". Sugiero http://www.nano.com/lisp/cmucl-tutorials/LISP-tutorial-16.html como una mejor manera de comenzar a entenderlo que cualquier respuesta aquí que pueda dar ... en resumen, sin embargo,setf
toma el primer argumento como "referencia", de modo que, por ejemplo(aref myarray 3)
, funcionará (como el primer argumentosetf
) para establecer un elemento dentro de una matriz.fuente
Puede usarlo
setf
en lugar deset
osetq
no viceversa, yasetf
que también puede establecer el valor de elementos individuales de una variable si la variable tiene elementos individuales. Vea los ejemplos a continuación:Los cuatro ejemplos asignarán la lista (1, 2, 3) a la variable llamada foo.
setf
tiene la capacidad adicional de establecer un miembro de la lista enfoo
un nuevo valor.Sin embargo, puede definir una macro de símbolo que represente un solo elemento dentro de
foo
Puede usarlo
defvar
si aún no ha definido la variable y no desea darle un valor hasta más adelante en su código.fuente
Uno puede pensar
SET
ySETQ
ser construcciones de bajo nivel.SET
Puede establecer el valor de los símbolos.SETQ
Puede establecer el valor de las variables.Luego
SETF
hay una macro, que proporciona muchos tipos de elementos de configuración: símbolos, variables, elementos de matriz, ranuras de instancia, ...Para símbolos y variables uno puede pensar como si se
SETF
expandiera enSET
ySETQ
.Entonces,
SET
ySETQ
se utilizan para implementar algunas de las funciones deSETF
, que es la construcción más general. Algunas de las otras respuestas le cuentan la historia un poco más compleja, cuando tomamos en cuenta las macros de símbolos.fuente
Me gustaría agregar a las respuestas anteriores que setf es una macro que llama a una función específica dependiendo de lo que se pasó como primer argumento. Compare los resultados de la expansión macro de setf con diferentes tipos de argumentos:
Para algunos tipos de argumentos, se llamará "función setf":
fuente