2010-07-25 8 views

Respuesta

7

Common Lisp es básicamente un descendiente del Lisp 1.5 original, o más bien, una unificación de sus dialectos divergentes. El Lisp 1.5 original era lo que hoy se llama Lisp-2. Porque estaba en los años sesenta y el hecho de que podía pasar funciones a otras funciones era bastante extraño. Nadie siquiera pensaría en dejarles compartir el mismo espacio de nombres. Casi cualquier idioma inventado hoy con soporte para funciones de orden superior y funciones anónimas elige el enfoque de espacio de nombre único. Incluyendo Clojure, que por lo demás está más cerca de Common Lisp que de Scheme.

El esquema, como Clojure, originalmente no era un dialecto divergente de Lisp 1.5, y para sus propósitos tiene sentido.

Por supuesto, en Clojure, vectores, mapas hash, conjuntos y todo lo que también se puede aplicar a argumentos, por lo que en cierto sentido un vector en Clojure podría verse como una función que toma un número natural y produce un valor de ese.

+3

(Probablemente también vale la pena mencionar que una función en los antiguos ceceo (s) era similar a una función en Emacs Lisp, solo una lista que comienza con 'lambda'.) –

+0

¿De verdad? No tenía ni idea. Entonces, ¿acaban de cambiar las variables limitadas de bajo nivel en eval antes de aplicarlo? Maldita sea, eso debe haber sido caro. – Zorf

+0

Rich Hicky habla sobre cómo evitó algunas de las trampas que normalmente vienen con Lisp-1s. (busque clojure en blib.tv). No recuerdo exactamente, así que quieres tratar de explicarlo yo mismo. – nickik

4

Me gusta tener varios espacios de nombres (más de dos pares); que hace las cosas más fáciles para el usuario y el compilador-escritor (aplicación):

CL-USER> (defclass test()()) 
#<STANDARD-CLASS TEST> 
CL-USER> (defun test()) 
TEST 
CL-USER> (defparameter test 42) 
TEST 

CL-USER> (describe 'test) 
COMMON-LISP-USER::TEST 
    [symbol] 

TEST names a special variable: 
    Value: 42 

TEST names a compiled function: 
    Lambda-list:() 
    Derived type: (FUNCTION NIL (VALUES NULL &OPTIONAL)) 
    Source form: 
    (LAMBDA() 
     (DECLARE (MUFFLE-CONDITIONS COMPILER-NOTE)) 
     (PROGN 
     (SB-INT:NAMED-LAMBDA TEST 
      NIL 
     (BLOCK TEST)))) 

TEST names the standard-class #<STANDARD-CLASS TEST>: 
    Direct superclasses: STANDARD-OBJECT 
    No subclasses. 
    Not yet finalized. 
    No direct slots. 

; No value 

CL-USER> (make-instance 'test) 
#<TEST {1005B1D601}> 
CL-USER> (test) 
NIL 
CL-USER> test 
42 
CL-USER> 
+0

¿Puede explicar por qué cree que "hace las cosas más fáciles para el usuario"? No escribí mucho Scheme, pero escribí una gran cantidad de Python, y nunca tuve un problema al querer dar una clase, una instancia y/o un método con el mismo nombre. Para el caso, incluso en Common Lisp, donde puedo volver a usar nombres como este, no creo haberlo hecho nunca. Las instancias tienden a ser sustantivos, las funciones tienden a ser verbos, etc. – Ken

+1

@Ken: Escribo rutinariamente cosas como '(defun foo (list) (list (bar list)))' en CL, que no funciona con el single espacio de nombres Tener que nombrar mis argumentos como 'lyst' o' lst' en Scheme me vuelve un poco loco. – Pillsy

+2

Pillsy: Eso es verdad. Por otra parte, llamar a los argumentos 'list' me volvería un poco loco, también, ya que es muy descriptivo. Yo lo llamaría 'source' o' target' o 'haystack' o' words' que dice cuál es el propósito de la lista. Si llamé a params por su tipo, el 90% de mis argumentos sería 'list'. :-) – Ken

7

Aunque puede haber un montón de argumentos en cada sentido en teoría, yo apostaría que es en gran parte filosófica de origen. Scheme, un Lisp-1, prefiere la elegancia sobre la practicidad, y eligió la misma sintaxis define para variables y funciones, lo que hace que un solo espacio de nombres parezca natural (y fomenta un estilo funcional de programación). Common Lisp tiende a preferir la practicidad y el poder sobre la elegancia, y fue un intento de creación de consenso, por lo que al ver una solución de dos nombres de espacio ampliamente aceptada y funcionando bien, la aceptó.

En la práctica, sin embargo, sobre todo significa tres cosas:

  • En Common Lisp (y de otros Lisp-2), usted tiene que utilizar funcall mucho
  • En el Esquema (y otros de Lisp-1), debe tener cuidado de no anular nombres de función necesarios con variables; p.ej. argumentos de la función como lst en lugar de list
  • En Internet, no habrá argumentos

Es un factor importante en por qué algunas personas prefieren una Lisp a otro, sin embargo.

+5

Los resultados de la diferencia son más profundos que simplemente usar 'funcall' o evitar conflictos de nombres: el uso de funciones de orden superior en Scheme es más natural, por lo tanto, más idiomático, por lo tanto, los compiladores trabajarán duro para optimizarlo. En CL, sin embargo, si está utilizando 'defvar' para definir una variable, y luego' funcall' it, entonces es muy probable que los compiladores la compilen en un código mucho más lento que usando una definición de función. Esto es similar a los CLers que prefieren construcciones de bucle, y los intrigantes prefieren las llamadas de cola en su lugar. Pero, por supuesto, su tercer punto es el más importante ... –

+0

Eso es cierto, y una parte de lo que quise decir con "fomenta un estilo funcional de programación" --- gracias por hacerlo más explícito. – JasonFruit

0

Además de los otros problemas mencionados anteriormente, tener un espacio de nombre separado para las funciones hace que las macros antihigiénicas de CL sean mucho menos propensas a morder al usuario macro. En CL, un nombre enlazado en el punto de llamada que aparece dentro de la expansión de una macro tendrá la definición utilizada en el punto de llamada, no la definición utilizada cuando se define la macro. Entonces, en una versión Lisp-1 de CL, si una macro se expande a una llamada en la función LISTA, y LISTA se definió como una variable en el punto donde se llamó a la macro, la macro no funcionaría correctamente. (Tenga en cuenta que los gensyms no resuelven este problema, a diferencia del problema inverso que resuelven).)

Esto no ocurre en Scheme porque de forma predeterminada las macros Scheme son higiénicas: todos los nombres utilizados en la expansión de una macro tienen los significados que tenían donde se define la macro, no donde se usa.

Cuestiones relacionadas