¿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
frealmente 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.setes una función. Por lo tanto, no conoce el medio ambiente.setNo se puede ver la variable léxica. Solo puede establecer el valor de símbolo de su argumento.setqya no se "establece entre comillas". El hecho de quesetqsea 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 delses 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 = 5en C.setqes igual quesetcon 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,setftoma 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
setfen lugar desetosetqno viceversa, yasetfque 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.
setftiene la capacidad adicional de establecer un miembro de la lista enfooun nuevo valor.Sin embargo, puede definir una macro de símbolo que represente un solo elemento dentro de
fooPuede usarlo
defvarsi 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
SETySETQser construcciones de bajo nivel.SETPuede establecer el valor de los símbolos.SETQPuede establecer el valor de las variables.Luego
SETFhay 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
SETFexpandiera enSETySETQ.Entonces,
SETySETQse 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