Vou viajar ao mundo dos betas .NET. Vale a pena porque as novidades parecem interessantes. Vou rumo ao desconhecido porque tenho pouca vivência com este outro mundo. Comentários corrigindo algo que não entendi direito serão muito bem vindos.
Siglas, quando acabo de aprender uma surge mais um monte. Algumas deixo de lado até que um dia fico curioso e procuro meu amigo google como fiz hoje. Queria saber o que é este tal de LINQ que a turma do .NET diz que é o futuro em termos de acesso de dados. Vou colocar aqui algumas coisas que aprendi navegando no google.
LINQ = Language INtegrated Query
1. Alo Mundo Velho como é hoje:
using System;
static class AloMundoVelho {
static void Main() {
string[] words = { "Alo", "Maravilhoso",
"Mundo", "Velho",
"Microsoft" };
// Pega palavras ate 5 letras e imprime
foreach (string word in words) {
if (word.Length <= 5)
Console.WriteLine(word);
}
}
}
2. Alo Mundo Linq quando puder usar o LINQ:
using System;
using System.Linq;
static class AloMundo {
static void Main() {
string[] words = { "Alo", "Maravilhoso",
"Mundo", "Linq",
"Microsoft" };
// Pega palavras ate 5 letras
var shortWords =
from word in words
where word.Length <= 5
select word;
// Imprime
foreach (var word in shortWords)
Console.WriteLine(word);
}
}
Mostrei o uso do LINQ acessando um array na memória do mesmo jeito que faria se fosse uma base de dados ou um XML.Por ser muito simplório, o uso do LINQ só complicou e isto é o que normalmente acontece quando a gente adota um padrão genérico, como o bridge, por exemplo. Na medida em que as consultas se complicarem, as vantagens do LINQ prevalecerão.
O LINQ define um conjunto de operadores de consultas padronizados que permitirá filtrar, enumerar e criar projeções de vários tipos de collections usando a mesma sintaxe. Tais collections podem incluir arrays, classes enumeráveis, XML, datasets oriundos de bancos de dados e outras fontes de dados. Os operadores fornecem um meio uniforme de obter dados a partir de qualquer objeto que implemente a interface IEnumerable
Abaixo mais um exemplo onde aparece o uso de uma expressão de consulta (query expression). Reparem na inicialização da variável local expr :
using System;
using System.Query;
using System.Collections.Generic;
class Gujeiros {
static void Main() {
string[] nomes = { "Paulo", "Philip",
"Fabio", "Carlos",
"Guilherme", "Daniel",
"Meyer", "Luca",
"Mauricio", "Louds",
"Rafael", "thingol"};
IEnumerable<string> expr =
from s in nomes
where s.Length == 5
orderby s
select s.ToUpper();
foreach (string item in expr)
Console.WriteLine(item);
}
}
Nenhum dos exemplos mostra, mas é preciso deixar claro que a solução não pretende esconder a base de dados como faz o Hibernate. E é claro também que o Java não tem nada parecido com isto.
Sem o LINQ, o atual programador .NET precisa conhecer e usar linguagens como SQL, XML ou XPath, várias tecnologias e APIs como ADO.NET ou System.Xml. Isto não será mais necessário com os programas escritos em linguagens que incluem o LINQ. Para o programador menos avançado o LINQ pode ser considerado o que se chama de syntatic sugar, isto é, alguma coisa que se acrescenta sem afetar a funcionalidade e apenas torna mais "doce" o seu uso ou entendimento.
O LINQ tem uma outra faceta que pode ser novidade para alguns programadores .NET: o mundo dele é strongly-typed. As vantagens imediatas do uso do LINQ é que as consultas serão verificadas em tempo de compilação e o programador ainda pode se beneficiar das sugestões do VisualStudio IntelliSense.
O LINQ se posiciona um passo acima da programação declarativa comum e é aqui que começo a escrever algo que tem a ver com o título deste blog. Como disse no meu texto anterior sobre linguagens funcionais, SQL é uma linguagem funcional. Só pela a inclusão do LINQ nas linguagens do .NET, já há um toque nelas de linguagem funcional. Porém, o LINQ usado com o C# 3.0, tem mais características de linguagem funcional porque o próprio C# 3.0 inclui novidades oriundas das linguagens funcionais.
Novidades do C# 3.0 (em cinza o que não é exatamente oriundo de linguagens funcionais):
- Local Variable Type Inference - é o var que mostrei no exemplo Alo Mundo. Exemplos de var:
- var i = 5; // equivalente a: int i = 5;
- var s = "isto eh uma string"; // equivalente a: string s = "isto eh uma string";
- Extension Methods (adiciona novas funções aos métodos existentes sem editar o fonte da classe)
- Anonymous Types
- Objects & Collections Initializers (dispensa múltiplos construtores)
- Lambda Expressions
É o cálculo lambda oriundo das linguagens funcionais e que existe no Lisp, Ruby e Phyton. Exemplo:
Funcincremento = i => i + 1;
Incremento(5); // o resultado é 6 - Expression Trees - representa Lambda Expressions como estrutura de dados
- Is C# becoming a functional language?
- Infoq-Is C# becoming a functional language?
- Linq, Functional Vs Declarative programming
A Microsoft está incluindo facilidades das linguagens funcionais na sua plataforma. Aliás, ela pesquisa sua própria linguagem funcional baseada em coisas do Phyton, ML, OCaml, MATLAB, Scheme e do próprio C#. O site de pesquisa da F# descreve o seguinte objetivo: Combining the efficiency, scripting, strong typing and productivity of ML with the stability, libraries, cross-language working and tools of .NET. E mais: F# is a programming language that provides the much sought-after combination of type safety, performance and scripting, with all the advantages of running on a high-quality, well-supported modern runtime system.
E a Sun? Bem, como disse antes as closures vem aí. Volta e meia alguém suspira por continuations. Já li que algumas sonhadas facilidades das linguagens funcionais seriam difíceis de incluir com segurança na JVM e continuations é uma delas.
Mas se o Java está limitado, se pode procurar outros caminhos. A possibilidade de rodar scripts na JVM e ainda usar dentro do código Java, oferece algumas perspectivas de estender o Java. Na linha de pesquisa deste blog, se alguém tiver know how, tempo e coragem, vale a pena experimentar alguns engines do scripting.dev.java.net. Lá tem engine para Haskell e Scheme com Jaskell e SISC respectivamente, Phyton com Jhyton, Ruby com JRuby e o Groovy.
Conclusão e recomendação:
Como disse no outro post, mudanças estão acontecendo e algumas novidades vem justamente das linguagens funcionais. Conhecer um pouco de uma delas não toma tanto tempo assim e pode ter a sua utilidade mesmo que não seja você um Neal Gafter, Doug Lea ou um Gilad Bracha. No mínimo você estará preparado para entender o que vem por aí.
Duas alternativas de linguagens funcionais que me atraem são erlang e Scala. Ambas tem seu valor e são adequadas para processos concorrentes. Escolhi começar pelo erlang que é uma linguagem funcional do tipo do Haskel e é orientada para concorrência. Parece muito adequada para o hardware de hoje em que os processadores estão crescendo mais rapidamente de tamanho do que na capacidade de processamento. O aumento de tamanho é porque as CPUs agora tem mais núcleos sendo já comuns os processadores dual core e quad core. Em breve isto irá longe e haja software para explorar. Estou apostando no erlang com a crença de que com ele será mais fácil encarar o desafio de usar corretamente estas facilidades de hardware. Espero que o erlang me dê também as noções mínimas de programação funcional que acho necessárias para seguir entendendo as mudanças no mundo do desenvolvimento de sistemas.
6 comentários:
Não tinha lido nada sobre LINQ e "a primeira vista" achei bacana. Belo post!
Oi Luca. Primeiro queria dar parabéns por finalmente começar a bloggar :). Agora estou me sentindo culpado que meu blog está às moscas.
Eu gostei do artigo, a tecnologia do LINQ é bem promissora, apesar do mal de origem. Eu não sei bem como as expressões LINQ se encaixariam no meio de um modelo de domínio OO tradicional; imagino que ainda seja necessário alguns anos de experiência para que se desenvolvam boas práticas.
Tenho a impressão que o primeiro item da lista de funcionalidades do C# é sim oriundo da programação funcional; acho que Inferência de tipo vem de ML. E a relação entre lambda-expressions e cálculo lambda não é muito direta (acho que Guy Steele cunhou o nome quando estava fazendo Scheme, chamando os Procedure Values de Lambda Expressions para enfatizar o escopo léxico).
Eu ando brincando bastante com Scala e uma novidade que vai aparecer logo é a adição de Structural Subtyping, estilo Anonymous Types do C#, permitindo fazer coisas parecidas com o LINQ. Ainda não tem Expression Trees, mas dá para simular como uma espécie de DSL; a biblioteca de acesso a BD em scala já faz algo assim hoje.
Último comentário: não sei se Erlang é tão parecido com Haskell assim, já que é dinâmicamente tipado e usa avaliação estrita (o Haskell é *bem* estáticamente tipado e tem lazy evaluation).
Abraços e estou aguardando os próximos posts.
Rafael
Obrigado pelas observações.
Na verdade este post foi como uma espécie da notas de aula escritas ainda sem conhecer muito bem sobre o que estava escrevendo. Daí esperava mesmo que alguém me corrigisse em algumas coisas.
Li em algum lugar sobre a semelhança entre o Haskell, sobre o qual nada sei, e o erlang que estou apenas entrando no capítulo 3 do livro. Repeti pois acreditei no que li sem muitas condições de saber se era verdade ou não.
Bom, como eu disse no GUJ, tenho medo de Haskell :)
Rafael
Alterei a cor do texto no que concerne a inferência de tipo pois realmente vem das LFs. Obrigado.
Luca, acabei de ler esta notícia na InfoQ que me remeteu imediatamente a este post seu. A notícia trata de Quaere, uma iniciativa da comunidade que emula funcionalidades do LinQ em Java. Que somprem os ventos da mudaça e que Darwin vença :)
http://www.infoq.com/news/2007/09/quaere-linq
Postar um comentário