Tendências em Linguagens de Programação


Hoje, no universo das linguagens de programação, fica clara a existência de uma fricção entre três dimensões distintas: 1) entre o mundo tipado e o não tipado; 2) entre o imperativo e o funcional; 3) entre linguagens específicas e linguagens genéricas.


Como trabalhei em projetos muito grandes, tendo a usar linguagens imperativas, genéricas e fortemente tipadas (como o C#), mas fico contente com a volta das linguagens sem tipos como Ruby ou Phyton. De certa forma, vejo estas linguagens forçando as linguagens tipadas a incorporar novos mecanismos que as tornem mais ágeis. Um exemplo claro disto é a incorporação da inferência de tipos tanto em VB quanto em C#, levando a uma simplificação no código (parece que o mesmo vai acontecer com o C++).


Linguagens funcionais é um caminho interessante para procurar novas tendências. Elas foram as primeiras a incorporarem os mecanismos de inferência de tipos e de “comprehensions” (como as cláusulas where do Linq) e trazem características declarativas que podem ser úteis para que os compiladores possam achar oportunidades de paralelismo. Elas têm algo da economia de linguagens não tipadas, com a precisão de tipos das linguagens tipadas. Por isto é grande a sua influência atual no design de linguagens.


Ainda sobre as linguagens funcionais, percebo que nem todos compreendem que elas funcionam a partir de regras de reescrita, o que as torna bem diferentes das demais. Por exemplo, em F# podemos definir uma função que retorna a soma entre dois números da seguinte forma:


> let add (x, y) = x+y;;


val add : int * int -> int


Como nas linguagens imperativas, podemos chamar add passando parâmetros:


> add (3,4);;


val it : int = 7


Mas existe uma forma chamada de curried (em homenagem ao matemático Haskell Curry) que pode ser definida na própria linguagem F#. Para isto precisamos apenas de um novo operador


> let curry f x y = f (x, y);;


val curry : ('a * 'b -> 'c) -> 'a -> 'b -> 'c


Esta forma de chamada nos permite tanto tirar os parêntesis na passagem de parâmetros (como abaixo)


> curry add 3 4;;


val it : int = 7


como nos permite definir uma nova função reutilizando nosso add de uma forma muito simples:


> let succ = curry add 1;;


val succ : (int -> int)


Com esta definição, podemos chamar a nova função succ como abaixo


> succ 4;;


val it : int = 5


Creio que este exemplo já dá um gostinho do poder de reescrita de uma linguagem funcional.


Interessante também é a perspectiva das linguagens específicas de domínio (DSL’s). Penso que, de certa forma, toda biblioteca ou framework gostaria de ser uma. Este conceito influenciou Ruby on Rails e atualmente influencia o projeto Oslo para modelagem de SOA da Microsoft. Vale a pena uma checada.


Para finalizar: esta disponível os vídeos do último simpósio do Lang.Net em http://langnetsymposium.com/. Este é um simpósio bem interessante entre experts no tema. Pena não haver tradução...


Dos que vi (e vi poucos) e recomendo:



  • a do Lars Bark que fala da otimização do JScript no Chrome (V8);

  • a do Erik Meijer sobre Observers;

  • e a do David Langworthy sobre Oslo (devo fazer um WebCast sobre Oslo e vou usar o exemplo dele…);

Bom simpósio.

Skip to main content