uso - ¿Cuál es la diferencia entre 1 y ''1 en Lisp?
diferencia entre a y ha (7)
Nunca había pensado realmente si un símbolo podría ser un número en Lisp, así que jugué con eso hoy:
> ''1
1
> (+ ''1 ''1)
2
> (+ ''1 1)
2
> (define a ''1)
> (+ a 1)
2
El código anterior es un esquema, pero parece ser aproximadamente el mismo en Common Lisp y Clojure también. ¿ Hay alguna diferencia entre 1 y 1?
Bueno, de hecho son muy diferentes. ''1
es, sin embargo, exactamente el mismo que (quote 1)
. (car ''''x)
evalúa el símbolo ''citar''.
1
es una expresión S, es la representación externa de un dato, un número 1. Decir que 1
es un ''objeto-número'' o una expresión-S para ingresar a ese objeto sería aceptable. A menudo se dice que 1
es la representación externa del objeto numérico real.
(quote 1)
es otra expresión S, es una expresión S para una lista cuyo primer elemento es el símbolo ''cita'' y cuyo segundo elemento es el número 1. Aquí es donde ya es diferente, las palabras clave sintácticas, a diferencia de las funciones, son no se consideran objetos en el lenguaje y no los evalúan.
Sin embargo, ambas son representaciones externas de objetos (datos) que se evalúan con el mismo dato. El número cuya representación externa es 1
, sin embargo, no son los mismos objetos, el mismo código, el mismo dato, lo mismo, simplemente evalúan exactamente lo mismo. Los números se evalúan a sí mismos. Decir que son lo mismo es decir que:
(+ 1 (* 3 3))
Y
(if "Strings are true" (* 5 (- 5 3)) "Strings are not true? This must be a bug!")
Son ''lo mismo'', no lo son, ambos son programas diferentes que simplemente terminan con el mismo valor, una forma de ceceo es también un programa, una forma es un dato que también es un programa, recuerde.
Además, una vez me enseñaron un truco útil que muestra que los datos de autoevaluación no son realmente símbolos cuando se ingresan:
(let ((num 4))
(symbol? num) ; ====> evaluates to #f
(symbol? ''num) ; ====> evaluates to #t
(symbol? ''4) ; ====> evaluates to #f
(symbol? ''#/c) ; #f again, et cetera
(symbol? (car ''''x)) ; #t
(symbol? quote) ; error, in most implementations
)
Los datos de autoevaluación realmente se evalúan a sí mismos, no son ''símbolos predefinidos'' de algún tipo.
Citar impide que las expresiones se evalúen hasta más tarde. Por ejemplo, la siguiente no es una lista adecuada:
(1 2 3)
Esto es porque Lisp interpreta 1 como una función, que no lo es. Entonces la lista debe ser citada:
''(1 2 3)
Cuando cita una expresión muy simple como un número, Lisp no altera su comportamiento.
Ver Wikipedia: Lisp .
Como se ha señalado, no hay diferencia, ya que los números se evalúan a sí mismos. Puede confirmar esto usando eval
:
(eval 1) ;=> 1
Esto no está limitado a los números, por cierto. De hecho, en Common Lisp, la mayoría de las cosas se evalúan a sí mismas. Es solo que es muy raro que se evalúe algo que no sean números, cadenas, símbolos y listas. Por ejemplo, los siguientes trabajos:
(eval (make-hash-table)) ;equivalent to just (make-hash-table)
En Common Lisp, ''1 es la abreviatura de (CITA 1). Cuando se evalúa, (QUOTE something ) devuelve la parte something , sin evaluar. Sin embargo, no hay diferencia entre 1 evaluado y 1 no evaluado.
Entonces, hay una diferencia para el lector: ''1 se lee como (CITA 1) y 1 se lee como 1. Pero no hay diferencia cuando se evalúa.
En Lisp, quote
evitar que se evalúe la siguiente expresión. ''
es una abreviatura de quote
. Como resultado, ''1
es lo mismo que (quote 1)
.
Sin embargo, en Lisp, los símbolos nunca pueden ser un número. Quiero decir, ''abc
es un símbolo, pero ''123
no es (evaluado) un símbolo. Creo que esto está mal con el diseño de Lisp. Otro caso es que no solo se puede usar #t
o #f
como expresión booleana.
En Lisp, el apóstrofo evita que se evalúen los símbolos. Usar un apóstrofo antes de que un número no esté prohibido, no es necesario ya que los números se representan a sí mismos. Sin embargo, como cualquier otra lista, automáticamente se transforma en una llamada de función apropiada. El intérprete considera que estos números coinciden con su valor.
Los números son objetos de autoevaluación . Es por eso que no tiene que preocuparse por citarlos, como lo hace con, por ejemplo, las listas.
Un símbolo se puede hacer desde cualquier cadena. Si desea el símbolo cuyo nombre es el carácter único 1
, puede decir:
(intern "1")
que imprime |1|
, sugiriendo una forma alternativa de ingresarlo:
''|1|