Vantagens e desvantagens de estruturar todo o código por meio de classes e compilar para classes (como Java)

13

Edit: minha linguagem permite herança múltipla, diferente do Java.

Comecei a projetar e desenvolver minha própria linguagem de programação para fins educacionais, recreativos e potencialmente úteis.

No começo, eu decidi basear isso em Java.

Isso implicava que todo o código seria gravado na forma de classes e esse código seria compilado em classes, carregadas pela VM.

No entanto, excluí recursos como interfaces e classes abstratas, porque não encontrei necessidade deles. Eles pareciam estar aplicando um paradigma, e eu gostaria que minha linguagem não fizesse isso. Eu queria manter as aulas como a unidade de compilação, porque parecia conveniente implementar, familiar, e eu apenas gostei da ideia.

Então notei que, basicamente, me resta um sistema de módulos, onde as classes podem ser usadas como "namespaces", fornecendo constantes e funções usando a staticdiretiva ou como modelos para objetos que precisam ser instanciados (finalidade "real" das classes) em outros idiomas).

Agora fico pensando: quais são as vantagens e desvantagens de ter classes como unidades de compilação?

Além disso, qualquer comentário geral sobre o meu design seria muito apreciado. Um post informativo no meu idioma pode ser encontrado aqui: http://www.yannbane.com/2012/12/kava.html .

jcora
fonte
1
Se as classes também incluírem namespaces que desambiguem todos os identificadores da classe, você terá uma unidade de compilação completamente independente. Essa classe pode ser compilada com êxito, desde que todas as dependências de outras classes possam ser satisfeitas por compilação ou por referência a uma classe compilada em um assembly. Essa atomicidade deve ter vantagens óbvias.
Robert Harvey
Nota lateral: se você remover classes e interfaces abstratas, estará forçando as pessoas a usar a herança para subtipagem e polimorfismo. Isso está destinado a produzir código horrível. Além disso, a menos que você adicione herança múltipla (e lide com os problemas associados), ela é incrivelmente restrita.
1
@ delnan: Na verdade, você ainda pode usar a composição para criar funcionalidade.
Robert Harvey
2
@RobertHarvey Suponho que você esteja falando de restrições por falta de herança múltipla. Sim, pode-se emular com composição suficiente, mas eu dificilmente consideraria aceitável. Por exemplo, um objeto que normalmente implementaria duas interfaces teria que ser implementado duas vezes, em subclasses de classes base distintas (e, embora ambas as implementações possam delegar para uma classe comum, isso ainda é uma merda de código extra e você não pode ativar facilmente uma instância de uma em uma instância da outra).
@ delnan: O que há de errado em usar herança para subtipagem e polimorfismo? Isso é o que a herança é para ...
Mason Wheeler

Respostas:

6

quais são os benefícios de ter aulas como unidades de compilação?

Pode reduzir a complexidade do idioma. Não há necessidade de construções diferentes, tudo é tratado da mesma maneira. Em certos designs (embora não seja o seu, ao que parece), você se beneficia por não ter estática e os problemas de design com os quais eles costumam se deparar (problemas de ordem de inicialização, limitações de simultaneidade, constrangimento com classes de tipos / genéricos). Ele também permite alguns benefícios do conceito de módulo, como instâncias de módulo isoladas para sandboxing ou paralelização; e digitação de módulos, onde as dependências se encaixam em alguma interface e todo o módulo de implementação pode ser instanciado e inserido.

Dito isto, o conceito tende a ter mais problemas do que não. Realisticamente, você não pode tratar tudo da mesma forma, uma vez que as classes de 'nível superior' precisam de regras especiais, como ter um construtor padrão (ou então você se depara com problemas estranhos que os transformam). A modularidade das unidades de compilação também tende a ficar realmente estranha. Como uma classe faz referência a outras quando são apenas classes? Como essas dependências são tratadas e como você determina a ordem correta para ativar as classes? Como você garante que as referências de classe duplicadas sejam reutilizadas por diferentes partes do aplicativo (ou como você lida com instâncias duplicadas se essa é a semântica que você deseja)?

Tendo analisado, encontrei muitos problemas com dependências, definição correta do escopo e preocupações com a inicialização. Você acaba se deparando com problemas que tornam as 'classes de nível superior' especiais, e com muitas limitações para fazê-las funcionar e acabam moldando-as em espaços de nomes simples.

Telastyn
fonte
Eu pretendo apenas ter uma única classe de nível superior, a Object. Percebo que provavelmente vou precisar de algum comportamento especial para isso, mas, desde que seja um caso isolado, estou bem com isso. Eu não acredito que terei problemas de dependência. Há um conjunto de classes que são carregadas quando a VM é iniciada, algumas delas são implementadas nativamente (a classe System), mas todas elas herdam do Object. Depois que tudo é carregado, o KVM carrega a classe que foi instruída a carregar e elabora as dependências. No entanto, estou interessado em quais problemas a estática introduz?
Jcora
@yannbane - não quero dizer object, quero dizer classes que se comportam como módulos, em vez de classes internas que não são necessariamente públicas fora de sua unidade de compilação. 'Elabora as dependências' se transforma em um ninho de vespas gigantes nos detalhes, se você deseja algum tipo de comportamento no estilo DLL; ymmv. Quanto a estática .
Telastyn
Esse comportamento tipo módulo seria alcançado através do uso de métodos / variáveis ​​estáticas, certo? É ruim, em vez de criar uma classe que possa ser instanciada, criar uma classe que tenha apenas membros e métodos estáticos? Vi esse artigo, no entanto, acho que não se aplica a membros estáticos constantes , nem a métodos estáticos. Por exemplo, não vejo nada de errado na criação de uma Mathclasse, que na verdade é um módulo com métodos estáticos e um membro duplo estático constante chamado Pi.
Jcora
@yannbane - Não, na verdade não. Módulos são módulos porque são instantâneos. Caso contrário, você apenas terá namespaces no estilo C ++. Depois de limitar as classes de nível superior aos namespaces no estilo C ++, elas não são mais classes.
Telastyn
Ainda estou bem e realmente não vejo o problema de criar módulos com classes. E sim, os módulos agem como espaços de nome, especialmente módulos Python.
Jcora #
4

Em vez de responder a essa pergunta, vou subir um nível e sugerir o estudo do MIT OpenCourseWare , particularmente 6.035 (Engenharia de linguagem de computador). Isso explicará toda a problemática, para que você não fique tentado a fazer perguntas como essa novamente.

Engenharia de Linguagem de Computadores

O único pré-requisito é Java.

http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-035-computer-language-engineering-spring-2010/lecture-notes/

Descrição do Curso

Este curso analisa questões associadas à implementação de linguagens de programação de nível superior. Os tópicos abordados incluem: conceitos fundamentais, funções e estruturas de compiladores, a interação da teoria e da prática e o uso de ferramentas na construção de software. O curso inclui um projeto para várias pessoas sobre o design e a implementação do compilador.

mosquito
fonte