O autor do artigo discute os problemas das linguagens de programação modernas e sobre as maneiras pelas quais corrigir deficiências.Somente nos últimos 18 anos, as pessoas criaram muitas línguas, entre as quais provavelmente as mais populares são Swift, Kotlin e Go. Ao mesmo tempo, a característica distintiva da linguagem de programação do século XXI é a ausência de características distintas. A coisa mais agradável ao trabalhar com esses idiomas é que você pode passar um fim de semana aprendendo um deles e finalmente dizer que conseguiu aprender uma novidade popular, mas na verdade você não aprendeu nada de novo. Eles realmente não são novidade. Todas as linguagens modernas são criadas com base em alguma fórmula correta e comprovada, cujo nome é provavelmente Objective-C, Java ou C.
A “falta de novidade” pode ser considerada uma característica valiosa, mas essa situação levanta uma questão. Estamos realmente enfrentando as linguagens do novo século 21, ou tudo isso é apenas um reflexo dos maus hábitos de programação do século 20?
Se eu inventasse a linguagem, não tentaria corrigir o passado, mas tentaria criar algo que funcionaria bem nas condições modernas, mas também seria capaz de desenvolver e resistir ao teste do tempo. Se isso requer soluções construtivas radicais, que assim seja.
Abaixo a sintaxe!
A sintaxe das linguagens modernas reflete uma tentativa de espremer a liberdade do giz e do quadro negro nos grilhões do ASCII. Alguns elementos de um registro, como sinais ou suportes aritméticos, são percebidos mais ou menos naturalmente. Mas várias outras designações são justificadas apenas economizando esforço ao pressionar os botões de teletipo.
A inserção de texto no teclado não é mais difícil. Não somos obrigados a nos colocar em uma posição em que é necessário adivinhar o significado da sintaxe. Peças como
(($: @ (<# [), (= # [), $: @ (> # [)) ({~? @ #)) ^: (1 <#) - um formato de gravação muito curto e amplo (a propósito, isso é um pedaço de código
real em
linguagem real ), mas não melhora a legibilidade de forma alguma. E, mais importante, é difícil "pesquisar" no google ou encontrá-lo no stackoverflow.
O mesmo pode ser dito sobre os nomes misteriosos de funções, convenções de códigos de retorno e atributos com significado obscuro. Eles serviram bem no passado, economizando muito espaço em cartões perfurados, mas hoje é hora de um descanso bem merecido.
Algo como
FILE * test_file = fopen("/tmp/test.txt", "w+");
deve ser transformado em
create file /tmp/test.txt for input and output as test_file
Não precisamos de todos esses colchetes, aspas, asteriscos e ponto-e-vírgula (a menos que, é claro, eles realmente não transmitam a idéia mais claramente). O realce da sintaxe é capaz de substituir completamente a notação de sintaxe.
Algumas coisas abundantes estão disponíveis no século XXI: por exemplo, velocidade de análise, memória do computador, pesquisa on-line. Outros recursos ainda estão no preço: tempo de desenvolvimento, memória do programador, esforço despendido no aprendizado dos recursos da linguagem. Alterações nas regras para escrever código devem mudar o foco para recursos mais baratos e economizar recursos mais caros.
Abaixo os tipos embutidos!
Você provavelmente conhece os
paradoxos do JavaScript . Por exemplo, como:
> 10.8 / 100
0.10800000000000001
Este resultado não é exclusivo do JavaScript. E isso não é um paradoxo, mas um exemplo de aderência absolutamente correta ao respeitado padrão IEEE 754. Uma implementação semelhante de números de ponto flutuante é encontrada em quase todas as arquiteturas. E não é tão ruim, considerando que estamos tentando colocar um número infinito de números reais em 32, 64 ou 256 bits.
O que os matemáticos consideram impossíveis, os engenheiros incorporam através da rejeição do senso comum em prol da implementação prática. Os números de ponto flutuante na interpretação IEEE não são números. A matemática exige associatividade da operação de sua adição. Os tipos float e double nem sempre salvam essa propriedade. A matemática exige que o conjunto de números reais inclua números inteiros, mas esse requisito não é atendido mesmo para float e uint32_t do mesmo tamanho. A matemática exige que os números reais tenham um elemento zero. Bem, nesse aspecto, o padrão IEEE excede todas as expectativas, porque os números de ponto flutuante têm dois elementos zero em vez de um.
Não apenas números de ponto flutuante possuem recursos semelhantes. Inteiros incorporados não são melhor implementados. Você sabe o que acontece se você tentar adicionar dois desses números de 16 bits?
0xFFFF + 0x0001
Ninguém dará uma resposta exata. Um instinto nos diz que o excesso excederá 0x0000. No entanto, esse resultado não está documentado em nenhum padrão internacional. Ao lidar com essa operação, todos são guiados pela abordagem C e pela família de processadores x86. Como alternativa, pode resultar 0xFFFF, ou uma interrupção será acionada ou algum bit especial indicando excesso será armazenado em um local especial.
Esses momentos geralmente não são considerados em lugar algum, e as regras para processar essas operações diferem de idioma para idioma. Se as esquisitices de ponto flutuante são pelo menos fixadas pelo padrão, a última questão levantada é, em princípio, imprevisível.
Em vez disso, para cálculos numéricos, sugiro introduzir tipos de dados de um valor definível com um ponto fixo e um comportamento padronizado em caso de perda de precisão ou ultrapassando o limite superior ou inferior. Algo assim:
1.000 / 3.000 = 0.333
0001 + 9999 = overflowed 9999
0.001 / 2 = underflowed 0
Não é necessário anexar todos os zeros à direita: a presença deles deve estar implícita na definição do tipo de dados. Mas é importante poder escolher você mesmo os limites máximo e mínimo e não depender da arquitetura do processador.
Esses cálculos não funcionam mais devagar? Sim eles vão. Mas pergunte-se: com que frequência você tem que programar computação de alto desempenho? Acredito que se você não é um especialista nesse campo, isso é muito raro. E se você estiver envolvido nessas tarefas, use equipamentos e compiladores especializados para esses fins. Até onde eu sei, um programador típico do século 21 raramente resolve equações diferenciais.
Seja como for, nada impede o uso de tipos internos rápidos, complexos e imprevisíveis do passado como uma alternativa, e não como a opção padrão.
Abaixo a prática das metalinguagens!
Existem idiomas maravilhosos que foram inventados não para executar tarefas, mas para criar idiomas capazes de realizá-las. Racket, Rebol e Forth são apenas alguns exemplos. Gosto de todos, brincar com eles é puro prazer. Mas, como você provavelmente adivinhou, o prazer recebido por trabalhar com o idioma não é o principal critério que torna o idioma universal e popular.
A capacidade de criar novos idiomas dentro de um idioma para executar uma tarefa específica é uma ferramenta muito poderosa que compensa completamente durante o trabalho de pesquisa independente. Infelizmente, se o código não deve ser entendido apenas pelo autor, além do principal, você terá que ensinar a outras pessoas uma nova linguagem interna. E aqui começam os problemas.
As pessoas querem concluir a tarefa e não aprender um idioma que ajude a fazer o trabalho exatamente uma vez, e depois disso não serão úteis. Para quem está de fora, a ideia de dominar seu idioma é um investimento que provavelmente não será recompensado. Mas aprender algo padronizado é um investimento para a vida. Portanto, eles reescreverão seu código novamente e só então o aprenderão. Assim, inúmeros dialetos aparecem para uma esfera aplicada. As pessoas discutem sobre estética, ideologia, arquitetura e outras coisas sem importância. E milhões de linhas de código são escritas para afundar no esquecimento em alguns meses.
Os caras do Lisp passaram por isso nos anos 80. Eles perceberam que quanto mais elementos de linguagem aplicados forem padronizados, melhor. Assim surgiu o Common Lisp.
E ele era enorme. O padrão INCITS 226-1994 possui 1.153 páginas. Esse recorde, 17 anos depois, foi quebrado apenas pelo C ++ com a norma ISO / IEC 14882: 2011 (1338 páginas). O C ++ precisa arrastar um legado insuportável, mesmo que nem sempre tenha sido tão grande. O Lisp comum foi criado na maior parte do zero.
A linguagem de programação não deve ser tão grande. Isto não é necessário. Ele só precisa de uma boa biblioteca padrão, cheia de todos os tipos de coisas úteis, para que as pessoas não precisem reinventar a roda.
Obviamente, manter um equilíbrio entre tamanho e adequação do aplicativo não é fácil. A experiência do C ++ na prática mostrou como é difícil. Acredito que, para alcançar o equilíbrio necessário, a linguagem do século XXI deve ser afiada condicionalmente sob um determinado campo aplicado. Como a maioria dos problemas agora surge precisamente no campo de aplicativos de negócios, a linguagem provavelmente deve se concentrar nos problemas de negócios, e não no desenvolvimento de jogos ou no design da web.
Então ...
A linguagem do século XXI deve ser orientada para os negócios, usar expressões de linguagem claras e não depender de tipos internos. É ótimo que essa linguagem já exista! O que você acha, do que estamos falando?
Sim, isso é COBOL.
Este é um dos primeiros idiomas de alto nível, hoje praticamente esquecido. Devo admitir que intencionalmente descrevi os recursos antigos do COBOL como ultramodernos e incrivelmente promissores. E eu fiz isso para mostrar uma coisa. O código não é escrito por recursos de idioma. Você faz isso.
É ingênuo pensar que o idioma é responsável pela qualidade do código e que adicionar alguns gadgets (ou removê-los) pode melhorar tudo automaticamente. Ao mesmo tempo, os programadores não gostaram do Fortran e do COBOL; portanto, eles inventaram o C ++ e o Java, a fim de chegar a uma situação em que, 20 ou 30 anos depois, eles também não gostavam de todos.
De acordo com meus sentimentos, a raiz do problema está em algum lugar no campo da sociologia e psicologia, mas não da programação. Nós realmente não gostamos tanto de idiomas? E estamos satisfeitos com o ambiente em que trabalhamos? O Windows é vulnerável, o Visual Studio é muito lento, é impossível sair do Vim. De fato, são essas coisas que causam descontentamento, e não o próprio processo criativo.
Mas você sempre tem que encontrar o culpado. Como engenheiros de software, em parte responsáveis por quão ruins são os programas, não nos culparemos, certo? Portanto, estamos procurando falhas nas ferramentas. Vamos inventar novos COBOLs até que um dia o sol comece a brilhar mais forte, os pássaros não cantem mais alto e o Windows comece a carregar em 2 segundos.
Mas provavelmente este dia nunca chegará.
Portanto, se eu quisesse inventar a linguagem de programação do século XXI, tentaria encontrar uma nova abordagem para a responsabilidade. Ou uma nova maneira de dominar melhor as ferramentas existentes. Eu tentava estar mais atento aos detalhes essenciais e me livrar impiedosamente de qualquer complexidade desnecessária. Em vez de idiomas que entram e saem de moda, sempre existem algumas coisas fundamentais que merecem repensar constantemente.
