Por que o elisp não possui espaços para nome?

40

P: Por que o elisp não possui espaços para nome e como podemos obtê-los?

O Elisp não possui espaços para nome que não sejam o global, o que levou à convenção de codificação de prefixar todas as funções, variáveis ​​e constantes globais com um prefixo exclusivo.

Além do fator de aborrecimento, isso também me parece uma questão fervilhante, dado 1) o número sempre crescente de grandes bibliotecas e pacotes e 2) a existência contínua de funções e variáveis ​​herdadas que não respeitam a convenção de prefixo ou são suficientemente idiossincráticos que não há realmente uma boa opção de prefixo que eles possam usar. Isso também significa que tentativas periódicas de racionalizar códigos mais antigos (como na transição de clpara cl-lib) é uma quantidade de trabalho não trivial. (Embora eu esteja feliz com a limpeza, ainda choro toda vez que digito algo assim cl-find).

Fui bisbilhotando para ver se conseguia descobrir por que o elisp ainda não possui espaços para nome após algumas décadas de uso, mas fiquei um pouco surpreso com a colheita modesta. A página wiki sobre namespaces é bastante curta. Nic Ferrier tem um tratamento um pouco mais longo do problema, e há um tópico bastante recente no emacs-devel também. Há um antigo thread Stack Overflow de 2010 que discute a possibilidade de usar macros para implementar namespaces; outro exemplo da abordagem macro pode ser encontrado aqui . Existem pelo menos algumas implementações ( aqui e aqui , com uma descrição desta última aqui) por aí, mas eles não vêem muita atividade há alguns anos, e eu não encontrei nenhuma biblioteca que as use.

Presumo que, se a adição de namespaces fosse fácil, isso já seria feito. Tão:

  • Quais são as barreiras técnicas para adicionar namespaces ao elisp?
  • Adicionar espaços para nome quebraria muito código existente?
  • Essa funcionalidade é algo que precisa ser orgânico para ser elisp (alterações no próprio intérprete) ou realmente pode ser construído no topo por meio de macros?
Dan
fonte
6
Você pode dar uma olhada nisto: github.com/Bruce-Connor/names Parece ser uma implementação compatível com versões anteriores (com a maneira manual atual de separar nomes) de espaços para nome automáticos. (E tenho 99% de certeza de que já vi outra biblioteca desse tipo, permitindo que o desenvolvedor exporte um subconjunto de funções com namespaces, mencionado recentemente em algum blog do emacs, mas não consegui encontrá-lo novamente).
T. Verron
2
Segundo, você deve dar uma olhada no link acima. É uma macro de namespace muito recente (lançada no mês passado) e muito robusta. Ainda estou trabalhando em alguns problemas em termos de compatibilidade com ferramentas como o edebug, mas o pacote funciona. Responder a sua pergunta é um ensaio muito longo (as barreiras técnicas que enfrentei foram muitas), mas tentarei colocá-lo em postagens de blog nas próximas semanas.
Malabarba
11
Eu acho que namespaces significam coisas diferentes. Eu teria dito emacs tem vários namespaces: Um para variáveis, outro para funções e macros, outro para rostos, e por temas, e ...
Harald Hanche-Olsen
11
@ HaraldHanche-Olsen você certamente pode dizer isso. Nesse contexto, ele está perguntando por que não há namespaces por pacote.
Malabarba 27/10/2014

Respostas:

28

Por que não há namespaces?

Porque é complicado, e ninguém considerou urgente o suficiente para mergulhar ainda. Isso já foi discutido na lista de desenvolvedores (mais de uma vez), e houve promessas de corrigir isso após a mudança para o git.

Enquanto isso, escrevi uma solução própria (veja abaixo uma lista de opções).

Quais são as barreiras técnicas?

Logo à porta, você tem 3 grandes obstáculos, que você precisa superar para que os namespaces tenham a chance de trabalhar no Emacs atual:

  • Você precisa alterar a forma como os símbolos são armazenados (esta é a parte mais fácil).
  • O compilador de bytes precisa entender os espaços para nome.
  • A geração de carregamento automático usada por package.elprecisa entender os espaços para nome.

A correção dessas três coisas para trabalhar, no entanto, você implementa namespaces não é trivial. Se você se dedica apenas à versão mais recente do Emacs, é certamente possível. Se você deseja escrever algum tipo de pacote que também suporte versões anteriores (como toda a família 24), isso se torna um grande desafio.

Além disso, existem muitos outros obstáculos opcionais. O Elisp é excelente por causa de todo o poder das ferramentas disponíveis para você e TODAS essas precisam ser corrigidas para funcionar com espaços para nome. Entre os mais importantes estão:

  • edebug
  • eval-defun
  • eval-last-sexp
  • lodo

Quebraria muito código existente?

Não se você fizer certo.

Isso é algo que precisa ser orgânico ou realmente pode ser construído no topo por meio de macros?

Idealmente, seria orgânico, é o que geralmente é discutido quando aparece na lista de desenvolvedores. Mas isso pode ser feito o suficiente enquanto é construído em cima.
Aqui estão alguns exemplos disso, extraídos desta lista :

Malabarba
fonte
11
Obrigado - essa foi uma opinião muito informativa sobre o assunto. Estou curioso sobre o seu último ponto re: sua namessolução. Gostaria de saber se há alguma razão para suspeitar que um orgânico, built-in solução está vindo em um futuro não muito distante, ou se deve apenas adotar o incorporada na solução que você forneceu.
Dan
11
@ Dan Sim, existe. . Dito isto, não há razão para não adotar nomes nesse meio tempo. É totalmente compatível com as convenções do Emacs; portanto, qualquer pacote que use Names é livre para parar de usar nomes a qualquer momento, e o usuário não saberá nada.
Malabarba 28/10
Você realmente deve adicionar namelessa esta lista :) É uma idéia brilhante e resolve o problema com muito cuidado.
Clément
22

Na última vez que isso foi discutido no emacs-devel, a discussão parou quando pessoas como Lars apontaram que gostariam de poder fazer M-x grepalgo. Adicionar namespaces ao Elisp não deve ser muito difícil, mas obter todas as ferramentas familiares para lidar com eles corretamente é outro problema.

Stefan
fonte
Eu acho que poderia ser facilmente 'fixo' através da criação de aliases para as funções comuns mais utilizados (ou todos eles, talvez)
Jesse
11
A necessidade de "grep" aparece normalmente durante o desenvolvimento de um pacote, onde você precisa saber onde uma variável / função pode ser usada em outros pacotes, para que possa ser aplicada a qualquer variável / função arbitrária, e não apenas a importantes. Por esse motivo, adicionar alguns aliases não fará diferença. Outra razão pela qual o mit não ajudará é que adicionar um alias não ajudará a encontrar os usos que não usam esse alias.
Stefan