O suporte a macros em uma linguagem de programação é considerado prejudicial?

8

O primeiro abuso que me vem à mente em C é:

#define if while 

Mas, ao mesmo tempo, é extremamente útil e poderoso quando usado corretamente.

Algo semelhante acontece com as macros Common Lisp.

Por que todas as linguagens de programação não suportam macros como esta e quais são as alternativas?

Eles são considerados prejudiciais?

OscarRyz
fonte
20
Facas são perigosas. Uma alternativa é tentar cortar as coisas com colheres.
Matt Ellen
1
@Matt ou para fornecer boas alças.
OscarRyz

Respostas:

15

Sou da opinião de que, se uma linguagem possui macros, ela deve ser uma parte bem planejada e integrante da linguagem e não do compilador .

Por exemplo, o sistema macro do Lisp é um recurso de linguagem integrada muito poderoso e está sujeito a todas as regras e regulamentos do próprio Lisp.

Por exemplo, o sistema de macro C / C ++ é separado da linguagem e incorporado ao compilador. O resultado é que você não está limitado às restrições do seu idioma e pode criar código inválido e redefinir palavras-chave específicas do idioma.

No final do dia, existem vários idiomas que não possuem recurso de macro - mas essas gorduras não perdem tanto. Tudo depende de quão expressiva é uma linguagem e se ela tem abordagens alternativas à metaprogramação. A metaprogramação é apenas uma maneira de garantir que, ao fazer X, X seja feito da mesma maneira em todo o aplicativo.

Berin Loritsch
fonte
4
Pior, o pré-processador C nem faz parte do compilador.
1
Qual é a diferença que você está tentando desenhar aqui entre "o idioma" e "o compilador"? O sistema de macros de C é definido no padrão de linguagem, as macros do Lisp são, de fato, expandidas pelo compilador Lisp, e qualquer implementação de linguagem é definida, quando tudo é dito e feito, pelo compilador e pelas bibliotecas padrão. Portanto, a frase "separado do idioma e incorporada ao compilador" não faz sentido. Talvez a distinção que você está procurando seja que as macros C sejam implementadas no front-end do compilador e as macros Lisp no back-end?
Mason Wheeler
A distinção tem a ver com a consistência da linguagem. Pense dessa maneira: você planeja ir para um país estrangeiro e precisa aprender a falar francês para ir a lugares e comprar comida. Ao lidar com a alfândega, você também prefere aprender sueco ou apenas lidar com o francês. As macros do pré-compilador C são sintática e gramaticalmente diferentes do padrão C. O desafio cognitivo é descobrir o que essa outra linguagem fará no seu programa C padrão. Em alguns casos, é fácil, mas vi frases de código inteiras como uma definição de macro. Agora depure.
Berin Loritsch
8

Macros C e macros Lisp são completamente diferentes. As macros C são expandidas usando a substituição de cadeias antes de qualquer outro processamento. As macros Lisp são expandidas após o texto de entrada ter sido analisado em uma árvore de sintaxe 1 e podem usar o idioma inteiro durante a expansão. Com as macros Lisp, você pode não apenas fazer coisas estúpidas #define begin {, como também pode definir suas próprias estruturas de controle e até preencher matrizes em tempo de compilação usando o código que desejar.

Uma razão para não incluir macros é que qualquer coisa mais complicada do que a simples substituição de cadeia de caracteres pode ser muito difícil de trabalhar em idiomas com sintaxe no estilo C. Outra reclamação sobre macros é que elas podem dificultar a leitura do código, o que pode ser verdadeiro se não for implementado com habilidade. Macros Lisp bem escritas podem realmente facilitar a leitura do código.

1, exceto para macros de leitura, que são expandidas durante o processo de criação da árvore de sintaxe.

Larry Coleman
fonte
2

Eu não acho que exista uma razão específica para que eles não sejam suportados em alguns idiomas, mesmo porque alguns diferenciam maiúsculas de minúsculas e outros não. Normalmente, não há uma razão real, apenas uma decisão que foi tomada.

MAS a razão pela qual eles não estão incluídos definitivamente não é segurança. o

#define X Y

A instrução altera todos os X para Y em tempo de compilação. Se você pode alterar as instruções #define, basta copiar / substituir a fonte que estava interessada em alterar e compilar novamente.

Mike M.
fonte