Eu vou falar para vocês agora sobre assunto que é bastante interessante, que todo mundo fala essa coisa, tal linguagem é dinâmica... tal linguagem é estática. Mas é muito dificil encontrar informações fidedignas sobre o que são linguagens dinâmicas ou linguagens estáticas, particular, português é muito raro ter bom material sobre isso. Então, vamos discutir pouco esse assunto. Primeiro, vamos ver alguns exemplos do que as pessoas normalmente se referem quando estamos falando que tal linguagem é estática. Normalmente são linguagens que são compiladas, como FORTRAN, ALGOL, PASCAL e C, e uma vez que você escreve o código fonte, tempo de compilação, toda a estrutura do programa, das estruturas de dados, são definidas tempo de compilação. Enquanto o programa está executando, ou seja, tempo de execução, você não tem muito poder de alterar essa estrutura, de criar novas coisas na estrutura dos seus dados e dos seus programas. Linguagens orientadas a objetos, tais como Simula -67, C ++, Java e Scala, também são linguagens consideradas linguagens estáticas, embora Java, SCALA e até C++, já estão rumando na direção das linguagens dinâmicas. Particular nessas linguagens é preciso declarar as variáveis antes de usá-las. E é preciso definir o tipo das variáveis e também o tipo dos argumentos, das funções, dos métodos. Aí ocorre, a gente fazendo, definindo esses tipos, a gente permite que o compilador faça o que a gente chama de checagem de tipos tempo de compilação ou tipagem estática. Também tem gente que diz que é uma linguagem fortemente tipada. O compilador pode verificar se há erros de compatibilidade entre os tipos dos programas tempo de compilação, antes de você executar o programa. Código tipicamente numa linguagem desse tipo, vai ser algo desse tipo int x recebe 32, eu estou dizendo que a variável x é do tipo inteiro e quando ele recebe esse 32, pode fazer a checagem para ver se realmente o 32 é inteiro, se é compatível com o tipo int. Quando eu quero criar uma nova instância de uma classe, por exemplo, fazendo new carro, eu quero guardar uma variável, tenho que dizer que essa variável é do tipo carro, nesse caso, ou tem que ser do tipo compatível. Podia ser super tipo de uma super classe compatível com o carro, também funcionaria. Quando eu tenho uma função, método, por exemplo, soma, eu tenho que dizer quais são os tipos dos parâmetros e qual é o tipo do valor devolvido pela função. Assim, o compilador pode checar se esses tipos estão sendo usados de uma forma consistente. Já as linguagens dinâmicas, tipicamente, a gente lembra de LISP, talvez a primeira linguagem dinâmica, depois Smalltalk, a primeira grande linguagem completamente orientada a objetos, que tem tudo que a gente considera importante orientada objetos. A linguagem Lua desenvolvida lá na Puc-Rio, aqui no Brasil. Linguagem Python, Ruby, JavaScript são linguagens dinâmicas. Nessas linguagens não é preciso declarar as variáveis antes de usá-las e as variáveis não tem tipo, tempo de compilação. As variáveis guardam os valores, e esses valores sim tem tipo, mas a variável si não tem. A vantagem disso é que o código acaba ficando muito mais flexível, porque uma variável, você tem uma função que tem determinado código funções de variáveis que não tem tipos fixos, elas funcionam para qualquer daqueles tipos que você passar como parâmetro. Tem também certos perigos, porque pode se passar tipo que é incompatível e não vai ser detectado tempo de compilação, essa incompatibilidade. Porque a checagem de tipo só é feita tempo de execução, o que a gente chama de tipagem dinâmica. Normalmente ela é simplesmente, se você tem objeto e você envia uma mensagem para aquele objeto, não é feita nenhuma verificação para ver se aqueles tipos são compatíveis. A única verificação que é feita é, se aquele objeto entende aquela mensagem que voce enviou, tipicamente se tem método com aquele nome, daquela mensagem que você enviou, isso é uma coisa que a gente chama de tipagem do pato, duck typing. Exemplos, então x recebe 32, eu não preciso declarar X a priori, nem declarar o tipo do x. C recebe carro, agora você vai ter algo do tipo carro e soma xy não estou dizendo qual que é o tipo do x, y. Eu posso talvez fazer código que funciona tanto com strings quanto com números inteiros, por exemplo, números complexos, ou matrizes. Então, são as linguagens dinâmicas. Tem outras características importantes linguagens dinâmicas. Vamos falar algumas delas. Então, por exemplo, interpretação. Tipicamente linguagens estáticas, na maioria das vezes são implementadas usando o compilador, o compilador traduz o código fonte para código executado e se executam. Linguagens dinâmicas tendem a ser interpretadas por meio de interpretador. Tem casos híbridos onde usam primeiro uma compilação pra byte code depois interpretação do byte code. Mas se você tem interpretador, você passa e você executa esse interpretador tempos de execução, você tem a capacidade de executar trechos da linguagem fornecidos só tempo de execução. Veja que interessante. Na linguagem Python tem esse comando exec que você passa, como parâmetro string, onde esse string pode conter código Python. Se eu fizer isso, exec que está string com esse código python, o que ele vai fazer é executar. Ele vai compilar tempo de execução esse código parcelamento desse string e vai executar isso. Isso permite que você faça programa onde o usuário do seu programa digita código Python, e ele é executado, por exemplo. Outra coisa bem interessante é a idéia de reflexão computacional, que tem dois lados. Primeiro lado é você poder tempo de execução consultar a estrutura do seu código, a medida que o código está executando. Então, dado objeto, você pode perguntar para aquele objeto, quais são seus métodos e baseado nesses métodos, você pode montar menu para o seu usário, o usuário escolhe uma opção do menu e você executa aquele método. E isso é super dinâmico. Porque se tempo de execução você acrescentar novo método, o menu vai crescer e vai ter uma opção nova no menu para o usuário. Outra possibilidade é você alterar a estrutura do código tempo de execução. Então você criar novo método, criar novo atributo, ou até mudar o jeito que aquele código está organizado tempo de execução. Algumas linguagens, as linguagens bem dinâmicas permitem isso, essas duas formas de reflexão. Outra característica que a gente vê muito linguagens dinâmicas é a gestão automática de memória. Se você aloca vários objetos e algum desses objetos não é mais utilizado, tem algoritmo por trás que se chama coletor de lixo, que detecta esses objetos, esses pedaços da memória que não são utilizados e ele considera aquilo lixo e coleta o lixo, ou seja, libera aquele pedaço da memória. Você não precisa de preocupar com isso, ele faz de forma automática. Quais são as consequências de eu usar uma linguagem mais estática, uma linguagem mais dinâmica? Nas linguagens estáticas os erros de tipo são checados pelo compilador. O compilador me ajuda a cometer menos erros de programação. Já nas linguagens dinâmicas, erros de tipos são pegos somente tempo de execução, quando são pegos. Então, se ter uma boa bateria de testes automatizados é muito importante linguagens estáticas, liguagens dinâmicas é mais importante ainda. Testes automatizados é algo sempre muito bom de você escrever a medida que você está desenvolvendo seu código, você está escrevendo seus testes, particular linguagem dinâmicas, isso é muito importante. Linguagens estáticas tendem a ficar com o código mais extenso, redundante, porque você tem que definir todos aqueles tipos. São mais palavras que você tem que escrever. Na linguagem Java ou C ++, por exemplo, o código é muito o que a gente chama de verboso, tem que escrever muita coisa. Já linguagens dinâmicas tendem a ter o código mais enxuto, às vezes, código Python tem metade dos caracteres que o código Java correspondente. Códigos linguagens estáticas são pouco flexíveis. Se você tem que definir o tipo de tudo, o código que você escreveu só funciona para determinado tipo. Já linguagem dinâmica você pode escrever código super flexível que funciona com qualquer tipo, dentro de conjunto que satisfaça algumas condições. Inclusive pode ser código que funcione para tipo que ainda não foi criado, que vai ser criado no futuro. Você consegue escrever muito menos código, por isso fica mais enxuto também. Na linguagem estática é mais difícil mudar o programa tempo de execução e linguagens dinâmicas é muito fácil você mudar o programa, mudar sistema, carregando novas componentes a medida que o sistema está sendo executado. De uma forma geral, linguagens estáticas são mais paternalistas com o programador e linguagens dinâmicas oferecem mais liberdade para o programador. A gente vê que, na verdade, as linguagens não são todas totalmente estáticas ou totalmente dinâmicas, não é uma questão booleana. Na verdade, tem toda uma gama que vai desde a linguagem mais estática, por exemplo, Fortran ou C, até uma linguagem super dinâmica, como o Smalltalk ou Ruby ou Python. É todo espectro, não apenas se minha linguagem é dinâmica ou estática, tem várias características envolvidas. E a gente tem visto uma evolução nos últimos anos também. Linguagens estáticas têm incorporado conceitos de linguagens dinâmicas, por exemplo, Java e Scala têm essa reflexão computacional, Java você tem aprendido a reflexão que você pode fazer, o que a gente chama de introspecção, ver o estado atual do seu sistema e perguntar para determinado objeto quais são seus métodos, perguntar para método quais são seus parâmetros, inspecionar a estrutura do código tempo de execução. Java você não consegue facilmente mudar o código. Python você consegue acrescentar novo método tempo de execução. Java isso é mais difícil, você tem que usar outro mecanismo mais sofisticado que se chama manipulação de bytecode que é uma coisa mais complicada. Linguagens tipo C e C++, hoje dia, já têm a possibilidade de carga de bibliotecas dinâmicas. É jeito de você oferecer dinamismo numa linguagem que, normalmente, não é muito dinâmica, tipo C e C++. Você pode ter sistema execução e, dinamicamente, você carrega uma nova biblioteca que tem novas funções, novas classes. Isso é possível, hoje dia, também C e C++, não é tão fácil quanto Python e Java, mas é possível, funciona. A partir do Java 7, a máquina virtual de Java, a JVM, mudou para ter novo comando, que se chama Invoke Dynamic, que oferece suporte para linguagens dinâmicas. Então, hoje dia, as linguagens dinâmicas são executadas com bastante eficiência, também, cima da máquina virtual de Java. Por outro lado, linguagens dinâmicas têm, também, incorporados conceitos de linguagens estáticas. Por exemplo, Python, que é uma linguagem dinâmica, onde você não define os tipos das variáveis, desde de Python 3.5, tem uma coisa que se chama Type hints, que você pode dar dicas sobre quais são os tipos do seu código. Então, você pode escrever algo desse tipo, uma função soma, que recebe x e y, que x é do tipo inteiro e y é do tipo inteiro. E essa função devolve algo do tipo inteiro e daí vem o seu código. Se você rodar isso aqui no interpretador Python, ele ignora os tipos, ele não faz nada com essas dicas de tipos, por outro lado, tem esse programa mypy, que se você rodar o seu programa dentro desse mypy, passando por parâmetro mypy, ele vai fazer a checagem de tipos. Se não me engano, nesse caso, vai dar erro, porque isso aqui está devolvendo string, deveria estar devolvendo int. Imagino que ele vai falar isso, que deveria estar devolvendo intero e está devolvendo string. Ele permite você fazer a checagem de tipos num programa Python, algo bem interessante. Tem uma série de novas linguagens de programação, que estão aparecendo nos últimos cinco, dez anos e que têm uma série de características bem interessantes. Depois que você terminar esse curso e estiver sabendo tudo sobre orientação a objetos, eu recomendo que, além de saber as linguagens mais básicas, Java, Python, que grande parte das pessoas conhecem, pegue uma dessas novas linguagens que estão aparecendo, porque elas são muito boas, muito interessantes e, talvez, o futuro vai estar alguma dessas linguagens aqui. Então, por exemplo, Kotlin é uma linguagem que é compatível com Java, só que é muito mais concisa. Lembra que eu falei que Java era muito redundante, o código ficava muito extenso? Kotlin consegue fazer a coisa ficar bem mais concisa e está sendo muito utilizado para o desenvolvimento de aplicativos Android. Scala é uma linguagem também muito eficiente, é boa para programação concorrente, programação paralela, ela tem tipagem estática e permite tanto os paradigmas de orientação a objeto quanto programação funcional. Julia é uma linguagem muito utilizada programação científica, tem tipagem dinâmica e também permite os paradigmas OO e funcional. Já Haskell é uma linguagem conhecida por ser uma linguagem funcional com tipagem estática. Clojure é muito legal porque é uma linguagem similar a LISP, é dialeto moderno de LISP, mas roda totalmente no ambiente Java, cima da JVM, você pode usar todas as bibliotecas de Java. Então eu tenho visto algumas empresas desenvolvendo sistemas super complexos, poderosos, com bastante agilidade, com toda agilidade que as linguagens dinâmicas permitem mas, usando esse paradigma funcional num ambiente Java, então você pode reutilizar o que você já tem Java. Para quem gosta de linguagens não orientadas a objetos, tipo a linguagem C, procedimental pura, tem uma nova geração da linguagem C, que é a linguagem Go, que é bastante interessante e recomendo dar uma olhada para quem quiser fazer algo nessa linha. Já para quem gosta de C++, tem gosto para tudo nesse mundo, eu recomendo olhar a linguagem Rust, que eu diria que é a nova geração dessa família de linguagens C++. Estude uma dessas linguagens ou várias delas que você vai aprender novas coisas e, quem sabe, você vai decidir adotar uma delas para fazer os seus projetos. Outra coisa interessante para quem tem uma mente mais científica, eu sou professor universitário, cientista da computação e eu oriento mestrados e doutorados também nessa área de linguagem de programação, engenharia de software. Gosto bastante dessas e tem alguns artigos científicos que tratam dessa questão de linguagens dinâmicas versus estáticas, por exemplo, esse artigo aqui de 2018, desenvolveu uma teoria para tentar explicar como que os programadores fazem a escolha entre usar uma linguagem dinâmica ou uma linguagem estática. D depois eu vou passar a referência bibliográfica de tudo para quem quiser dar uma olhada. Esse outro artigo mostra, pelo menos no contexto que ele analisou, que código de linguagens estaticamente tipadas tendem a ser pouquinho mais limpos. Você tem que olhar o artigo para dizer qual é a definição dele de mais limpo e de pouquinho. Já esse outro artigo, faz estudo interessante, comparando código JavaScript, que é uma linguagem dinâmica e com tipagem dinâmica, como seria se aquele código fosse escrito na linguagem TypeScript, que é muito similar a JavaScript, mas tem tipagem estática e eles chegam a conclusão de que teria 15% menos de erros, outro estudo interessante. Esse outro estudo aqui, pouco mais antigo, de 2011, mostra que desenvolvedores são mais rápidos na maioria das tarefas de desenvolvimento de software quando eles estão usando linguagens dinâmicas, são mais eficientes. Tem vários estudos científicos, particular, se você quiser se aprofundar e fazer ciência nessa área, você pode pensar fazer mestrado ou doutorado nessa área, também é algo muito rico para pesquisas futuras. Sempre lembrando que cada estudo científico é feito num contexto muito específico. Você tem que ler o artigo para ver quanto daquilo é generalizável para outros contextos. Então, resumindo. Para finalizar, existe contínuo, desde a linguagem mais estática até a linguagem mais dinâmica, não é booleano. Tem várias gradações de dinamismo, não é uma abordagem que é claramente melhor ou pior, não faz sentido falar linguagens dinâmicas são melhores, linguagens estáticas são melhores, eu brinco que isso é uma briga religiosa, tem o pessoal que é da religião de linguagem estática e religião de linguagem dinâmica e a gente tem que ter uma abordagem científica, não religiosa. Determinados contextos vai fazer mais sentido usar uma linguagem dinâmica, outros vai fazer sentido usar uma linguagem estática. Depende do código que você está tendo, do ambiente computacional que você está trabalhando, das pessoas que você tem disponível para trabalhar na equipe de desenvolvimento. Tudo isso vai determinar se uma opção é melhor ou a outra opção é melhor. Cada programador tem a sua preferência. Eu, por exemplo, tendo a preferir linguagens dinâmicas, acho que porque eu tive muito trauma de escrever muito código C++ e Java e sofri muito com isso e depois, tive experiências melhores com Python, Ruby, Smalltalk. Por isso eu tenho essa minha preferência por linguagens dinâmicas mas isso é uma questão de gosto, não é uma questão científica. A gente tem que ter uma abordagem científica também desenvolvimento de softwares. Mas, os excelentes programadores vão saber se dar bem ambas as situações e vão saber decidir quando é melhor usar uma ou outra. Espero que vocês tenham gostado dessas reflexões sobre dinamismo linguagem de programação. Eu vou deixar essa bibliografia aqui e eu gostaria de agradecer três excelentes cientistas da computação que me ajudaram fornecendo informações para eu gravar esse vídeo. O Renato Cerqueira é cientista da computação que entende tudo de Middleware e da linguagem Lua também, por exemplo. Já o Maurício Aniche é cientista da computação que entende tudo de orientação a objetos e testes automatizados. E o Eduardo Guerra é cientista da computação que entende tudo sobre testes automatizados, arcabouços, frameworks, metadados, anotações código, três excelentes pesquisadores, cientistas e desenvolvedores de software. Obrigado a eles.