Pregunta

Scheme utiliza un único espacio de nombres para todas las variables, independientemente de si están vinculadas a funciones u otros tipos de valores. Common Lisp separa los dos, de modo que el identificador '' hola '' puede referirse a una función en un contexto y una cadena en otro.

(Nota 1: esta pregunta necesita un ejemplo de lo anterior; siéntase libre de editarlo y agregar uno, o envíe un correo electrónico al autor original con él y lo haré).

Sin embargo, en algunos contextos, como pasar funciones como parámetros a otras funciones, el programador debe distinguir explícitamente que está especificando una variable de función, en lugar de una variable que no es una función, utilizando # ' , como en:

(sort (list '(9 A) '(3 B) '(4 C)) #'< :key #'first)

Siempre he considerado esto como una verruga, pero recientemente me he encontrado con un argumento de que esta es realmente una característica:

...la La distinción importante en realidad radica en la sintaxis de las formas, no en la tipo de objetos Sin saber nada sobre los valores de tiempo de ejecución involucrado, está bastante claro que el primer elemento de una forma de función debe ser una función CL toma este hecho y lo hace parte de la lenguaje, junto con formas macro y especiales que también pueden (y deben) ser determinado estáticamente Entonces mi pregunta es: ¿por qué quieres el nombres de funciones y nombres de variables para estar en la misma espacio de nombres, cuando el uso principal de los nombres de funciones es aparecer donde un nombre de la variable rara vez querría aparecer?
Considere el caso de los nombres de clase: ¿por qué debería evitar una clase llamada FOO? el uso de variables llamadas FOO? La única vez que me referiría al La clase con el nombre FOO está en contextos que esperan un nombre de clase. Si, en la rara ocasión que necesito para obtener el objeto de clase que está vinculado a la nombre de clase FOO, hay FIND-CLASS.

Este argumento tiene algún sentido para mí por experiencia; Hay un caso similar en Haskell con los nombres de campo, que también son funciones utilizadas para acceder a los campos. Esto es un poco incómodo:

data Point = Point { x, y :: Double {- lots of other fields as well --} }
isOrigin p = (x p == 0) && (y p == 0)

Esto se resuelve con un poco de sintaxis adicional, que se hace especialmente agradable con la extensión NamedFieldPuns :

isOrigin2 Point{x,y} = (x == 0) && (y == 0)

Entonces, a la pregunta, más allá de la coherencia, ¿cuáles son las ventajas y desventajas, tanto para Common Lisp vs. Scheme como en general, de un solo espacio de nombres para todos los valores versus los separados para funciones y valores no funcionales?

¿Fue útil?

Solución

Los dos enfoques diferentes tienen nombres: Lisp-1 y Lisp-2. Un Lisp-1 tiene un espacio de nombres único para variables y funciones (como en el Esquema), mientras que un Lisp-2 tiene espacios de nombres separados para variables y funciones (como en Common Lisp). Menciono esto porque es posible que no conozca la terminología ya que no se refirió a ella en su pregunta.

Wikipedia se refiere a este debate :

  

Si un espacio de nombres separado para funciones es una ventaja es una fuente de controversia en la comunidad de Lisp. Por lo general, se conoce como el debate Lisp-1 vs. Lisp-2. Lisp-1 se refiere al modelo de Scheme y Lisp-2 se refiere al modelo de Lisp común. Estos nombres fueron acuñados en un artículo de 1988 por Richard P. Gabriel y Kent Pitman, que compara ampliamente los dos enfoques.

Artículo de Gabriel y Pitman titulado Problemas técnicos de separación en celdas de función y celdas de valor aborda este problema.

Otros consejos

En realidad, como se describe en el documento de Richard Gabriel y Kent Pitman , el debate es sobre Lisp-5 contra Lisp-6, dado que ya hay varios otros espacios de nombres allí, en el documento se mencionan nombres de tipos, nombres de etiquetas, nombres de bloque y nombres de declaración. editar: esto parece ser incorrecto, como señala Rainer en el comentario: el esquema en realidad parece ser un Lisp-1. Sin embargo, lo siguiente no se ve afectado en gran medida por este error.

Si el símbolo denota algo a ejecutar o algo a lo que se hace referencia siempre queda claro por el contexto. Lanzar funciones y variables al mismo espacio de nombres es principalmente una restricción: el programador no puede usar el mismo nombre para una cosa y una acción. Lo que un Lisp-5 obtiene de esto es solo que se evita cierta sobrecarga sintáctica para hacer referencia a algo desde un espacio de nombres diferente al que implica el contexto actual. editar: esta no es la imagen completa, solo la superficie.

Sé que a los proponentes de Lisp-5 les gusta el hecho de que las funciones son datos, y que esto se expresa en el núcleo del lenguaje. Me gusta el hecho de que puedo llamar a una lista '' lista '' y un automóvil '' automóvil '' sin confundir mi compilador, y las funciones son un tipo fundamentalmente especial de datos de todos modos. editar: este es mi punto principal: los espacios de nombres separados no son una verruga en absoluto.

También me gustó lo que Pascal Constanza tenía que hacer. decir sobre esto.

He encontrado una distinción similar en Python (espacio de nombres unificado) frente a Ruby (espacios de nombres distintos para métodos versus no métodos). En ese contexto, prefiero el enfoque de Python; por ejemplo, con ese enfoque, si quiero hacer una lista de cosas, algunas de las cuales son funciones y otras no, no tengo que hacer nada diferente con sus nombres. , dependiendo de su '' función-ness '', por ejemplo. Consideraciones similares se aplican a todos los casos en los que los objetos de función deben agruparse en lugar de llamarse (argumentos y valores de retorno de funciones de orden superior, etc., etc.).

Las no funciones también se pueden llamar (si sus clases definen __call__ , en el caso de Python, un caso especial de "sobrecarga del operador"), entonces la "distinción contextual" tampoco es necesariamente claro.

Sin embargo, mi " lisp-oid " la experiencia es / fue principalmente con Scheme en lugar de Common Lisp, por lo que puedo estar sesgado inconscientemente por la familiaridad con el espacio de nombres uniforme que al final proviene de esa experiencia.

El nombre de una función en Scheme es solo una variable con la función como su valor. Si hago (define x (y) (zy)) o (let ((x (lambda (y) (zy))))) , estoy definiendo un función que puedo llamar. Entonces, la idea de que "un nombre de variable raramente querría aparecer allí" es algo engañoso en lo que respecta a Scheme.

Scheme es un lenguaje característicamente funcional, por lo que tratar las funciones como datos es uno de sus principios. Tener funciones como un tipo propio que se almacena como todos los demás datos es una forma de llevar a cabo la idea.

El mayor inconveniente que veo, al menos para Common Lisp, es la comprensibilidad. Todos podemos estar de acuerdo en que usa diferentes espacios de nombres para variables y funciones, pero ¿cuántos tiene? En PAIP, Norvig demostró que tiene "al menos siete". espacios de nombres.

Cuando uno de los libros clásicos del lenguaje, escrito por un programador muy respetado, ni siquiera puede decirlo con certeza en un libro publicado, creo que hay un problema. No tengo ningún problema con varios espacios de nombres, pero desearía que el idioma fuera, al menos, lo suficientemente simple como para que alguien pudiera entender este aspecto por completo.

Me siento cómodo usando el mismo símbolo para una variable y una función, pero en las áreas más oscuras recurro a usar diferentes nombres por miedo (¡los espacios de nombres en colisión pueden ser realmente difíciles de depurar!), y eso realmente debería nunca será el caso.

Hay cosas buenas en ambos enfoques. Sin embargo, creo que cuando importa, prefiero tener una LISTA de funciones y una LISTA variable que tener que deletrear una de ellas incorrectamente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top