Pergunta

Esquema usa um único namespace para todas as variáveis, independentemente se eles são obrigados a funções ou outros tipos de valores. Lisp comum separa os dois, de modo que o identificador "Olá" pode se referir a uma função em um contexto, e uma string em outra.

(Nota 1:. Esta questão necessita de um exemplo do acima; sinta-se livre para editá-lo e adicionar um, ou e-mail do autor original com ele e vou fazê-lo)

No entanto, em alguns contextos, como passar funções como parâmetros para outras funções, o programador deve distinguir explicitamente que ele está especificando uma variável função, em vez de uma variável não-função, usando #', como em:

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

Eu sempre considerei que este seja um pouco de uma verruga, mas eu recentemente se depara com um argumento de que este é realmente um recurso:

...a distinção importante, na verdade, reside na sintaxe das formas, não no tipo de objectos. Sem saber nada sobre os valores de tempo de execução envolvido, é bastante claro que o primeiro elemento de uma forma de função deve ser uma função. CL leva este fato e faz com que seja uma parte do linguagem, juntamente com formas macro e especiais que também pode (e deve) ser determinado estaticamente. Então, minha pergunta é: por que você quer o nomes de funções e nomes de variáveis ??para estar na mesma namespace, quando o principal uso de nomes de função é para aparecer onde uma nome da variável raramente gostaria de aparecer?
Considere o caso de nomes de classe: por que uma classe chamada FOO evitar o uso de variáveis ??chamado FOO? A única vez que eu iria estar se referindo a classe pelo nome FOO é em contextos que espera um nome de classe. Se, por a necessidade raras ocasiões I para obter o objeto de classe que está ligado ao nome da classe FOO, há FIND-CLASS.

Este argumento faz algum sentido para mim a partir da experiência; há um caso similar em Haskell com nomes de campo, que são também as funções utilizadas para acessar os campos. Isto é um pouco estranho:

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

Esta é resolvido por um pouco de sintaxe extra, feita especialmente agradável pela extensão NamedFieldPuns:

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

Assim, para a questão, além de consistência, quais são as vantagens e desvantagens, tanto para Lisp Comum vs. Esquema e, em geral, de um único namespace para todos os valores em comparação com aqueles separados para as funções e valores não-função?

Foi útil?

Solução

As duas abordagens diferentes têm nomes: Lisp-1 e Lisp-2. Um Lisp-1 tem um único espaço de nomes para ambas as variáveis ??e funções (como no Esquema), enquanto um Lisp-2 tem espaços de nomes separados para variáveis ??e funções (como em Lisp comum). Digo isto porque você pode não estar ciente da terminologia desde que você não se referem a ele na sua pergunta.

refere-se a este debate :

Se um namespace separado para funções é uma vantagem é uma fonte de discórdia na comunidade Lisp. É geralmente referido como o Lisp-1 vs Lisp-2 debate. Lisp-1 refere-se ao modelo de Scheme e lisp-2 refere-se ao modelo de lisp comum. Estes nomes foram cunhados em um papel 1988 por Richard P. Gabriel e Kent Pitman, que extensivamente compara as duas abordagens.

Gabriel e papel de Pitman intitulado questões técnicas de separação em células funcionam e Células Valor endereços esta questão.

Outras dicas

Na verdade, conforme descrito no o papel de Richard Gabriel e Kent Pitman , o debate é sobre Lisp-5 contra Lisp-6, uma vez que existem vários outros namespaces já está lá, no papel são mencionados nomes de tipo, nomes de marcas, nomes de bloqueio e nomes de declaração. edit: este parece ser incorreta, como Rainer aponta no comentário: Esquema realmente parece ser uma Lisp-1. O seguinte não é afectada por este erro, no entanto.

Se um símbolo denota algo a ser executado ou algo a ser referido sempre é clara a partir do contexto. Jogando funções e variáveis ??na mesma namespace é principalmente uma restrição: o programador não pode usar o mesmo nome para uma coisa e uma ação. O que um Lisp-5 fica fora de esta é apenas que alguma sobrecarga sintática para fazer referência a algo de um namespace diferente do que o contexto atual implica é evitado. edit:. Este não é o retrato inteiro, apenas a superfície

Eu sei que Lisp-5 proponentes como o fato de que funções são dados, e que isso é expresso no núcleo da linguagem. I como o fato de que eu possa chamar uma lista "lista" e um "carro" carro sem confundir meu compilador, e as funções são um tipo fundamentalmente especial de dados de qualquer maneira. edit: esse é o meu ponto principal:. Namespaces separados não são uma verruga em tudo

Eu também gostei que Pascal Constanza tinha que dizer sobre isso.

Eu conheci uma distinção semelhante em Python (namespace unificado) vs Ruby (namespaces distintas para os métodos vs não-métodos). Nesse contexto, eu prefiro a abordagem de Python - por exemplo, com essa abordagem, se eu quiser fazer uma lista de coisas, algumas das quais são funções enquanto outros não são, eu não tenho que fazer nada diferente com seus nomes , dependendo de sua "função-ness", por exemplo. Considerações semelhantes aplicam-se a todos os casos em que objetos de função devem ser cogitados em torno ao invés de chamada (argumentos para, e valores de retorno de, funções de ordem superior, etc, etc).

Não-funções pode ser chamado, também (se suas classes definem __call__, no caso de Python - um caso especial de "sobrecarga de operador"), de modo a "distinção contextual" não é necessariamente claro, seja

experiência No entanto, o meu "lisp-oid" é / foi principalmente com o esquema em vez de Lisp comum, para que eu possa ser inconscientemente influenciados pela familiaridade com o namespace uniforme que, no final vem a partir dessa experiência.

O nome de uma função no esquema é apenas uma variável com a função como seu valor. Se eu faço (define x (y) (z y)) ou (let ((x (lambda (y) (z y)))), estou definindo uma função que eu posso chamar. Assim, a ideia de que "um nome de variável raramente quer que apareça lá" é uma espécie de especioso, tanto quanto Esquema está em causa.

Esquema é uma linguagem característica funcional, de modo tratar funções como dados é um dos seus princípios. Ter funções ser um tipo de seu próprio que está armazenado como todos os outros dados é uma maneira de levar adiante a ideia.

A maior desvantagem que vejo, pelo menos para Lisp comum, é compreensão. Nós todos podemos concordar que ele usa diferentes namespaces para variáveis ??e funções, mas quantos tem? Em PAIP, Norvig mostrou que ele tem "pelo menos sete" namespaces.

Quando um dos livros clássicos da linguagem, escrita por um programador altamente respeitado, nem sequer pode dizer com certeza em um livro publicado, eu acho que há um problema. Eu não tenho um problema com vários espaços de nomes, mas eu desejo que a linguagem era, no mínimo, bastante simples, que alguém poderia entender esse aspecto dele inteiramente.

Eu estou confortável usando o mesmo símbolo para uma variável e para uma função, mas nas áreas mais obscuros eu recorrer ao uso de nomes diferentes por medo (namespaces colisão pode ser muito difícil de depuração!), E que realmente deveria nunca será o caso.

Há coisas boas para ambas as abordagens. No entanto, acho que, quando importa, eu prefiro ter tanto uma lista de funções e uma lista uma variável do que ter que soletrar uma delas incorretamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top