- Por: Paulo Torrens
- Originalmente portado no facebook em 2014-03-08
#["LÓGICA DE PROGRAMAÇÃO" É BOBAGEM, e explicarei porquê.]
Se preparem que o texto é longo.
Várias vezes chegam novatos aqui perguntando como começar, e a galera diz "estuda lógica primeiro, depois vai pra linguagem X". Vivo dizendo que é bobagem. Ontem, em particular, falei isso, e vieram várias pessoas por inbox me perguntar porquê (e uma pra me xingar, achando que falei por arrogância).
Pra facilitar, eu vou escrever uma boa explicação de porquê "lógica de programação" é furada, doa a quem doer, e postar na APDA e no fórum da EnergyLabs (para futuras referências, porque esse assunto vai voltar, ctz).
Primeiro... vamos para a definição. O que a galera chama de "lógica de programação"? Basicamente, um fluxo lógico de instruções para executar uma operação. Professores gostam de exemplificar isso como "a receita de um bolo". Mas na prática, o que isso significa?
Acabam sendo a sequência de ifs e whiles que vão te fazer um programa. Ou ao menos é isso que alguns pensam - erroneamente.
Por que isso é errado? Porque as pessoas assumem nisso uma linguagem imperativa (http://en.wikipedia.org/wiki/Imperative_programming). Alias, muitos dizem "se tu já sabe uma linguagem, aprende qualquer uma, porque é só lógica", o que é uma bobagem enorme.
Linguagens imperativas são linguagens que expressam uma lista de instruções para o programa, sequenciais. Exemplos não faltam: C, C++, Objective-C, Java, C#, Pascal, Delphi (Object Pascal), PHP, Ruby, Python, Perl, JavaScript, Lua, Fortran, Cobol, Smalltalk, Self, PL/SQL...
Talvez alguns não conheçam linguagens além dessas. E é verdade, se tu sabe C vai ser relativamente fácil aprender uma das outras. Mas nem todas as linguagens são imperativas.
O oposto, linguagens declarativas (http://en.wikipedia.org/wiki/Declarative_programming) não descreve como fazer algo, e sim o quê deve ser feito. Tem dois paradigmas que caem aí dentro: linguagens funcionais e linguagens lógicas.
Isso nos deixa, até agora, com três formas completamente diferentes de pensar, baseado em três paradigmas: imperativo, funcional e lógico.
Você pode saber todas as linguagens citadas acima. Vamos assumir que alguém sabe aquelas todas. Essa pessoa não teria facilidade em aprender uma linguagem funcional como Common Lisp, Scheme, Dylan, Clojure, Scala, F#, OCaml, SML, Haskell, Erlang...
Alguém pode pensar: "mas ninguém usa isso!". Estão muito errados - e cada vez mais e mais errados. Os nossos sistemas de telefonia são feitos quase inteiramentes em Erlang. Se você for trabalhar no Facebook, grandes chances de usar Haskell. Mas fica a dúvida pra quem ainda é novato na área: pra que servem?
Bom, servem pra resolver problemas, como linguagens imperativas (como C e Java). Mas por que elas não eram populares - e por que estão cada vez mais populares? Hora, Lisp foi uma das primeiras linguagens de programação, então linguagens funcionais não são coisas novas. Mas as Lisp Machines (processadores feitos pra trabalharem bem com Lisp) eram da antiga União Soviética, então a história ajuda aqui. As linguagens imperativas, especialmente C, parecem mais com o que os nossos processadores (na época, os processadores ocidentais) usam, parecem com assembly (que é imperativo). Logo, tornaram-se mais populares, embora não sejam mais novos.
As pessoas não gostam muito de linguagens funcionais, porque não conseguem entendê-las facilmente (porque estão acostumadas com o pensamento imperativo, com a "lógica de programação"), mas a recíproca também é verdadeira: já vi pessoas que aprenderam a programar com Haskell, que foi sua primeira linguagem, e essas acharam Java muito estranho, e tiveram dificuldade pra acostumar a forma de pensar.
Mas por que linguagens funcionais começaram a aparecerem de novo? Elas tem conceitos de dados imutáveis (não existem variáveis!) e funções puras (sem efeitos colaterais). Na prática, o problema é o paralelismo. É difícil escrever um programa em C ou Java (ou outras linguagens imperativas) para aproveitarem processadores multicore, ou vários processadores (manycore). E você precisa escrever explicitamente. Precisa dizer que quer rodar em vários cores. Linguagens funcionais, pelos motivos que citei no começo do parágrafo, podem seguramente serem paralelizadas pelo compilador. Então é fácil um código em Haskell rodar em 1, 4 ou 16 cores e ganhar muito desempenho com isso, enquanto com C é difícil conseguir isso. E sabemos que cada vez mais é vital esse paralelismo.
As pessoas costumam dizer "C é a linguagem mais rápida!", mas apenas comparando com outras linguagens imperativas. Haskell e Lisp conseguem ser tão rápidos quanto - as vezes até mais rápidos - que C!
Por exemplo: se eu fiz um programa em C, e quero fazê-lo rodar num cluster (computadores em rede, digamos, para um servidor web), eu preciso alterá-lo para funcionar lá. Se eu escrever em Haskell, eu não preciso alterá-lo. A linguagem já garante que isso pode acontecer. Não haverá deadlock porque não é necessário haverem locks (pra quem lembrar da aula de sistemas operacionais). Sem falar que linguagens funcionais são perfeitas pra inteligência artificial. Há linguagens imperativas projetadas para usar paralelismo, como Go, mas o programador tem que ser explícito, o programador precisa se preocupar com o paralelismo. Nas linguagens funcionais ele não precisa.
Mas a "lógica de programação" que o cara tirou tempo pra estudar é inútil em Haskell, pois você não pode pensar de forma imperativa, você precisa pensar de forma funcional. Não dá pra controlar a ordem de execução de funções.
Falei sobre o paradigma lógico. A única linguagem lógica que fez sucesso, que também é antiga (nasceu em 72, mesmo ano que a linguagem C - para comparação, JavaScript surgiu em 95), é a linguagem Prolog .
Mesmo que alguém fosse pica e soubesse todas as linguagens citadas anteriores, tanto imperativas quanto funcionais, o cara iria sofrer pra aprender Prolog! Por quê? Porque precisa pensar de uma forma diferente. Precisa usar a "lógica lógica" (em contrasta à lógica imperativa e à lógica funcional).
Prolog, por exemplo, é usada muito usada para interpretar linguagens naturais (humanas), para inteligência artificial, e vários outros usos. Mas, novamente, a "lógica de programação" que tanto falam se tornou inútil.
Existe também um outro paradigma, uma outra forma de pensar, que é menos comum, que seria dataflow. Esse conceito não tem variáveis, e as vezes não tem nem memória. Surgiu ofic com a linguagem SISAL (http://en.wikipedia.org/wiki/SISAL) em 83, mas é um conceito estabelecido em 66. Podem pensar que também não usam, mas esse paradigma é usado em linguagens de descrição de hardware, VHDL e Verilog (http://en.wikipedia.org/wiki/Hardware_description_language). Hoje em dia processadores (lá na Intel e AMD) não são desenhados, seria inviável, são programados com VHDL e/ou Verilog. Linguagens de dataflow, que precisam de uma forma de pensar bem diferente. Outro exemplo famoso é a linguagem Lucid.
Existem linguagens especiais, também. Um exemplo é a linguagem Forth (http://en.wikipedia.org/wi…/Forth_%28programming_language%29), de 1970 (repararam que todos os paradigmas surgiram mais ou menos ao mesmo tempo?). Novamente assumindo que alguém saiba todas as linguagens citadas ali em cima, o cara ainda ia apanhar um pouquinho pra manjar de Forth. A linguagem é concatenativa, baseada em stack. É muito interessante, realmente. Aos curiosos, recomendo.
Também temos as linguagens dependentemente tipadas, que são quase sempre funcionais. Elas são muito difíceis de se aprender! Quais seriam exemplos? Gallina (COQ), Idris, Agda, ATS... e qual a diferença? Ao invés de tipos como "int", temos conjuntos complexos, como "int de 10 até 100". É um conceito difícil de engolir - sofri pra entender. Mas pra que isso serve? Elas são usadas por provadores automáticos (proof assistants), e elas te garantem que seu programa pode ser 100% sem bugs. Para áreas aeroespaciais e médicas isso é importante. Fizeram um compilador com Gallina, chamado CompCert, um compilador de C que foi provado, matematicamente, a partir dos tipos dependentes, que não tem bugs, e não tem falhas. Isso pode ser muito valioso, e eu apostaria que essas linguagens se tornaram populares no futuro.
Então o conceito de "lógica de programação" é extremamente relativo e abstrato, e nem sequer deveria ser usado, especialmente isoladamente.
Então, aos novatos que estão lendo, gostariam de saber o que recomendo?
Sim, vocês tem que aprender a lógica imperativa, mesmo que talvez não trabalhem com isso sempre, com certeza terão que eventualmente trabalhar com ela. Mas aprendam com alguma linguagem. Eu recomendo, pra quem nunca programou na vida, começar com a linguagem Ruby (http://en.wikipedia.org/wiki/Ruby_%28programming_language%29). Foi com a qual comecei. Ela é imperativa e 100% orientada a objetos. Quem a usa aprende orientação a objetos sem perceber - no meu caso, quando eu li a definição de "orientação a objetos", eu pensei: "ahhhh, então é isso? Eu já sei fazer isso...". Ela é fácil até para crianças, e é bem intuitiva. Realmente recomendo.
Nunca comecem estudando fluxogramas, eles não vão te ajudar a entender nem a lógica imperativa. Programação se aprende apenas na prática, sinto muito. Muita, muita prática.
E para quem já sabe linguagens imperativas e quer saber como aprender a lógica funcional? Eu gostaria de recomendar Scala (http://en.wikipedia.org/wi…/Scala_%28programming_language%29). Scala é o "novo Ruby". É uma linguagem orientada a objetos que roda na JVM, então tem uma integração fácil com Java, e que pode ser tanto imperativa quanto funcional. Ela pode ajudar na transição.
Programação lógica não tem jeito, é Prolog na veia. Recomendo Prolog e Forth para os entusiastas.
Escrevi isso pois trabalho com compiladores e linguagens de programação - faz parte do meu trabalho saber essas coisas. Não quero ninguém achando que estou desmerecendo ninguém. Todos tem que aprender de alguma forma, algum dia. Ninguém nasce sabendo. Eu me esforcei pra saber dessas coisas, e trabalho com elas. Apenas quis deixar claro: "lógica de programação" é bobagem, pois não existem apenas linguagens imperativas. Talvez você, que está lendo e mandava as pessoas aprenderem "lógica de programação", trabalhe com Java e PHP, mas você não é todo mundo.
Enfim, gostaria de desejar boa sorte a todos que estão iniciando na informática, estão na faculdade, ou simplesmente gostam de aprender. Não percam a esperança. Eu também senti vontade de desistir e ir vender cachorro quente na esquina várias e várias vezes, é apenas natural. Confiem em si mesmos. :3
Você sequer deve saber a diferença entre semântica e sintaxe pra escrever uma coisa dessas.
Nunca é tarde. Com esse seu pensamento, tenho certeza que você lucrará mais como vendedor de cachorro quente do que como programador, isso é, se você não achar que investir na qualidade do produto também é bobagem.
Aos que estão lendo, esse é um exemplo certo de mal exemplo a ser seguido.