Programar — como começar?

O leitor poderá achar estranho (sendo já um programador) ao ler um artigo sobre um aspecto passado do seu percurso. Sob esse ponto de vista, este artigo poderá até parecer redundante, mas penso que o tema em questão justifica bem a “redundância”, tendo em conta que a programação é um exercício cada vez mais acessível a qualquer pessoa.

Existe na comunidade de programadores uma estranha ideia de que toda a gente deve começar a programar com a linguagem X, Y ou Z. Frequentemente (e como se pode ver em discussões acesas no Portugal-a-Programar), as linguagens X, Y e Z são frequentemente a linguagem C. Chegamos mesmo ao cúmulo de ver afirmações que parecem sugerir que começar com uma linguagem dinâmica de alto nível (quase diametralmente oposta a C) é equivalente a uma lobotomia seguida da incapacidade permanente de escrever programas eficientes, de baixo nível.

Eu comecei a programar durante o ensino básico (com 12–13 anos) e fi-lo essencialmente sem ajuda de ninguém. Comecei com uma variante de Pascal (no Delphi 1.0), e com ela permaneci durante alguns anos. Embora a minha ideia de programa fosse nessa altura algo “quadrada” (com uma barra azul e três botões cinzentos acima, à direita), lá consegui compreender que a essência de programar não era um conjunto de janelas e botões bonitos. Não, a essência de programar é resolver ou simplificar problemas.

Entretanto fui aprendendo outras linguagens (continuo a fazê-lo), mas vou apenas partilhar a minha primeira impressão de C, vindo de Pascal: C tinha uma sintaxe absurda. Não me refiro à questão das chavetas vs begins e ends mas sim à ambiguidade da sintaxe. Em C, * pode ser várias coisas (o mesmo para &), e até mesmo as declarações de variáveis são idênticas aos protótipos de funções. Neste aspecto, Pascal pareceu-me uma linguagem muito mais regrada, pensada e coerente. A sua sintaxe (bastante mais explícita que a de C) exige mais dos teclados, mas bons editores de texto e ambientes de desenvolvimento automatizam algumas partes da escrita do código, suavizando este “problema”.

Deparei-me também com problemas que não tinha encontrado em Pascal: em C não havia um tipo de dados string como em Pascal1. As strings de Pascal têm as suas desvantagens, mas para pequenos programas são bastante razoáveis e muito mais confortáveis que as “strings” de C2. Também senti falta da flexibilidade do sistema de tipos de dados de Pascal quando comecei a utilizar C.

Depois havia também o problema da modularização do código em C. Vindo de Pascal, estava habituado às units de código com secções explícitas para a interface e implementação. Em C fui obrigado a aprender as artimanhas dos #includes e include guards3.

Até na questão da gestão de memória e apontadores Pascal me oferecia uma sintaxe mais lógica que C.

Antes que me desvie mais do tema principal, vou resumir: senti-me um pouco perplexo acerca dos motivos pelos quais esta linguagem aparentemente primitiva, confusa e mal pensada era a mais utilizada em todo o mundo. Eventualmente lá compreendi que “a ideia” da linguagem C era ser compacta, concisa, desprovida de redundâncias. Hoje em dia aprecio imenso essas características, e a sintaxe não me incomoda mais (mas ainda a acho ambígua). Ainda assim, fica-me a ideia de que esta linguagem não é a mais indicada para quem está a começar a programar devido aos problemas que falei acima e outros como contacto precoce e “demasiado intenso” com gestão manual de memória, apontadores, entre outros.

Esta “sub-secção” do artigo não foi escrita com o objectivo de comparar Pascal com C (isso seria tema suficiente para um artigo por si só), mas sim com o objectivo de mostrar problemas que eu enfrentei quando aprendi C e que provavelmente toda a gente enfrenta quando começa a programar em C. É importante reter que eu já tinha experiência com Pascal (e Javascript, entre outras) e mesmo assim encontrei os defeitos acima referidos.

Peguemos agora no problema por outra ponta. Que linguagem devemos incentivar o jovem programador a escolher como sua primeira aposta? É uma questão complexa, e a resposta não é a mais simples, mas penso que podemos dar algumas aproximações.

Na minha opinião, C não é a melhor escolha para primeira linguagem. Pascal (já que já falámos dele) é uma opção bem melhor e menos desmotivante para quem não tem ideia alguma do que é programar4, mas não precisamos de ficar com Pascal. Podemos pegar, por exemplo, em Python. Python, sendo uma linguagem dinâmica nos tipos de dados e de alto nível de abstracção, consegue ser bastante expressiva e, por esse motivo, adequada a quem se inicia na programação precisamente por facilitar a transposição das ideias para código5. Ainda por cima, Python oferece suporte para outros paradigmas de programação (objectivo, funcional) sendo por isso uma “plataforma” a partir da qual o programador pode partir para novos desafios.

Mas deixemos o Python de lado por agora. Existem muitas outras linguagens que podem preencher o seu lugar. Ruby, por exemplo, é praticamente equivalente a Python, com algumas diferenças sintácticas e operacionais, mas essencialmente idêntica. Este tipo de linguagens oferece uma prototipagem rápida, um nível de expressividade e abstracção elevados e por isso devemos encorajar os iniciados a brincar com elas desde cedo.

Consideremos agora o paradigma funcional. São estas as linguagens que deveríamos aprender primeiro. Com uma boa dose de inspiração da matemática, estas linguagens dão grande ênfase à composição de funções e à transparência referencial6.
Sem mutabilidade, ciclos e outros “artifícios”, as linguagens funcionais obrigam o programador a pensar nos problemas de outra forma e mesmo que na sua actividade profissional não venha a programar numa destas linguagens, será um programador melhor simplesmente pelo contacto prévio com este paradigma.

Existem diversas opções neste ramo, mas vou salientar apenas duas: Haskell e Scheme (um dialecto de Lisp).
Haskell é uma linguagem funcional pura, com um sistema de tipos de dados impressionante. O conjunto de operações que fornece para manipularmos funções é simplesmente incrível e torna-se muito difícil tentar descrever a um programador de C (ou Python, ou outra linguagem imperativa) o que é possível fazer em Haskell, mas vale a pena aprender. Com o seu sistema de tipos de dados, os programas em Haskell “surgem” muitas vezes como consequência directa dos dados envolvidos

Notas

  1. Naturalmente, a representação de uma string em Pascal é menos eficiente em termos de memória, mas apresenta alguns ganhos de eficiência nalgumas situações. De qualquer modo, as tradicionais “strings de C” também estão disponíveis em Pascal sob o nome PChar.
  2. Na realidade, não existem strings em C; o que existe é um conjunto de funções que lida com arrays do tipo char[].
  3. Isto acontece porque C não tem verdadeiro suporte para modularização de código.
  4. Não subestimemos o valor da motivação na (auto-)aprendizagem.
  5. Python pode até mesmo ser considerado “pseudo-código executável”, de certa forma.
  6. Ou seja, funções que têm sempre o mesmo resultado para o mesmo conjunto de argumentos.
  7. Este tipo de meta-programação é incomparavelmente melhor que as tradicionais macros de C/C++ ou os templates de C++.
  8. Mais uma vez, não comparemos as macros de C/C++ com isto, são coisas completamente diferentes.