Unixtopia

main/ artigos/

Linguagem de programação

É uma linguagem formal artificial matemática criada para permitir que humanos escrevam algoritmos para computadores com relativa facilidade. Ela basicamente permite que um humano diga a um computador de forma muito específica e precisa, mas ainda relativamente confortável, o que fazer. Chamamos um programa escrito em linguagem de programação de código-fonte do programa. Linguagens de programação frequentemente tentam imitar a linguagem humana, praticamente sempre o inglês, para ficar um pouco próxima dos humanos, mas a linguagem de programação é na verdade muito mais simples para que um computador possa realmente analisá-la e entendê-la com precisão, já que computadores são extremamente ruins em entender a linguagem humana real, sem ambiguidade, então no final tudo também parece parcialmente expressões matemáticas. Uma linguagem de programação pode ser vista como um meio termo entre o código de máquina puro, a linguagem nativa do computador, muito difícil de ser manuseada por humanos, e a linguagem natural, difícil de ser manuseada por computadores.

Para iniciantes, uma linguagem de programação é na verdade muito mais fácil de aprender do que uma língua estrangeira, ela normalmente terá menos de 100 palavras para aprender, das quais você usará, na maioria das vezes, cerca de 10 e, uma vez que você conhece uma linguagem de programação, aprender outra se torna moleza porque todas elas são parecidas em conceitos básicos. A parte difícil pode ser aprender alguns dos conceitos. Uma linguagem de programação é diferente de uma linguagem de computador geral por seu propósito de expressar algoritmos e ser usada para criação de programas. Isso quer dizer que há linguagens de computador que não são linguagens de programação, ao menos no sentido mais restrito, como HTML, json e assim por diante. Escrevemos dois tipos básicos de programas nessas linguagens, programas executáveis que podem ser executados diretamente, e bibliotecas, código que não pode ser executado sozinho, mas deve ser usado em outros programas, como uma biblioteca para funções matemáticas, redes, jogos e assim por diante. Um exemplo simples de código fonte na linguagem de programação C é o seguinte:

// Programa simples que calcula o quadrado de números

#include <stdio.h>

int square(int x)
{
 return x * x;
}

int main(void)
{
 for (int i = 0; i < 5; ++i)
 printf("%d ao quadrado é %d\n",i,square(i));

 return 0;
}
Que imprime:
0 ao quadrado é 0
1 ao quadrado é 1
2 ao quadrado é 4
3 ao quadrado é 9
4 ao quadrado é 16

Dividimos as linguagens de programação em diferentes grupos. Talvez a divisão mais comum seja em dois grupos:

Às vezes, a distinção aqui pode não ser completamente clara, Python é normalmente considerada uma linguagem interpretada, mas também pode ser compilada em bytecode e código nativo. Java é considerada mais uma linguagem compilada, mas não compila para código nativo, compila para bytecode. C é tradicionalmente uma linguagem compilada, mas existem interpretadores. Outra divisão é por nível de abstração, tenha em mente que a transição é gradual e depende do contexto, a linha entre low e high nível é difusa:

Podemos dividir a linguagem de muitas outras maneiras, como com base em seu paradigma, aproximadamente sua ideia, modelo, filosofia central: imperativo, declarativo, orientado a objetos, funcional, lógico, propósito, geral, propósito especial, poder computacional: Turing completo ou mais fraco, muitas definições de uma linguagem exigem completude de Turing, tipagem: forte, fraco, dinâmico, estático, ou avaliação de função: estrito, preguiçoso.

Uma linguagem de computador consiste em duas partes principais:

Nós também comumente dividimos uma linguagem em duas partes principais:

Além da biblioteca padrão, também existirão muitas bibliotecas de terceiros, mas elas não são mais consideradas parte da linguagem em si, elas já são produtos da linguagem. Qual é a melhor linguagem de programação e qual você deve aprender? Essas são as grandes questões, o tópico de linguagens de programação é infame por ser muito religioso e pessoas diferentes torcem por linguagens diferentes. Para minimalistas, a linguagem padrão é C, que também é provavelmente a linguagem mais importante da história. Não está na liga das linguagens absolutamente mais minimalistas e objetivamente melhores, mas é relativamente minimalista, muito mais do que praticamente qualquer linguagem moderna, e tem grandes vantagens, como ser uma das linguagens absolutamente mais rápidas, ser extremamente bem estabelecida, testada há muito tempo, suportada em todos os lugares, ter muitos compiladores. Mas C não é fácil de aprender como primeira linguagem. Alguns minimalistas também promovem Go, que é como novo C. Entre as linguagens mais minimamente utilizáveis estão tradicionalmente Forth e Lisp, que meio que competem por quem realmente é o menor. Para aprender programação, você pode querer começar com alguma linguagem feia como Python, mas você realmente deve tentar fazer a transição para uma linguagem melhor mais tarde. Você pode usar várias linguagens de programação para um projeto? Sim, embora possa ser um fardo, então não faça isso só porque você pode. Combinar linguagens é possível de muitas maneiras, incorporando uma linguagem de script em uma linguagem compilada, vinculando arquivos de objetos produzidos por diferentes linguagens, criando diferentes programas que se comunicam pela rede.

História

WIP

Os primeiros computadores eram programados diretamente em código de máquina, não havia nem mesmo assemblers e linguagens de montagem, os programadores tinham que fazer coisas como procurar por opcodes em manuais de computador, codificar dados manualmente e colocar tudo isso em cartões perfurados ou usar alguma interface primitiva, como o chamado painel frontal para programar o computador. Esses tipos de linguagens de máquina que eram usados naquela época agora são chamados de linguagens de primeira geração. A primeira linguagem de programação high-level foi provavelmente Plankalkul feita por Konrad Zuse algum tempo logo após 1942, embora não tenha rodado em nenhum computador, estava apenas em estágio de especificação, sua implementação só seria feita muito mais tarde, em 75. Era bastante avançada, tinha funções, matrizes, exceções e algumas estruturas de dados avançadas, embora não suportasse chamadas recursivas. Foi importante porque plantou a semente de uma ideia de uma linguagem abstrata e independente de máquina.

A primeira linguagem assembly foi criada por Maurice Wilkes e sua equipe para o computador EDSAC lançado em 49. Ela usava letras únicas para instruções. As linguagens assembly são chamadas de linguagens de segunda geração, elas ajudam ainda mais na programação, embora ainda em um nível muito baixo. Os programadores agora eram capazes de escrever texto, em oposição a números simples, as instruções tinham nomes mais amigáveis aos humanos e os montadores faziam algumas tarefas simples, mas tediosas, automaticamente, mas ainda era muito tedioso escrever em assembly e os programas ainda eram específicos da máquina, não portáteis. Somente as linguagens de terceira geração deram o passo de adicionar abstração significativa para atingir um nível de desenvolvimento confortável e portabilidade, os programadores seriam capazes de escrever expressões algébricas que seriam automaticamente traduzidas para instruções específicas pelo compilador da linguagem; seria suficiente escrever o programa uma vez e então compilá-lo automaticamente para diferentes CPUs, sem a necessidade de reescrevê-lo. Fortran é considerada a primeira linguagem desse tipo, feita em 1957 pela IBM. Fortran se desenvolveria e mudaria ao longo dos anos, foi padronizado e adicionou mais recursos, tornou-se bastante popular e ainda é usado até hoje, é conhecido por ser muito rápido. Em 58, John McCarthy começou a desenvolver Lisp, uma linguagem de alto nível altamente elegante que geraria muitos derivados e continua muito popular até hoje. No final dos anos 60, o termo programação orientada a objetos apareceu, assim como as primeiras linguagens como Simula e Smalltalk que eram baseadas neste paradigma. Naquela época, era um experimento bastante acadêmico, não realmente prejudicial em si, mais tarde, a POO seria apreendida e estuprada por capitalistas para quebrar computadores. Em 64, um lixo chamado BASIC apareceu, com o objetivo de tornar a programação mais fácil até para não profissionais, ela se tornaria uma linguagem muito popular para computadores domésticos. Em 70, Pascal foi criado para ser uma linguagem educacional, alguns hackers já viam isso como uma retardação muito grande das linguagens de programação, veja o famoso ensaio Real Programmers Don't Use Pascal.

Um dos eventos mais notáveis na história das linguagens foi a invenção da linguagem C em 72 por papai Ritchie e titio Kerninghan, que a usaram como uma ferramenta para seu sistema operacional UNIX. A versão inicial era bem diferente da de hoje, mas a linguagem como um todo é a mais importante da história, não é a mais elegante, mas alcançou a mistura exata de recursos, simplicidade e escolhas corretas de design, como permitir liberdade e flexibilidade de implementação que levaria à extrema eficiência e adoção por muitos, à padronização, levando ainda mais a muitas implementações e sua alta otimização, o que aumentou ainda mais a popularidade de C e assim por diante. Deste ponto em diante, novas linguagens normalmente tentariam iterar em C. Também em 72, a primeira linguagem de programação esotérica, INTERCAL, foi criada como uma espécie de linguagem de paródia. Isso criaria uma comunidade dedicada de pessoas criando uma linguagem engraçada semelhante, que é altamente ativa até hoje. Em 1978, a CPU Intel 8086 foi lançada, dando origem à linguagem assembly x86, a assembly que se tornaria talvez a mais amplamente usada, devido à popularidade das CPUs Intel. Em 79, um viado chamado Bjarne Stroustrup infelizmente começou a trabalhar em C++, uma linguagem que violaria o conceito de programação orientada a objetos introduzido por Simula e Smalltalk de uma forma distorcida e capitalista, iniciando a tendência de criar linguagens feias e inchadas focadas em lucro. Pouco antes dos anos 90, no ano de nosso Senhor 1989, o padrão ANSI C, também conhecido como C89, foi lançado, este é considerado um dos melhores padrões C. Em 1991, Java, uma linguagem lenta, bloat e orientada a capital com POO forçada começou a ser desenvolvida pela Sun Microsystems. Isso foi um desastre, fodeu completamente os computadores para sempre. No mesmo ano, Python, uma linguagem de retardados para retardados, apareceu, o que contribuiu para destruir a tecnologia de computadores em algumas décadas. Após alguma faísca de interesse renovado em linguagens esotéricas, Brainfuck foi criado em 93 e se tornou provavelmente o mais popular entre as linguagens esotéricas, este foi ao menos um bom evento. 95, outro desastre aconteceu quando JavaScript foi anunciado, o que mais tarde destruiria toda a web. No final dos anos 90, em 1999, o outro dos dois melhores padrões, C99, foi lançado. Isso basicamente marca o fim de bons eventos no mundo das linguagens de programação.

Mais detalhes e contexto

O que realmente é uma linguagem de programação, é um software? Um padrão? Uma linguagem pode ser bloated? Como as linguagens evoluem? Onde está a linha exata entre uma linguagem de programação e uma linguagem não programada? Quem faz as linguagens de programação? Quem as possui? Quem as controla? Por que há tantas e não apenas uma? Essas são apenas algumas das perguntas que alguém pode fazer ao aprender sobre programação. Vamos tentar responder rapidamente algumas delas. A rigor, uma linguagem de programação é uma linguagem formal com semântica, apenas algo semelhante a uma ideia matemática e não pode ser diretamente possuída, ao menos não com base em direitos autorais, como parece ter sido fortemente estabelecido por alguns processos judiciais agora. Coisas relacionadas a uma linguagem podem, infelizmente, ser possuídas, suas especificações, padrões oficiais que descrevem a linguagem, marcas registradas, nome ou logotipo da linguagem, implementações, software específico, como o compilador e patentes sobre ideias usadas na implementação. Se uma linguagem for muito complexa, ela pode ser possuída na prática, normalmente, uma corporação criará uma linguagem extremamente complicada que somente 1.000 programadores pagos podem manter, dando à corporação controle total sobre a linguagem, veja monopólio de bloat e software capitalista.

Neste ponto, devemos começar a distinguir entre a linguagem pura e sua implementação. Como foi dito, a linguagem pura é apenas uma ideia, essa ideia é explicada em detalhes na chamada especificação de linguagem, um documento que é uma espécie de padrão que descreve precisamente a linguagem. A especificação é um documento técnico, não é um tutorial ou material promocional ou algo assim, seu propósito é apenas definir a linguagem para aqueles que a implementarão, às vezes a especificação pode ser um padrão muito oficial feito por alguma organização de padronização, como C, outras vezes pode ser apenas um documento colaborativo online que ao mesmo tempo serve como referência de linguagem, como o Lua. É importante versionar a especificação assim como versionamos programas, porque quando a especificação muda, as linguagens especificadas geralmente mudam também, a menos que seja uma pequena mudança, como corrigir alguns erros de digitação, então temos que ter uma maneira de identificar exatamente qual versão da linguagem estamos nos referindo. Teoricamente, a especificação é a primeira coisa, na prática, geralmente temos alguém, programar uma pequena linguagem para uso interno em uma empresa, então essa linguagem se torna mais popular e difundida e só então alguém decide padronizá-la e fazer a especificação oficial. A especificação descreve coisas como sintaxe, semântica, critérios de conformidade, geralmente usando ferramentas formais precisas, como gramáticas.

É difícil fazer uma boa especificação porque é preciso decidir até que profundidade ir e até mesmo o que deixar propositalmente sem especificar. Alguém poderia pensar que é sempre melhor definir o máximo de coisas possível, mas isso é ingênuo, deixar algumas coisas para a escolha daqueles que implementarão a linguagem lhes dá liberdade para implementá-la de uma forma que seja mais rápida, mais elegante ou conveniente de qualquer outra forma. É possível que uma linguagem exista sem especificação oficial, a linguagem é então basicamente especificada por algumas de suas implementações, ou seja, dizemos que a linguagem é "o que este programa aceita como entrada válida". Muitas linguagens passam por essa fase antes de receber sua especificação. Linguagem especificada puramente por uma implementação não é uma ideia muito boa porque, em primeiro lugar, tal especificação não é muito legível e aqui tudo é especificado por este programa, a linguagem é igual a um compilador específico, não sabemos onde está a liberdade de implementação. Outras implementações têm que produzir exatamente o mesmo binário compilado que este, sem poder otimizá-lo melhor ou produzir binários para outras plataformas? Se não, o quanto elas podem diferir? Elas podem usar representações diferentes de números, pode ser importante para compatibilidade? Elas têm que reproduzir até mesmo os mesmos bugs do compilador original? Elas têm que ter as mesmas limitações técnicas? Elas têm que implementar a mesma interface de linha de comando, sem potencialmente adicionar melhorias?

TODO