Ultimamente tem sido crescente a discussão sobre JavaScript e linguagens que "compilam" para JavaScript, como CoffeeScript, TypeScript e outras. Já testei algumas dessas linguagens e todas elas, na minha opinião, são incrivelmente superiores em muitos aspectos ao JavaScript.
Outra questão que vejo ser abordada com frequência recentemente é o uso de Node.js, um framework realmente fantástico, performático, incrivelmente escalável e totalmente assíncrono. Mas que no entanto só entende uma linguagem: JavaScript. Obviamente as linguagens que compilam para JavaScript podem ser usadas ao se trabalhar com Node.js, mas nativamente não são suportadas, ainda.
Outro ambiente de execução que tem sido muito bem avaliado é a máquina virtual Erlang. No entanto, a linguagem Erlang em si é monstruosamente horrorosa e até o momento a melhor tentativa de ser executar uma outra linguagem sobre essa máquina virtual tem sido a Elixir.
No caso da gigante JVM, já faz algum tempo que a comunidade Java começou a admitir que a linguagem Java é uma linguagem verbosa demais, improdutiva e deficiente em muitos aspectos. Como resposta a isso surgiram Scala, Groove, Clojure, Kotlin. Todas essas, linguagens que são executadas sobre a JVM, trazendo muitas vantagens quando comparadas com sua matriarca, Java.
No mundo .NET, diversas linguagens em um único ambiente de execução já é algo que existe desde sua concepção e com certeza parte da inspiração para a criação de novas linguagens executando sobre a JVM e compilando para JavaScript vieram dai.
A competição, a necessidade e principalmente a insatisfação tem levado ao surgimento de ao menos uma nova linguagem a cada ano, no entanto falta a essas linguagens, e principalmente a suas máquinas virtuais, a visão de que para ganhar mercado, a linguagem não precisa ser apenas universal e performática, precisa também ser produtiva, agradável de se usar.
Imaginem poder executar CoffeeScript diretamente sobre o Node.js ou nos navegadores web, ou código Ruby ou C# sobre a máquina virtual Erlang. Certamente o crescimento e a popularidade desses ambientes cresceria bastante.
Isso me lembra o projeto Singularity, mas isso fica para um próximo post.
Mostrando postagens com marcador c#. Mostrar todas as postagens
Mostrando postagens com marcador c#. Mostrar todas as postagens
terça-feira, 18 de junho de 2013
quarta-feira, 29 de maio de 2013
C#, Java e os Enums - Parte 2
No último post falei sobre os enums do C#, os enums do Java, suas origens e algumas de suas peculiaridades. Neste post apresentarei um State específico para usarmos como estudo de caso e farei referência a dois repositórios do GitHub que implementam o padrão State do zero em cada uma dessas linguagens.
Abaixo está definido o State OnOff, o qual usaremos como estudo de caso.
Esse State representa dois estados concretos: ligado e desligado. Cada estado possui uma propriedade (displayText) e um manipulador (swtch).
A implementação foi feita em Java, utilizando os enums introduzidos no Java 1.5.
A mesma implementação sem o uso dos enums do Java 1.5 poderia ser feita conforme pode ser visto neste repositório no GitHub. Não apresentarei o código completo aqui para não tornar o texto extenso demais.
Visitando o repositório acima você verá que seriam necessários três arquivos, um para o estado abstrato e um para cada estado concreto. Uma implementação bastante trabalhosa.
Implementar esse mesmo State em C# não seria muito diferente e tal implementação pode ser encontrada neste outro repositório. No entanto nesse caso apenas um arquivo seria suficiente, contendo os estados concretos como tipos internos ao estado abstrato.
Além disso, algumas outras peculiaridades diferem a implementação Java da implementação C#. No próximo post falarei um pouco a respeito dessas peculiaridades e apresentarei alguns recursos da linguagem C# que podem tornar essa implementação bem diferenciada.
Abaixo está definido o State OnOff, o qual usaremos como estudo de caso.
Esse State representa dois estados concretos: ligado e desligado. Cada estado possui uma propriedade (displayText) e um manipulador (swtch).
A implementação foi feita em Java, utilizando os enums introduzidos no Java 1.5.
public enum OnOff {
ON {
@Override
public String displayText() {
return "Ligado";
}
@Override
public OnOff swtch() {
return OnOff.OFF;
}
},
OFF {
@Override
public String displayText() {
return "Desligado";
}
@Override
public OnOff swtch() {
return OnOff.ON;
}
};
public abstract OnOff swtch();
public abstract String displayText();
}
Essa implementação satisfaz ao padrão state e possui a representação enxuta que apresentei no post anterior mas para isso foram necessárias alterações significativas na linguagem.A mesma implementação sem o uso dos enums do Java 1.5 poderia ser feita conforme pode ser visto neste repositório no GitHub. Não apresentarei o código completo aqui para não tornar o texto extenso demais.
Visitando o repositório acima você verá que seriam necessários três arquivos, um para o estado abstrato e um para cada estado concreto. Uma implementação bastante trabalhosa.
Implementar esse mesmo State em C# não seria muito diferente e tal implementação pode ser encontrada neste outro repositório. No entanto nesse caso apenas um arquivo seria suficiente, contendo os estados concretos como tipos internos ao estado abstrato.
Além disso, algumas outras peculiaridades diferem a implementação Java da implementação C#. No próximo post falarei um pouco a respeito dessas peculiaridades e apresentarei alguns recursos da linguagem C# que podem tornar essa implementação bem diferenciada.
sexta-feira, 24 de maio de 2013
C#, Java e os Enums - Parte 1
Enums, ou enumerações, são tipos de dados cujo valor é atribuído a exatamente um elemento de um conjunto finito.
Nos velhos tempos do Delphi, enums eram muito conhecidos e usados, sendo declarados conforme abaixo:
Nos velhos tempos do Delphi, enums eram muito conhecidos e usados, sendo declarados conforme abaixo:
type TSuit = (Hearts, Diamonds, Clubs, Spades); var ASuit : TSuit; ASuit := Hearts;
Uma variável declarada como sendo do tipo TSuit poderia assumir exclusivamente um dos valores determinados em tal conjunto.
Com o advento da linguagem Java, enums não se mostraram presentes, e foram uma das grandes faltas sentidas por aqueles que migraram para essa nova linguagem.
Posteriormente, com o surgimento da linguagem C#, enums foram trazidos de volta à cena, com características bem semelhantes ao antigo enum do Delphi.
A linguagem Java resistiu à introdução dos enums durante algum tempo, mas quando a trouxe, o fez de forma que enums poderiam tanto ser vistos como um simples conjunto de valores:
Implementar o padrão de projeto State em C# é semelhante a implementá-lo em Java, sem fazer o uso de seus enums, claro. No entanto a construçao é tão elaborada que torna seu uso bastante desestimulante, principalmente diante dos simples enums que a linguagem oferece.
Lançando mão de recursos como generics e classes parciais, realizei um implementação um pouco mais elaborada do padrão State em C#, algo que remete bastante ao formato visto nos enums do Java.
Nos próximos posts apresentarei essa implementação e farei algumas comparações entre ela e a implementação java.
Com o advento da linguagem Java, enums não se mostraram presentes, e foram uma das grandes faltas sentidas por aqueles que migraram para essa nova linguagem.
Posteriormente, com o surgimento da linguagem C#, enums foram trazidos de volta à cena, com características bem semelhantes ao antigo enum do Delphi.
enum Suit { Hearts, Diamonds, Clubs, Spades }
Suit suit = Suit.Hearts;
Junto com a simplicidade herdada do Delphi, vieram suas limitações. Não era possível declarar métodos em um enum, nem para o tipo como um todo e nem para seus valores. Não era possível também sobrescrever seus operadores, um importante recurso apresentado como diferencial pela linguagem C#.A linguagem Java resistiu à introdução dos enums durante algum tempo, mas quando a trouxe, o fez de forma que enums poderiam tanto ser vistos como um simples conjunto de valores:
enum Suit { HEARTS, DIAMONDS, CLUBS, SPADES }
Suit suit = HEARTS;
Quanto uma implementação completa do padrão de projeto State:enum ShippingMethod {
FIRST_CLASS {
public double shippingCost(double weight, double distance) {
...
}
},
FED_EX {
public double shippingCost(double weight, double distance) {
...
}
},
UPS {
public double shippingCost(double weight, double distance) {
...
}
};
public abstract double shippingCost(double weight, double distance);
};
O que possibilita construções bastante elaboradas, sem dúvida algo muito mais rico e útil que os enums do C#.Implementar o padrão de projeto State em C# é semelhante a implementá-lo em Java, sem fazer o uso de seus enums, claro. No entanto a construçao é tão elaborada que torna seu uso bastante desestimulante, principalmente diante dos simples enums que a linguagem oferece.
Lançando mão de recursos como generics e classes parciais, realizei um implementação um pouco mais elaborada do padrão State em C#, algo que remete bastante ao formato visto nos enums do Java.
Nos próximos posts apresentarei essa implementação e farei algumas comparações entre ela e a implementação java.
domingo, 28 de abril de 2013
Dynamic Method Binding
Já não é novidade que a partir da versão 4 do .NET Framework e da linguagem C# é possível declarar objetos com tipagem dinâmica. Veja este link para mais detalhes.
Em C#, quando um objeto é declarado como dynamic, o compilador nos permite invocar qualquer método a partir desse objeto, sem checar em tempo de compilação se este método existe ou não. Esse recurso é conhecido como Dynamic Method Binding e apenas em tempo de execução o Framework irá informar, através de uma exceção, que o método invocado não existe.
Exemplo:
Imagine escrever um conjunto de métodos privados sobrecarregados, cada um tratando um tipo específico de entrada e delegar a um único método público a função de decidir qual dos métodos privados deve ser executado.
O exemplo abaixo faz isso:
Veja como esse mesmo código ficaria se utilizássemos tipagem dinâmica para deixar que o .NET Framework decida em tempo de execução qual a versão do método GenusFor deve ser executada:
Usando ((dynamic)this), informamos ao compilador que queremos que o this seja tratado como um tipo dinâmico, assim a existência de um método GenusFor com os parâmetros informados não será verificada em tempo de compilação.
Em tempo de execução, o CLR irá procurar por um método chamado GenusFor no objeto this e encontrará 4 sobrecargas, 1 pública e 3 privadas. Nesses casos, o comportamento do CLR é utilizar o método cujos tipos dos parâmetros esperados sejam o mais próximos possíveis dos parâmetros passados. Isso faz com que o método correto seja invocado, conforme o tipo de IAnimal recebido como parâmetro.
Interessante, não? No entanto lembre-se que recursos poderosos como esse devem ser usados com muita cautela. Brinque um pouco com o código disponível no GitHub e veja o impacto positivo e negativo que esse tipo de abordagem pode trazer.
Confira também o uso desse recurso em um dos exemplos citados no livro Implementing Domain-Driven Design, de Vaugh Vernon.
Abraços.
Em C#, quando um objeto é declarado como dynamic, o compilador nos permite invocar qualquer método a partir desse objeto, sem checar em tempo de compilação se este método existe ou não. Esse recurso é conhecido como Dynamic Method Binding e apenas em tempo de execução o Framework irá informar, através de uma exceção, que o método invocado não existe.
Exemplo:
dynamic objetoDesconhecido = ObtemObjetoDesconhecidoDeAlgumLugar(); objetoDesconhecido.MetodoQueNaoExiste(); // Compila mas não executaNão quero discutir aqui o propósito dessa inclusão à linguagem, quero apenas apresentar uma construção bastante interessante permitida com o uso desse recurso.
Imagine escrever um conjunto de métodos privados sobrecarregados, cada um tratando um tipo específico de entrada e delegar a um único método público a função de decidir qual dos métodos privados deve ser executado.
O exemplo abaixo faz isso:
public class Taxonomy
{
public string GenusFor(IAnimal animal) {
if (animal is Lion)
return GenusFor((Lion)animal);
if (animal is Zebra)
return GenusFor((Zebra)animal);
if (animal is Elephant)
return GenusFor((Elephant)animal);
return null;
}
private string GenusFor(Lion lion) {
return "Lion";
}
private string GenusFor(Zebra zebra) {
return "Zebra";
}
private string GenusFor(Elephant elephant) {
return "Elephant";
}
}
O código acima pode parecer desnecessário se considerarmos que o genero do animal poderia ser uma simples propriedade da interface IAnimal, no entanto serve bem para ilustrar a ideia.
Veja como esse mesmo código ficaria se utilizássemos tipagem dinâmica para deixar que o .NET Framework decida em tempo de execução qual a versão do método GenusFor deve ser executada:
public class Taxonomy
{
public string GenusFor(IAnimal animal) {
return ((dynamic)this).GenusFor((dynamic)animal);
}
private string GenusFor(Lion lion) {
return "Lion";
}
private string GenusFor(Zebra zebra) {
return "Zebra";
}
private string GenusFor(Elephant elephant) {
return "Elephant";
}
}
Usando ((dynamic)this), informamos ao compilador que queremos que o this seja tratado como um tipo dinâmico, assim a existência de um método GenusFor com os parâmetros informados não será verificada em tempo de compilação.
Em tempo de execução, o CLR irá procurar por um método chamado GenusFor no objeto this e encontrará 4 sobrecargas, 1 pública e 3 privadas. Nesses casos, o comportamento do CLR é utilizar o método cujos tipos dos parâmetros esperados sejam o mais próximos possíveis dos parâmetros passados. Isso faz com que o método correto seja invocado, conforme o tipo de IAnimal recebido como parâmetro.
Interessante, não? No entanto lembre-se que recursos poderosos como esse devem ser usados com muita cautela. Brinque um pouco com o código disponível no GitHub e veja o impacto positivo e negativo que esse tipo de abordagem pode trazer.
Confira também o uso desse recurso em um dos exemplos citados no livro Implementing Domain-Driven Design, de Vaugh Vernon.
Abraços.
Assinar:
Postagens (Atom)