Você está lendo minha mente.
Quando fiz um curso de compilador, alguns anos atrás, descobri que se você pega um AST e o serializa, com notação de prefixo em vez da notação de infixo usual, e usa parênteses para delimitar instruções inteiras, você obtém o Lisp. Embora eu tenha aprendido sobre o Scheme (um dialeto do Lisp) em meus estudos de graduação, nunca havia realmente apreciado isso. Definitivamente, apreciei o Lisp e seus dialetos, como resultado desse curso.
Problemas com o que você propõe:
é difícil / lento compor um AST em um ambiente gráfico. Afinal, a maioria de nós pode digitar mais rápido do que mover um mouse. E, no entanto, uma pergunta emergente é "como você escreve código de programa com um tablet?" Digitar em um tablet é lento / complicado, comparado a um teclado / laptop com um teclado de hardware. Se você pudesse criar um AST arrastando e soltando componentes de uma paleta em uma tela em um grande dispositivo com tela de toque, a programação em um tablet pode se tornar algo real.
poucas / nenhuma de nossas ferramentas existentes suportam isso. Temos décadas de desenvolvimento envolvidos na criação de IDEs cada vez mais complexos e editores cada vez mais inteligentes. Temos todas essas ferramentas para reformatar o texto, comparar o texto, pesquisar o texto. Onde estão as ferramentas que podem fazer o equivalente a uma pesquisa de expressão regular em uma árvore? Ou um diff de duas árvores? Todas essas coisas são facilmente feitas com texto. Mas eles só podem comparar as palavras. Altere o nome de uma variável, de modo que as palavras sejam diferentes, mas o significado semântico seja o mesmo, e essas ferramentas de comparação enfrentam problemas. Essas ferramentas, desenvolvidas para operar em ASTs em vez de texto, permitiriam que você se aproximasse da comparação do significado semântico. Isso seria uma coisa boa.
Embora transformar código-fonte de programa em AST seja relativamente bem compreendido (temos compiladores e intérpretes, não é?), transformar um AST em código de programa não é tão bem-compreendido. Multiplicar dois números primos para obter um número composto grande é relativamente simples, mas fatorar um número composto grande novamente em números primos é muito mais difícil; é onde estamos com ASTs de análise versus descompilação. É aí que as diferenças entre os idiomas se tornam um problema. Mesmo em um idioma específico, há várias maneiras de descompilar um AST. Iterando através de uma coleção de objetos e obtendo algum tipo de resultado, por exemplo. Use um loop for, iterando através de uma matriz? Isso seria compacto e rápido, mas há limitações. Use um iterador de algum tipo, operando em uma coleção? Essa coleção pode ser de tamanho variável, o que adiciona flexibilidade às (possíveis) despesas de velocidade. Mapear / Reduzir? Mais complexo, mas implicitamente paralelelizável. E isso é apenas para Java, dependendo de suas preferências.
Com o tempo, o esforço de desenvolvimento será despendido e desenvolveremos usando telas sensíveis ao toque e ASTs. A digitação se tornará menos necessária. Vejo isso como uma progressão lógica de onde estamos, observando como usamos computadores hoje. Isso resolverá o problema nº 1.
Já estamos trabalhando com árvores. Lisp é apenas ASTs serializados. XML (e HTML, por extensão) é apenas uma árvore serializada. Para fazer a pesquisa, já temos alguns protótipos: XPath e CSS (para XML e HTML, respectivamente). Quando são criadas ferramentas gráficas que nos permitem criar seletores e modificadores no estilo CSS, teremos resolvido parte do número 2. Quando esses seletores puderem ser estendidos para suportar expressões regulares, estaremos mais próximos. Ainda está procurando uma boa ferramenta gráfica de comparação para comparar dois documentos XML ou HTML. À medida que as pessoas desenvolvem essas ferramentas, o número 2 será resolvido. As pessoas já estão trabalhando nessas coisas; eles simplesmente não estão lá ainda.
A única maneira que vejo de poder descompilar esses ASTs para o texto da linguagem de programação seria algo em busca de objetivos. Se eu estiver modificando o código existente, o objetivo poderá ser alcançado por um algoritmo que torne o código modificado o mais semelhante possível ao código inicial (diferença textual mínima). Se estou escrevendo um código do zero, o objetivo pode ser o menor e mais apertado (provavelmente um loop for). Ou pode ser um código paralelo da maneira mais eficiente possível (provavelmente um mapa / redução ou algo que envolva CSP). Portanto, o mesmo AST pode resultar em código significativamente diferente, mesmo no mesmo idioma, com base em como os objetivos foram definidos. O desenvolvimento de um sistema desse tipo resolveria o problema nº 3. Seria computacionalmente complexo, o que significa que provavelmente precisaríamos de algum tipo de acordo cliente-servidor,