Como você projetaria uma linguagem de programação? [fechadas]

41

Se você projetasse uma linguagem de programação, como faria isso? Quais recursos você colocaria? O que você deixaria de fora? Estática ou dinamicamente digitada? Tipo forte ou fraco? Compilado ou interpretado? Justifique suas respostas.

Chinmay Kanchi
fonte
12
Esta pergunta é muito vaga. Os recursos do idioma não podem ser discutidos até que o objetivo do idioma seja determinado.
blucz
1
Se você pode votar e achar que essa é uma pergunta útil ou que possui respostas úteis abaixo, vote. Os sites StackExchange precisam de votos para criar uma boa comunidade. Você pode dar 30 votos por dia, não os desperdice. Especialmente usuários com alta reputação e baixa contagem de votos dados, por favor leia isto: meta.programmers.stackexchange.com/questions/393/…
Maniero
3
Eu criaria uma linguagem de alto nível com um método: public void DoWhatIMeant ();
Dave
6
a linguagem de programação ideal? ... Eu faria o compilador ler minha mente e gerar um programa exatamente como eu quero .. :) pode demorar um pouco, mas valeria a pena.
WalterJ89
2
Compilação e interpretação são características de ... bem, o compilador ou intérprete (duh), não o idioma. Todos os idiomas podem ser implementados por um compilador ou intérprete. E, de fato, praticamente todos eles são. Há compiladores para Ruby, Python, ECMAScript, PHP, existem intérpretes para C, C ++, Java, Haskell, ...
Jörg W Mittag

Respostas:

55
  • Definitivamente, acho que as linguagens de programação funcionais continuarão, então minha linguagem será funcional. Consulte Domesticando efeitos com programação funcional

  • Acho que as CPUs em breve terão centenas de núcleos, e os threads serão um inferno para gerenciar. Portanto, o modelo do ator é uma obrigação, em vez de threads. Veja Erlang - software para um mundo simultâneo

  • Eu também acho que OOP falhou, a comunicação entre objetos foi assumida como assíncrona . Então, acho que precisamos passar mensagens , com mensagens imutáveis. Envie e esqueça. Como no modelo do ator. Consulte Programação orientada a objetos: o caminho errado?

  • Eu acho que seria bom ter uma digitação estática , para que os erros sejam detectados no início do ciclo de desenvolvimento. Mas eu usaria a inferência de tipo como em Haskell, para que o desenvolvedor não precise escrever o tipo em qualquer lugar do código, como em C, C # e Java. Veja Aprenda um Haskell para um grande bem

  • Eu também projetaria uma ótima biblioteca de interface do usuário , com layout declarativo , como no WPF e no Android. Mas eu gostaria de tê-lo como na Programação Reativa Funcional .

Portanto, minha linguagem seria semelhante à concorrência em Erlang, mas com a digitação como em Haskell e uma estrutura de GUI como no WPF.NET.

Jonas
fonte
4
soa como Scala, na verdade, exceto talvez a grande biblioteca de UI.
Ape-inago
Eu pensei que scala tinha mensagens e atores. Acho que não sei como isso se relaciona com o POO.
Ape-inago
@ Jonas: parece ótimo :) Eu não sei muito sobre o modelo de ator, é semelhante ao que Go fez com as goroutines?
Matthieu M.
1
A única coisa que eu sou cético é com a digitação estática. Definitivamente, prefiro digitação forte em vez de fraca, mas às vezes a digitação estática é muito restritiva. Mas eu não estou familiarizado com Haskell, e tenho ouvido apenas coisas boas sobre o seu sistema de digitação :)
sakisk
1
O fracasso da OOP, francamente, é que quase nenhuma linguagem "orientada a objetos" realmente a implementa . Mais simplesmente, calce um modelo de objeto para uma linguagem processual e chame-a de dia. Eu gostaria que o Smalltalk entendesse mais a si mesmo, em vez de pedir a todos os que estão na linguagem processual que dissessem "Eh, nós podemos fazer algo meio que talvez isso" e conseguir perder completamente o objetivo da OOP.
cHao
22

Nota: usei a sintaxe do tipo C para descrever os recursos deste post, mas não sou exigente quanto à sintaxe, desde que não seja algo ridículo, como todas as palavras-chave que são CAPS.

1. Sistema de digitação

O recurso número um que eu gostaria em um idioma é a digitação estática com a digitação dinâmica opcional . O motivo é que a digitação estática permite: a) detectar erros mais cedo do que tarde eb) a maioria dos códigos são implicitamente digitados estaticamente, independentemente de o idioma fazer ou não a distinção. No entanto, existem vários casos de uso em que a digitação dinâmica é extremamente útil. Por exemplo, ao ler dados de um arquivo, você costuma ter campos de tipos variados, e a digitação dinâmica facilita os contêineres heterogêneos. Então, minha linguagem ideal teria algo assim:

//variable declarations
int anInt = 42 //anInt is now irrevocably an integer and assigning another type to it is an error
vartype aVariable = 42 //aVariable is currently an integer, but any type can be assigned to it in the future

//function definitions
int countElements(Collection c)
{
  return c.count();
} 

//c HAS to be a collection, since countElements doesn't make sense otherwise

void addToCollection(Collection& c, vartype v) 
{
  c.append(v)
}

//c is passed by reference here

2. Compilado vs. Interpretado

Eu gostaria que o idioma fosse compilado com antecedência ou JIT, mas não puramente interpretado, sendo a velocidade a razão. Isso está relacionado ao ponto 1 , já que um compilador / jitter otimizando terá muito mais facilidade para otimizar o código digitado estaticamente, e o código digitado dinamicamente pode simplesmente ser deixado como está.

3. Encerramentos

A linguagem deve suportar construções de programação funcional e as funções devem ser objetos de primeira classe.

4. Orientado a objetos

A linguagem deve permitir que você escreva código orientado a objetos, mas também deve ser permitido um código imperativo simples. ou seja, deve ser possível escrever um programa Olá Mundo como este:

int main(string<> args=null)
{
  printf("hello, world"); 
  return 0;
}

// this code also demonstrates two other features,
// default arguments for functions (not explained further)
// and immutable lists like string<> (see 6. Built-in datatypes)

5. Namespaces

Namespaces são uma coisa boa. Muito pouca coisa deve ser inserida no espaço de nomes global. Mas se você precisar colocar coisas no espaço de nomes global, poderá (ala C ++).

6. Tipos de dados internos

O idioma deve ter, como tipos de dados internos, as seguintes construções:

  • Um inttipo de dados ou tipos. Se houver apenas um inttipo, ele deverá ter alcance ilimitado. Se houver mais, deve haver upcasting implícito no menor tipo capaz de conter o resultado de uma computação, sendo o tipo de alcance ilimitado o maior.
  • Um único floattipo binário interno, equivalente a um IEEE 754double
  • Um listtipo mutável que é implementado como uma lista duplamente vinculada ou como um bloco de memória contígua contendo ponteiros para cada elemento
  • Um listtipo imutável que age como uma matriz, mas cujo tamanho não pode ser alterado após a criação
  • stringTipos mutáveis ​​e imutáveis , com o padrão imutável.
  • Um tipo mapou dictque é mutável e contém chaves imutáveis ​​e valores mutáveis ​​e / ou imutáveis.
  • Os tipos de coleção internos devem ser digitados de maneira homogênea por padrão, mas podem ser vartyped, se necessário
  • Um booleantipo
  • Um nullou nonetipo que pode ser atribuído a uma variável de qualquer tipo.
  • setTipos mutáveis ​​e imutáveis
  • Um decimaltipo que implementa variáveis ​​decimais de ponto flutuante
  • Um fixedtipo que implementa um número de ponto fixo

Os tipos decimal, floate fixeddevem compartilhar exatamente a mesma interface pública (via herança ou digitação de pato), permitindo que sejam passados ​​e retornados de forma transparente a partir de funções. O tipo pai pode ser chamado real.

7. Chamada por valor e por referência

Você deve ser capaz de chamar funções por valor e referência, com o valor padrão (ou seja, uma cópia do argumento é feita e operada na função).

8. Ponteiros

O idioma deve ter ponteiros e permitir aritmética do ponteiro. Os ponteiros só podem ser digitados estaticamente (para evitar o pesadelo que é a void*). vartypeponteiros são explicitamente proibidos. Ter ponteiros e aritmética de ponteiros permite que a linguagem seja seriamente usada como linguagem de programação de sistemas.

9. Montagem em linha

Em conexão com 8. , o idioma deve permitir o código da linguagem assembly em linha para as situações em que é necessário.

10. Segurança

O idioma deve ser mais seguro de usar, suportando o tratamento de exceções etc. A montagem aritmética e embutida do ponteiro pode ser relegada para partes do código explicitamente marcadas como inseguras. Código inseguro é permitido, mas fortemente desencorajado.

11. Comportamento indefinido

O padrão da linguagem deve especificar como o programa deve se comportar em todas as circunstâncias, exceto no código explicitamente marcado como inseguro, ou seja, não deve haver comportamento indefinido fora dos blocos inseguros. Isso permite que o idioma seja usado como um idioma viável de desenvolvimento de aplicativos, enquanto ainda permite que você diga, escreva um sistema operacional nele.

É tudo o que consigo pensar no momento, mas vou editar / atualizar o post à medida que penso em mais coisas.

Chinmay Kanchi
fonte
5
Dê uma olhada em "Linguagem de programação D": digitalmars.com/d
Wizard79
Tanto quanto me lembro, D não tem digitação dinâmica opcional ou um número inteiro de intervalo ilimitado embutido. O tipo inteiro não é um problema, mas a falta de digitação dinâmica opcional o torna bastante pouco atraente.
Chinmay Kanchi
1
Eu realmente adicionaria um decimaltipo aqui.
configurator
3
“Um tipo nulo ou nenhum que pode ser atribuído a uma variável de qualquer tipo.” - Incluindo booleano? :-p
Timwi
1
Não vejo "flexível" na postagem original. O Assembline Inline não me veio à mente como requisito principal para uma linguagem de programação. Talvez isso esteja de acordo com Felix von Leitner hoje em dia, ao escrever o Assembler na maioria das vezes, você obtém resultados incorretos lentos.
LennyProgrammers
7

É assim que minha linguagem de programação dos sonhos se pareceria:

  • Um poderoso sistema de tipo estático com algum suporte para digitação dependente.
  • Digitação dinâmica opcional.
  • Torre numérica à la Lisp, mas digitada estaticamente.
  • Macros à la Lisp.
  • Principalmente uma linguagem de programação funcional com suporte básico para programação imperativa (como a família ML).
  • Coleta de lixo.
  • Inferência de tipo.
  • Continuações.
  • Semântica lenta opcional.
  • Todas as construções de controle seriam fornecidas na forma de funções da biblioteca. (Isso pode ser possível usando os dois últimos recursos.)
  • Sintaxe mínima (não tão pequena quanto Lisps, mas algo do tipo Ioke / Seph.)
desaparecido
fonte
Parece bom. Eu realmente não vi uma boa maneira de fazer macros estaticamente seguras para tipos.
Jörg W Mittag
@ Jörg: Nemerle?
missingfaktor
No Smalltalk, todas as estruturas de controle são, na verdade, métodos, e não usa continuações em sua implementação. Um não é necessário para o outro.
Carvalho
@ Oak, você pode implementar o Python yieldno Smalltalk? Deve ser o mais limpo possível de usar.
precisa saber é o seguinte
Um mecanismo semelhante ao rendimento já está implementado no smalltalk como um método de biblioteca, sem continuações.
carvalho
6

Eu o teria projetado praticamente como C #, mas a Microsoft me superou. :)

(Exceto, é claro, que o meu teria sido menos bem pensado e mais amador.)

Não me importo muito se é compilado ou interpretado, então não preciso justificar isso.

No que diz respeito à tipagem estática forte, acho difícil entender por que isso exige justificativa. A digitação estática é um recurso que captura bugs durante o tempo de compilação. A digitação dinâmica é a falta desse recurso e adia os bugs até o tempo de execução. Na minha experiência pessoal, eu tinha poucos casos de uso em que o despacho dinâmico fazia sentido e era útil; portanto, as convoluções que tive que passar em C # antes do 4.0 para obtê-lo eram facilmente justificadas. Com o C # 4.0, nem preciso mais justificar isso, porque temos despacho dinâmico agora.

No entanto, eu provavelmente teria criado uma nova sintaxe em vez de aderir tão religiosamente à sintaxe C antiga quanto o C #. A declaração switch é particularmente horrível e também não gosto da sintaxe do elenco (é o contrário). Porém, não faço muita barulho quanto aos detalhes da sintaxe, então não preciso justificá-la em detalhes, exceto que não a quero tão detalhada quanto o Visual Basic.

O que mais você gostaria que eu justificasse?

Timwi
fonte
+1 boa resposta! Vou postar um dos meus mais tarde também.
Chinmay Kanchi
4
C # é uma linguagem poderosa, mas a sintaxe geralmente é confusa. Eu acho que isso ocorre porque muitos desses recursos não estavam no design original.
Casebash 02/09/10
Daí "4.0", eu acho.
Mark C
5

Bem, aqui está uma lista de recursos que eu colocaria:


Sintaxe como Lisp

Estilo Lisp

Prós :

  • Sintaxe facilmente extensível. Já tentou implementar um loop foreach em C? Não é exatamente fácil. (Veja bem, eu já fiz ).
  • Homoiconicidade. Você pode simplesmente(eval "your data files")

Contras :

  • A notação polida aninhada geralmente é difícil de ler

Programação Funcional

Estilo Haskell

Prós :

  • Simultaneidade fácil, todo o código é seguro para threads.

Contras :

  • Difícil de implementar efeitos colaterais em código funcional puro, embora as mônadas pareçam fazer um bom trabalho.

Digitação dinâmica forte

Estilo Python

Prós :

  • A digitação dinâmica torna o código legível limpo, a digitação forte pode eliminar erros de digitação

Implementação :

Permitir sobrecarga de função com base em tipos, semelhantes aos CLs defgeneric:

(define (+ (a <int>) (b <int>))
  (ints-add a b))

(define (+ (a <string>) (b <string>))
  (string-concat a b))

(define (+ a b)
  (add-generic a b))

Compilável e Interpretável

Prós :

  • Aumento de desempenho se compilado (geralmente verdadeiro, nem sempre)

Contras :

  • Pode limitar recursos no idioma, mas o llvm seria um bom suporte.

Programação de sistemas

Estilo C

Prós :

  • Apela a uma gama muito pequena de usuários.
  • Mais fácil para aplicativos, kernel e drivers de dispositivo interagirem se todos estiverem escritos no mesmo idioma

Contras :

  • Limita as abstrações no idioma; a digitação dinâmica geralmente não é adequada.

Macros higiênicas (estilo CL e estilo Scheme)

Prós :

  • Fácil de estender o idioma, especialmente com a sintaxe Lispy ™
  • Eu já disse isso antes, não disse?

Contras :

  • Poucos se forem feitos com a sintaxe Lispy ™

Pensando bem, esse esquema define mais ou menos, exceto o bit de compilação e programação de sistemas. Isso pode ser contornado usando libguile e escrevendo esses bits em C.

Joe D
fonte
1
Dê uma olhada em Ioke e Seph. É incrível a facilidade de leitura de uma linguagem com mais facilidade, adicionando apenas uma quantidade pequenina de sintaxe, em comparação com as Expressões S, e ainda tendo todos os recursos macro. (Basicamente, em vez de "toda chamada de função é uma lista e as listas são de primeira classe", é "tudo é um envio de mensagens e as cadeias de mensagens são de primeira classe". Em vez de uma lista cuja carfunção e cdrargumento são, você tem um objeto cujo namecampo é o método e cujo argumentscampo é os argumentos e em vez de nidificação, você tem. preve nextponteiro campos).
Jörg W Mittag
Sons muito bonito exatamente como Clojure (supondo que você use Mjolnir para generaltion código nativo em LLVM para os sistemas de Programação de peças - github.com/halgari/mjolnir )
mikera
3

Existem vários idiomas por aí que considero muito bons (C # é o meu favorito atual). Como essa é a minha linguagem de fantasia, eis o que eu realmente quero:

  • Documentação oficial da API da Kick-ass. A API Java é boa assim, e C # /. NET é muito bom. Ruby / Rails é bastante terrível aqui.
  • Documentação geral oficial do Kick-ass (instruções, usos comuns, muitos exemplos de código). C # /. Net é bom para isso.
  • Uma enorme comunidade de documentadores baseados em blogs e solucionadores de problemas do StackOverflow para me ajudar a superar dificuldades
  • Uma ampla variedade de plugins / bibliotecas / extensões bem suportados, bem documentados e poderosos (o Ruby / Rails tem 'poderoso', mas nenhum dos outros dois).
  • É razoavelmente estável - não é possível alterar tudo para quebrar a maioria dos códigos existentes anualmente (olhando para você, Ruby / Rails).
  • Não é muito estável - é capaz de se adaptar aos avanços no design da linguagem (olhando para você, c ++)
Fishtoaster
fonte
2
Os pontos de "documentação de pontapé de saída" devem incluir PHP: D
Corey
3

Dicas do compilador

Estou falando mal de mim porque não sei muito sobre design de linguagem, mas acho que o recurso de que estou falando se chama dicas em outros idiomas. Dicas do compilador , talvez?

Não sei se li isso em um rascunho do Perl6 ou estava alto na época, mas imagino uma linguagem em que tudo, por padrão, é frouxo e auto-mágico. Mas se você realmente deseja aumentar o desempenho e dizer, ei, esse valor é sempre um número inteiro ou nunca é nulo, ou pode ser paralelo, ou sem estado, coisas assim ... Que o compilador poderia ir automaticamente à cidade nessas áreas especificamente marcadas.

E: Eu apreciaria comentários esclarecendo o que estou pedindo ou citando exemplos onde isso já existe.

Mark Canlas
fonte
1
Você pode fazer isso no Common Lisp. Por exemplo, você pode dizer ao compilador que i é um número inteiro de tamanho razoável. Uma coisa útil é que, variando os valores safetye speed, é possível que o compilador verifique e imponha (para encontrar problemas) ou assuma que o que você diz é verdadeiro (e compile um código mais rápido).
David Thornley
2

Para experimentar novas idéias:

Eu criaria uma linguagem de programação funcional de tipo dinâmico, que permite executar todos os truques de expressão de instrução e a sintaxe lambda mais simples com correspondência de padrões. Regra externa ativada.

// a view pattern (or Active Pattern in F#)
default = \def val: !!val.Type val def

// usage of the pattern
greet = \name<(default "world") `and` hasType Str>:
  p "Hello, \{name}!"

(p "Enter your name", .input).greet // (, ) is a sequence expression, returning the last value

Aqui está uma explicação:

default =define o armazenamento, \def valcomeça uma função de avaliar num com dois argumentos, val.Typeé o mesmo que Type[val], !!convertidos para booleano, e booleano pode ser aplicado, por isso, valedef are after it.

f x= f[x]= x.f .f=f[]

e em greet, usado name<(default "world")e hasType Str>, significa que o padrão default "world"será usado e vinculado name. O padrão padrão especifica um valor padrão. andé outro padrão que une dois padrões. o defaultpadrão não pode falhar enquanto hasTypepode falhar. Nesse caso, lança uma exceção.

As variáveis ​​são, na verdade, armazenamentos, que podem ser passados ​​funcionalmente, e as tabelas de armazenamento podem ser referências, criadas e destruídas à medida que os escopos são alterados.

Hashes e similares serão como em Lua e JavaScript.

Se eu vou criar uma linguagem compilada, vou criar um F # para Java, com recursos do tipo Haskell. É uma linguagem funcional pura, exceto que existe um recurso que combina Cotações e Comp Exprs para obter uma programação imperativa, escrevendo blocos semelhantes a pseudocódigo.

Ming-Tang
fonte
1
Parece um pouco com o Erlang, uma linguagem de programação funcional de tipo dinâmico e adicionada a isso uma linguagem simultânea bastante singular.
Jonas
2

Tendo em mente que as únicas linguagens que conheço são PHP e javascript, e que realmente devo aprender mais algumas antes de criar uma linguagem:

Sintaxe: Pense cuidadosamente nos nomes das funções e na ordem dos argumentos (ou seja, seja menos confuso que o PHP).

Recursos: Possui um conjunto de stringfunções, que operam em variáveis ​​como uma série de bytes, mas não entendem o texto, e um conjunto de textfunções, que entendem muitas codificações e podem operar no UTF-8 e em outras seqüências de vários bytes. (E possui verificações de integridade de codificação incorporadas ao idioma, com uma função como a text.isValidEncoding(text, encoding)que informa se uma sequência de bytes está malformada e insegura para ser tratada como texto.

Acho que gosto da ideia de digitação estática forte, mas nunca a usei, por isso não posso dizer.

TRiG
fonte
2

Antes de projetar uma linguagem de programação, eu encontraria uma boa resposta para a pergunta: por que precisamos de outra linguagem de programação? O Código Rosetta no momento da redação deste artigo lista 344 idiomas. Se nenhum deles atendesse às minhas necessidades, os detalhes específicos do motivo pelo qual eles não determinariam o ponto de partida (os idiomas mais próximos) e o que seria adicionado a ele.

Se eu ganhasse na loteria e, por algum motivo, não tivesse nada melhor para fazer, começaria com Liskell e a tornaria uma linguagem completa em oposição a um front-end do GHC, depois tornaria a FFI mais fácil (e automatizada) para que eu pudesse usar qualquer Biblioteca C / C ++.

Larry Coleman
fonte
2

Uma boa língua é uma linguagem que é:

  • fácil de raciocinar (sem sintaxe obscura)
  • deixe você expressar suas idéias com o mínimo de distorção
  • ocultar os detalhes essenciais de você (otimização / gerenciamento de recursos)
  • facilmente paralelizável (múltiplos núcleos, computação distribuída)

É muito difícil transformar isso em uma lista de recursos, mas acho que a Programação Funcional, apesar de não parecer natural , está mais próxima disso do que a programação imperativa (especialmente para esconder os detalhes minuciosos)

  • Interface C: C é a língua franca das linguagens de programação e o número de bibliotecas desenvolvidas em C é incrível. Por ter uma interface fácil (como Python) para C, a linguagem se beneficia automaticamente de todas essas bibliotecas e também permite enviar tarefas pesadas que não puderam ser otimizadas o suficiente para uma linguagem próxima à metal.
  • Distribuído : eu gosto da versão do Go no multi-threading, com rotinas leves que o tempo de execução despacha em threads, dependendo de sua atividade. Essa linguagem incentiva o programador a raciocinar sobre tarefas e isolá-las umas das outras.
  • Coleta de Lixo : escusado será dizer hoje em dia;)
  • Imutável : muito mais fácil de raciocinar sobre algo que nunca pode sofrer mutação, muito mais fácil de implementar computação multithreading / distribuída (você só precisa de sincronização para lidar com a vida útil, que é a tarefa do compilador)
  • Lambdas : combina com funções de primeira classe, eu acho
  • Message Passing : imutabilidade não significa mutex, portanto seguimos a sugestão de Tony Hoares
  • Módulos : um pouco semelhantes aos namespaces, mas com melhor encapsulamento
  • Reflexão : a computação distribuída requer serialização, que deve ser deixada para o compilador, e a desserialização é mais facilmente alcançada com alguma forma de reflexão.
  • Static Strong Typing : quanto mais cedo um erro for detectado, menor será o custo

No momento, o idioma mais próximo dessa lista é provavelmente Haskell, no entanto:

  • ela não tem rotinas: Eu não vi um naturais maneira de expressar o paralelismo em Haskell ainda (embora possa ser minha ignorância ...)
  • tem uma sintaxe obscura: de alguma forma, parece que os programadores Haskell prosperam usando operadores estranhos em vez de palavras. Pode parecer liso, mas não ajuda muito a entender o que está acontecendo.
Matthieu M.
fonte
2

Para sua primeira pergunta, "como você faria isso" - resposta curta, eu não faria. Não tenho a teoria do analisador / compilador suficiente para fazer isso. Mas como programa há 25 anos, tenho algumas idéias e opiniões para compartilhar.

Primeiramente, eu tentaria criar uma abordagem OOP que permita criar modelos verdadeiramente conectados. O que quero dizer com isso é que os modelos são uma das coisas mais importantes em quase qualquer tipo de projeto de programação - é sempre muito trabalhoso e refatoração contínua para fazer o que é certo, e eu culpo isso por falta de conectividade real. Idiomas OO.

Permita-me demonstrar. Digamos que uma classe House tenha uma propriedade Door.

var door = house.Door;

Agora você tem uma variável local com uma referência à instância do Door.

Mas considere o que acabou de acontecer: você acabou de arrancar a porta da casa e agora está muito feliz passando a porta, e o resto do seu código ignora o fato de que essa porta está realmente conectada a uma casa.

Para mim, isso é fundamentalmente errado.

E sim, eu sei, isso é "facilmente" corrigido caso a caso - nesse caso, mantendo uma referência inversa de cada Porta da Casa à qual ela está atualmente conectada. É claro que isso abre seu modelo para erros, já que agora é seu dever manter com precisão duas referências reversas, para que você torne as propriedades House.Doors e Door.House privadas e adicione métodos como House.AddDoor (), House.RemoveDoor ( ), Door.SetHouse () etc., conecte tudo e teste-a para garantir que realmente funcione.

Isso não está começando a parecer muito trabalho para modelar um relacionamento tão direto? Muito código para manter? Muito código para refatorar à medida que o modelo evolui?

O problema é ponteiros. Toda linguagem OO que eu já vi inerentemente sofre com o fato de uma referência a objeto ser realmente um ponteiro, porque é isso que os computadores usam.

Ponteiros não são uma boa maneira de modelar o mundo real. Independentemente do mundo que você está tentando modelar, é quase garantido que qualquer relacionamento nesse mundo será de mão dupla. Os ponteiros apontam apenas em uma direção.

Eu gostaria de ver uma linguagem em que o modelo de dados fundamental seja um gráfico - em que todos os relacionamentos, por padrão, tenham duas extremidades. Isso certamente forneceria um ajuste muito mais natural para modelar o mundo real, que é realmente a única coisa para a qual precisamos de computadores. (isso e videogames.)

Não tenho idéia de como seria a sintaxe para uma linguagem como essa, ou se ela pode ser expressamente concebida usando texto. (Eu me perguntei se essa linguagem teria que ser gráfica, de alguma forma ...)

Eu também gostaria de ver todas as formas de estado acidental eliminadas.

Por exemplo, no desenvolvimento da Web, gastamos muito tempo moldando dados de bancos de dados, modelos de negócios, modelos de exibição para apresentação ... então alguns desses dados são apresentados em formulários, o que é realmente apenas outra transformação. .. e state volta das postagens de formulário e, em seguida, remodelamos esses dados e os projetamos de volta no modelo de exibição, por exemplo, ligadores de modelo de exibição e outros ... então projetamos do modelo de exibição de volta para o modelo de negócios model ... então usamos mapeadores objeto-relacionais (ou trabalho pesado) para transformar os dados do modelo de visualização e projetá-los em um banco de dados relacional ...

Isso está começando a parecer redundante? Em que ponto, durante toda essa loucura, realizamos alguma coisa útil? Por útil, quero dizer, algo tangível - algo que o usuário final possa entender e se importar. No final do dia, as horas que você passou construindo algo que os usuários podem entender são realmente as únicas horas bem gastas. Tudo o resto é efeitos colaterais.

Eu gostaria de uma linguagem altamente dinâmica. O ciclo de gravação / compilação / execução é um desperdício de tempo tedioso. Idealmente, o idioma deve apenas descobrir o que mudou e compilar / carregar de forma transparente, em segundo plano, conforme necessário.

Idealmente, você nem precisa pressionar "executar" - as coisas devem acontecer na tela, conforme você faz as alterações, refletindo imediatamente as alterações feitas. O problema com o ciclo de gravação / compilação / execução, ou mesmo o ciclo de gravação / execução mais direto, é que você está muito desconectado do que está fazendo - para se sentir conectado ao nosso trabalho, nós precisa de feedback imediato, resultados instantâneos. Qualquer espera é muito longa!

Novamente, nem sei se isso pode ser conseguido com um IDE tradicional ou se isso exigiria um tipo de interface totalmente novo.

Você poderá usar uma combinação de digitação fraca e forte, o que for mais adequado para o problema em que está trabalhando.

Estado em geral deve ser algo que o idioma gerencia totalmente para você. Por que você precisa confiar em um banco de dados para persistência? Idealmente, eu gostaria de poder simplesmente especificar o tempo de vida de qualquer variável no modelo: uma solicitação da Web, uma sessão, 24 horas, permanentemente.

Por que temos que escolher entre toda uma gama de soluções de armazenamento para diferentes mídias e condições de vida? - sem mencionar a transformação e modelagem dos dados para caber em cada mídia; cache do navegador, banco de dados, memória, disco, quem se importa! Dados são dados. Onde você armazena seus dados (e por quanto tempo) deve ser uma escolha simples, não uma batalha contra os deuses!

Bem, boa sorte com isso.

mindplay.dk
fonte
1

Provavelmente seria uma linguagem de paradigmas múltiplos, suportando o seguinte:

  • Programação estruturada / processual
  • Programação orientada a objetos
  • Programação funcional

Por que esses? Orientado a objetos, porque é uma ótima maneira de organizar grandes programas, especialmente para organizar os dados. Estruturado porque você nem sempre quer / precisa disso (OOP), as pessoas devem ter escolha. Funcional porque facilita a depuração de programadores e torna os programas mais claros.

Eu usaria o modelo do Python com blocos recuados para marcar blocos de código. É muito agradável e agradável de ler.

Eu roubaria muitas idéias do Python, na verdade, porque o Python é uma linguagem muito agradável. Eu pegaria para declaração e copiaria seus mapas, lista e tuplas.

Agora, eu provavelmente não pegaria os conceitos dinâmicos do Python: por um lado, provavelmente seria explicitamente e estaticamente digitado. Eu acho que os programas ficam mais claros com isso. As variáveis ​​provavelmente seriam objetos com métodos, então você poderia fazer algo como str.length()obter o comprimento de uma string. Nas definições de função, você teria que especificar o tipo de retorno e os tipos dos argumentos (suportando também alguns tipos de tipos genéricos).

Vamos voltar a copiar do Python ;-). Eu amo que é maneira de ter argumentos de procedimento opcionais, então eu provavelmente teria isso. Python, no entanto, não suporta sobrecarga de procedimentos, eu gostaria disso.

Vamos dar uma olhada nas aulas, eu abandonaria a herança múltipla; fácil de abusar. Eu implementaria escopos privados e similares e provavelmente implementaria isso da maneira que é feita em C ++. Eu também teria classes abstratas e interfaces; Não acredito que o Python tenha isso.

Seria compatível com classes internas, na verdade, eu gostaria de uma linguagem orientada a objetos muito poderosa.

Provavelmente seria interpretado. É possível obtê-lo muito rápido usando uma boa compilação JIT (eu gostaria de uma linguagem rápida, embora a produtividade do programador fosse a primeira) e a compilação é ruim para a produtividade muitas vezes. Os idiomas interpretados também promovem a independência da plataforma, algo que importa cada vez mais a cada dia.

Teria embutido suporte Unicode; hoje em dia a internacionalização é muito importante.

Definitivamente seria lixo coletado. Porra, eu odeio fazer o gerenciamento de memória; também não é bom para produtividade.

Finalmente, teria uma boa biblioteca padrão.

Uau, acabei de perceber o quanto eu realmente amo Python.

Anto
fonte
Por que Interpreted languages also promote platform independance? Acho que existem mais intérpretes entre plataformas e compiladores (porcentagem), mas não consegui descobrir por que essa frase deveria ser verdadeira? Eu acho que não há nenhuma diferença entre eles, em relação às habilidades de plataforma cruzada.
Mahdi
1

Antes de tudo, eu comprava alguns livros sobre compiladores, alguns padrões e fazia um ou dois cursos em idiomas e compiladores. Contribuiria com PEP e visitaria as reuniões do comitê de padrões C ++. Eu contribuiria com patches para os compiladores que uso, espero que para recursos e bugs.

Depois, voltaria a olhar horrorizado para a lista apresentada agora, que é quais as direções que eu seguiria com um idioma se começasse agora:

  • Funcional , porque atualmente não sou versado em nenhuma linguagem funcional e criar uma seria uma ótima maneira de aprender. Caso não siga diretamente: tudo é constante .
  • Eu o preencheria com o máximo de Inferência de Tipo que pudesse caber nele, mas com a opção de especificar interfaces explicitamente. Não tenho certeza sobre outros tipos. Isso dobra, pois todas as funções são genéricas por padrão.
  • Como você deve ter adivinhado, com interfaces ; isto é, com tipos que fornecem apenas promessas nas operações disponíveis.
  • Dizer se o idioma é forte ou fracamente digitado não é muito significativo nesse caso, pelo que sei. Eu chamaria isso de tipo forte, pois as coisas nunca mudam quais interfaces eles implementam .
  • Teria muito suporte do Design by Contract . Novamente, tanto quanto eu posso ajustar: pré-condições e pós-condições são uma obrigação; Não sei o quanto os invariantes são importantes quando se trata de programação funcional.
  • Enquanto estou nisso, eu daria uma olhada nos idiomas em que você pode provar formalmente a correção e ver se consigo pegar alguma coisa a partir daí.
  • Eu saía e escrevia uma incrível biblioteca de testes . Mesmo que eu não consiga torná-lo incrível, pelo menos gastarei um tempo considerável trabalhando nisso, pois acho que é algo que todo idioma deveria ter.
  • Quanto à sintaxe, o idioma teria espaços em branco significativos e se pareceria muito com o Python , ou seria baseado no Lojban e compartilharia muito da gramática e vocabulário. No primeiro caso, eu faria o possível para tornar a gramática o mais próxima possível de um CFG.
  • Eu não me importaria se as pessoas que implementaram a linguagem a compilariam com antecedência, a interpretariam, interpretariam, cantariam em fogueiras ou pagariam estudantes universitários para executá-la por eles. Minha própria implementação provavelmente começaria como um intérprete ou um compilador C e, eventualmente, passaria para um JITter.

Como esses pontos bastante amplos provavelmente mudariam rapidamente se eu começasse a implementar o idioma, acho que entrar em mais detalhes é desnecessário.

Anton Golov
fonte
0

Se eu tivesse tempo, projetaria uma linguagem de programação localizável baseada no Scala, para que ele tivesse a maioria de seus recursos, exceto provavelmente para XML. Meu objetivo é criar um idioma que leia quase naturalmente em idiomas com uma estrutura diferente do inglês, como o árabe (minha língua materna). Estou pensando nos seguintes recursos:

  • Uma #langdiretiva de pré-processador , usada para informar o pré-processador da linguagem humana usada para programação. Por exemplo: #lang arpermitiria o uso da palavra em فئةvez de class, em عرفvez de defe assim por diante. As palavras-chave específicas do idioma humano seriam definidas nos arquivos padrão do pré-processador.
  • O pré-processador removeria algumas palavras-chave opcionais cujo único objetivo é adicionar clareza ao código. Por exemplo, ele removeria "é composto de" in class MyClass is composed of {para se tornar class MyClass {e remover "como" def MyMethod(x: Int) as {para se tornar def MyMethod(x: Int) {. Em algumas línguas (humanas), isso tornaria o código muito mais fácil de entender, especialmente para os alunos.
  • O compilador permitiria o uso de notação de prefixo para acesso à propriedade. Isso pode não fazer sentido para a maioria dos falantes de idiomas baseados em latim, mas para alguns outros idiomas faz todo o sentido. Por exemplo, o acesso à propriedade em árabe normalmente é prefixo, como em اعرض طول اسم محمد, o que equivale a print(length(name(Mohammad)))em inglês de programação. (Os parênteses são para maior clareza.)

Acredito que essas mudanças mínimas no pré-processador e compilador tornariam a programação muito mais simples para quem não fala inglês.

Hosam Aly
fonte
5
A Microsoft (e algumas outras antes) criou versões localizadas do VBA (aplicativos do Visual Basic for Office). Foi uma bagunça. Embora seja bom para iniciantes, jovens e não ingleses lerem código na língua materna, é muito difícil compartilhar código com pessoas fora do seu país. Nos nossos dias na Internet, trabalhar isoladamente não é muito produtivo. Se eu tiver que confiar apenas em fontes francesas (artigos de blog, livros etc.) para aprender Scala (como atualmente faço), perderia muitas informações úteis. Sem mencionar a dificuldade / quantidade de trabalho para localizar as bibliotecas ...
PhiLho
1
@ PhiLho: Você certamente está certo. Mas meu principal objetivo de criar esse idioma é poder introduzir a programação para um público muito mais amplo, incluindo estudantes do ensino fundamental e médio e idosos que podem não ser proficientes em inglês. No nível introdutório, eles provavelmente não precisam usar bibliotecas externas, e criar wrappers localizados para alguns pequenos (por exemplo print) não faria mal.
Hosam Aly
1
O outro ponto é que muitas pessoas já usam seus idiomas nativos para nomes de classes e métodos. Isso não os ajuda a saber que as palavras-chave estão em inglês, nem faz diferença para outras pessoas, pois as palavras-chave não são suficientes para entender o código que não está em inglês. No entanto, o pré-processador sempre pode substituir as palavras-chave de volta ao inglês e, em seguida, para qualquer outro idioma, se necessário.
Hosam Aly