segunda-feira, 23 de novembro de 2015

Swift: Brincando com Enum

E aí galera, tudo de boa?
Tô há um tempão sem escrever! Mas estou com algumas novidades, atualmente estou trabalhando com mobile, no Elo7 e claro não desisti do funcional, ando estudando haskell de uma forma um pouco mais compromissada, todas as quintas-feiras estou participando de um dojo de haskell, quem quiser, só mandar um email no abner.terribili@gmail.com ou se caso estiver muito longe e queira participar de longe, aceitamos pull requests em wando-hs :)

Para estrear o mobile aqui no Hackeando, que tal conhecermos o poder do Enum no Swift?

O que é Enum?

Enum, no Swift, nada mais é do que a definição de um tipo para um grupo de valores que têm alguma relação.

Abstrato né?

Imagine que você precisa filtrar uma lista, é um exemplo meio recorrente no meu dia a dia, por isso o escolhi. Então, temos uma lista de jogos, e desejo filtrar por plataforma, o enum em Java, seria algo do tipo:

enum GameFilter {
  PS3("playstation3"),
  PS4("playstation4"),
  XBOX360("xbox360"),
  XBOX_ONE("xboxOne");

  final String tag;
  GameFilter(String tag) {
    this.tag = tag;
  }

  @Override
  public String toString() {
    return tag;
  }
}

O tag aí serve para podermos pegar o valor que será aplicado no momento de filtro, ou seja, para montar a url:

www.lojadejogos.com/jogos?plataforma=playstation3

Podemos ver que, usando Java, precisamos de uma pequena field auxiliar para guardarmos o valor da tag. Vamos dar uma olhadinha no GameFilter construído em Swift:

enum GameFilter: String {
  case PS3 = "playstation3"
  case PS4 = "playstation4"
  case XBOX360 = "xbox360"
  case XBOX_ONE = "xboxOne"

  func description() -> String {return self.rawValue}
}

São quase iguais né? Com a diferença que ao invés de uma field auxiliar para armazenar o valor da tag, nós baseamos nosso enum em String.

Isso é muito chato e básico!

Vamos fazer algo mais legal, imagina que você quer ter um pouco mais de segurança com o que você trabalha (se costuma programar, já deve ter tomado um NullPointerException na cara), semântica e é hipster, sendo assim decidiu implementar um Optional na mão, isso tem fins didáticos, pois no Swift já temos uso extensivo de Optional.

Então temos nosso enum:

enum Optional<T> {
    case None
    case Some(T)

    init(_ value: T) {
        self = .Some(value)
    }

    init() {
        self = .None
    }

    func getOrElse() -> Any {
        switch self {
        case .Some(let value):
            return value
        default:
            return Optional.None
        }
    }
}

Na linha enum Optional<T> {..} nós definimos o nome do Enum, e declaramos um tipo genérico que será usado para inferir o tipo.

Com isso nós implementamos dois construtores, um que recebe um valor qualquer init(_ value: T) {self = .Some(value)} e outro que não recebe nenhum argumento: init() {self = .None}, fica meio maluco esse bind self=**, mas entenda, estamos atribuindo o valor da instância de acordo com o construtor que é usado. :)

E por fim, definimos um método que devolve qualquer coisa (Any), o objeto que está envelopado ou um Optional.None, e que faz a validação pra gente a respeito da instância que está chamando o getOrElse().

Para usarmos nosso Optional é simples:

let none = Optional()
none.getOrElse() //-> ()

let some = Optional(10.0)
some.getOrElse() //-> 10

Podemos ver que o construtor vazio devolve None, ou seja, nada, já o construtor que tem parametro, devolve o valor que foi passado, e olha que legal o Generics funcionando no Swift!

E aí, deu pra sentir a força do enum no Swift? E da pra fazer MUITO mais. Isso é só o básico :)

Só pra finalizar, se você já deu uma olhadinha de leve em Swift, com certeza o conceito de Optional não passou batido, pra nossa implementação ficar bacanuda, o que acham de implementarmos o sufixo para fazer unwrap do valor?

postfix operator *? {}
postfix func *? <T>(value: Optional<T>) -> Any {
    return value.getOrElse()
}

O código não é tão claro, mas basicamente estamos definindo um operador, do tipo sufixo, ou seja, que é utilizado no fim da expressão. Algo como:

Optional("xablau")*? //-> "xablau"

E por hoje é só galera, se rolar alguma dúvida ou sugestão, só comentar abaixo ou me enviar um email
Abraços

segunda-feira, 4 de agosto de 2014

Açúcar Sintático com Extension Methods no C#

Fala galera, tudo tranquilo?
Essa semana me empolguei nos Extensions Methods de C# e resolvi escrever a respeito!


Extension Methods


Os Extension Methods surgiram com o intuíto de te auxiliar na hora do desenvolvimento. Ele resolvem um problema dos grandes, permitem que você adicione métodos a tipos de dados já existentes. Evitando assim, que você tenha que criar um novo tipo.
Existe uma biblioteca muito famosa no C# que se chama LINQ no qual implementa diversos extension methods para trabalharmos com IENumerable.

Bom, mas como de costume, existem fontes mais detalhadas a respeito Extension Methods, se puder, invista uns 15 minutos lendo.

Vamos a prática? É bem simples! Criei um projetinho Class Library no Visual Studio, e adicionei algumas dependências que já estou acostumado a usar: FluentAssertions e NUnit.
Primeira classe:

public static class Ext
{
    public static int Soma(this int x, int y)
    {
        return x + y;
    }
       
    public static string RecortarEColar(this string s, string old, string neww)
    {
        return s.Replace(old, neww);
    }
}

E como usamos esses métodos?


public class extTest
{
    [Test]
    public void DeveSomar()
    {
        234.Soma(266).Should().Be(500);
    }
    [Test]
    public void DeveTrocar()
    {
        "Extension Methods são fodas".RecortarEColar("fodas", "úteis").Should.Be("Extension Methods são úteis");
    }
}


Simples de usar e entender. Mas por que os métodos são estáticos? Eles são apenas um Açucar Sintático, servem para deixar o código mais legível! Assim como o Should().Be()... Na Real o que o compilador faz é tornar o código acima parecido com isso:
      
    Ext.Soma(234, 266);
    Ext.RecortarEColar("Extension Methods são fodas", "úteis");


E aí qual ficou mais legível, nosso código acima, ou o clássico chama a classe estática e seu método e passamos os parâmetros?

Por hoje é isso aí galera. Abraços


sexta-feira, 20 de junho de 2014

Mais Polimorfismo (Haskell)

Fala galera, tudo tranquilo?

Bom, hoje vou levantar um dos assuntos que mais falo a respeito no Blog: Polimorfismo. Mas vamos estudar um pouco disso no Haskell. Certo?

Haskell incorpora alguns tipos polimórficos, as expressões de tipos polimórficos, na essência, descrevem famílias de tipos. Por exemplo, uma lista de caracteres ['h', 'a', 's', 'k', 'e', 'l', 'l'] , uma lista de inteiros [1,1,2,3,5,8] e podemos chegar até na lista de lista de caracteres [['a'], ['b'], ['c']], ou seja, todas essas listas compartilham da mesma família de tipos. Mas, no Haskell, temos uma pequena restrição, uma lista que foi determinada para ser usada com Inteiros, não pode receber um caracter. (Ex.: [1, 'b'])

Ao definirmos uma função que utiliza tipos polimórficos, definimos uma função genérica. Como exemplo abaixo:
   length [] = 0
   length (a:x) = 1 + length x 

Com essa função podemos ver claramente que independente do tipo de dado que for utilizado, conseguiremos usa-lo como parametro para a função que calcula o tamanho da lista. E você sabe dizer qual o retorno da função acima?
 Prelude> :t length
          length :: [a] -> Int

O a é uma variável do tipo polimórfica. A função length é uma função genérica.

O sistema de tipos Haskell possui duas propriedades: - Toda expressão bem tipada é garantida por ter um único tipo genérico. - O tipo genérico ou mais geral pode ser inferido automaticamente.

Lembrando que, no Haskell temos uma linda type inference(Inferência de tipos), mesmo que você possa definir o tipo de uma função, o Haskell o faz:
    soma :: Int -> Int -> Int
    soma x y = x + y

No entanto a função acima pode ser escrita somente pela segunda linha, usando assim o type inference do Haskell.

Por hoje é só, escrevi esse post porque acordei cedo e estava sem sono rs. No próximo, vou falar do Polimorfismo ad hoc.

Abraços!

quinta-feira, 22 de maio de 2014

Já testou seu código Javascript? Jasmine!

Fala aí galera, tudo tranquilo?

Você certamente já brincou ou trabalhou com Javascript, mas já testou o que você fez? E saiba, não estou falando de testes manuais. hehe

Em algum momento dos meus atuais exercícios com o Jonas aqui na Lambda, ele me apresentou o Jasmine que é um framework de teste para Javascript, que rola seguindo uma técnica de desenvolvimento Ágil, chamada BDD(Behavior Driven Development), mas como não é o foco, não entrarei em maiores detalhes.

Jasmine

Vamos diretamente a prática, baixe o arquivo do Jasmine no Github deles.
Abra esse arquivo, que é um diretório, abra a pasta spec e crie um novo arquivo "testando-soma.js". Feito isso, vamos abrir o arquivo e criar uma função de soma em Javascript:

 function soma(x, y){
    return x + y;
}

Agora vamos escrever um teste para essa função básica:
 
describe("Dado a soma de 2 e 1:", function(){
    it("O retorno deve ser 3.", function(){
        var resultado = soma(2, 1);
        expect(resultado).toBe(3);
    })
}

Entendendo Basicamente na primeira linha describe, nós descrevemos nossa função, na segunda linha it definimos o que deveria ser o resuldado. Já ali na quarta linha expect nós inspecionamos a variável resultado e com o toBe(), veja como Ser. Ou seja, o resultado esperado deve ser 3.
Agora teste você mesmo, abra o arquivo SpecRunner.html, com o seu navegador, e verá o resultado do seu teste. Mas antes, já que você não vai ver nenhum resultado do seu teste, e o motivo é simples, com o seu editor padrão, abra o arquivo SpecRunner.html e inclua a linha:

 <script type="text/javascript" src="spec/testando-soma.js"></script>

Feito isso, nosso arquivo javascript, escrito acima, será carregado e poderá passar pelos testes.
Bom, agora vamos escrever um teste mais legal certo?
Vamos reverter uma string, então bora escrever o teste primeiro:

 describe("Dado a string 'Asdrubal' a reversão:", function(){
    it("O retorno deve ser laburdsA.", function(){
        expect(reverse("Asdrubal").toBe("laburdsA");
    }); 

});

Agora vamos escrever a função:

 function reverse(texto){
    return texto.split("").reverse().join(""); 
}

No código acima, fizemos um split para pegar cada letra e transformar num array de char, depois usamos o reverse para reverter esse array e, por fim, o join para montar novamente uma string, coisa básica. Mas já é um teste mais legal :). Não deixe de conferir a documentação e a Introdução, mas é claro, não se prenda ao Jasmine, apenas a idéia de testar seu código já é sensacional, ou não!

Dica para os JS testers: Mocha.

Valeu Galera!


terça-feira, 22 de abril de 2014

Vi IMproved, mais conhecido como Vim!

Fala galera, tudo bom?

Há um tempo atrás prometi que iria falar a respeito do editor de texto Vim, e hoje o assunto é esse.
Para começar, que tal instalar o Vim no seu pc/mac?

Quem tem Linux ou MacOS como Sistema Operacional, muito provavelmente já vem instalado, só ir até terminal e digitar:
vim --version

Caso você não possua instalado é só baixar no link ao lado: vim.org.





O Vim (Vi IMproved) é uma versão melhorada do antigo VI, é um excelente e produtivo editor de texto modal, hoje conheceremos os 2 modos básicos:
Insert: O modo de inserção, onde podemos editar texto normalmente.
Command: No modo de comando temos algumas maneiras eficientes de navegação e edição de texto.

Agora vamos a prática, crie um novo arquivo e abra-o em seu terminal ou editor Vim para aprendermos.

A primeira coisa são os modos, assim que você abre o arquivo, está no modo command, como citado acima, pode navegar pelo documento e manipular textos.

Para começarmos a inserir texto digite i, entrará no modo de inserção, vamos fazer um hello-world.html:
  
    <html>
    <head>
      <title>Hello World</title>
    </head>
    <body>
      <h1>Hello World :)</h1>
    </body>
    </html>

Feito isso, vamos treinar algumas comandos no modo command, basicamente para navegação simples:
  • h: para navegar a esquerda.
  • j: para navegar para baixo.
  • k: para navegar para cima.
  • l: para navegar a direita.
Pratique esses movimentos, caminhe pelo nosso hello-world.html.
Próxima lista de comandos básicos:
  • G: para ir até a última linha do arquivo.
  • gg: para ir até a primeira linha do arquivo.
  • w: para navegar de palavra em palavra para frente.
  • b: para navegar de palavra em palavra para trás.
Pratique esses movimentos, navegue pelo nosso hello-world.html.
E aí, sentindo dificuldades? É só acostumar, depois fica tudo mais simples. Vamos para comandos de copiar, colar e deletar:
  • yy: você copia uma linha.
  • p: você cola uma linha.
  • dd: você recorta a linha.
Bom, agora vamos misturar as coisas, os comandos também aceitam uma quantidade específica de vezes que eles devem ser executados, como funciona?
( <repetição> <comando> )
  • 2h : para navegar 2 vezes para a esquerda.
  • 4k : para navegar 2 linhas acima.
  • gg yG : copiar todo o arquivo.
  • 3w : para navegar 3 palavras a direita.
  • 2b : para navegar 2 palavras a esquerda.
  • 10dd para recortar 10 linhas a partir da atual.
  • 8p para colar 8 linhas a partir da atual.
Bom, essa é a hora da sua imaginação fluir e ir tentando coisas novas e não se prenda aos poucos ensinamentos que passei hoje, busque muito mais.

E a boa de hoje?
Venho acompanhando o Drew Neil do VimCast e estou aprendendo milhares de coisas novas a cada vimcast. Esse site da UniRio também me ajudou muito no início e não deixe de acompanhar meu blog, prometo escrever mais a respeito do Vim.

Qualquer dúvida email-me abner.terribili@lambda3.com.br ou comente abaixo.


segunda-feira, 24 de março de 2014

Haskell: Operações Recursivas em Listas

Fala galera, tudo tranquilo?

Hoje o assunto é bem bacana, venho fazendo uma listinha de exercícios marotos em Scala, e estou aprendendendo muito. Hoje o assunto é recursividade, de novo esse assunto? Sim isso está mudando minha vida ou mesmo a forma como penso. (Exagerando rs)

Então, vamos fazer em Haskell?

A ideia é simples, quero deixar bem claro e simples as operações em listas imutáveis usando recursividade, já expliquei algo sobre listas imutáveis aqui.

Bom, vamos começar com um problema, que tal fazermos um map* em uma lista.

* = Para quem não sabe, mapear uma lista é transformar cada valor da lista atual, em um valor que passará através de uma determinada função.

Crie um novo arquivo, double.hs, como não falo há pouco de tempo de Haskell, nos meus primeiros posts, você consegue ver como instalar o interpretador Hugs.

Vamos ao double.hs:

double [] = []
double (head:tail) = head * 2 : double tail

Bom, isso aí já torna a compreensão pouco simples, mas vou explicar, entenda:  double [] = [] é a nossa guarda, ou seja, um ponto onde devemos parar a execução da função. Já falei muito a respeito em posts mais antigos.
Já na segunda linha, vemos algo novo, mas acredito ser bem expressivo, double (head:tail), ali estamos separando a cabeça da lista, de seu corpo, faremos uma operação na cabeça (head *2) e concatenaremos com o corpo, mas passando o corpo como argumento da função double, repetiremos esse processo novamente, isso é incrível e simples.

Para exercitar, primeiro vamos deixar nosso double mais genérico, pois podemos querer fazer outros tipos de map em lista, crie um arquivo mapear.hs:

mapear f [] = []
mapear f (x:xs) = (f x) : mapear f xs

Pronto, agora nossa função está apta a receber outras funções a serem aplicadas a lista, você pode testar no Hugs.

Vá ao seu terminal, caminhe até o diretório do arquivo e digite: hugs mapear.hs

Para construir listas em Haskell, você pode usar de duas formas:

[1,1,2,3,5,8]
1 : 1 : 2 : 3 : 5 : 8 : []

Agora é só passar os parâmetros para sua função: mapear (*2) (1 : 2 : 3 : [])

Use os parênteses para "separar" os argumentos. Tudo certo! (Ou deveria estar).

Vamos evoluir mais um pouco, outra das operações básicas que podem ser efetuadas com lista é o Filter, onde você filtra os elementos da lista e só extraí o que "passar pelo filtro". Basicamente vamos passar uma validação para cada elemento da lista, e como fazer? Crie um arquivo filtro.hs e vamos codar nele:

filtro :: (a -> Bool) -> [a] -> [a] 
filtro f [] = []
filtro f (x:xs) | f x = x : filtro f xs
                | otherwise = filtro f xs

Trabalhamos com quase a mesma forma de aplicar a função do mapear, porém fizemos uma verificação, onde:

  •  | é a nossa verificação;
  • caso f x retorne false:
    • devolvemos só  filtro f xs;
  •  caso f x retorne true:
    • concatenamos a cabeça x ao filtro f xs;


Ou seja, como vamos navegando na lista, cada hora a cabeça é o elemento posterior, isso é muito simples. Já falei de estruturas de verificação.

O desafio de hoje é meio trabalhoso, caso a preguiça domine vai ter que esperar eu fazer aqui também pra disponibilizar no Github. Você deve implementar um Flatten, ou seja, caso receba uma lista de listas, deve devolver uma lista contendo todos os elementos das listas internas.

É isso aí gente, qualquer dúvida comente abaixo ou email-me: abner.terribili@lambda3.com.br.



segunda-feira, 17 de março de 2014

Java, C#: Substituindo o Switch com Polimorfismo

Fala galera, tudo tranquilo? Passado o Carnaval, espero que tenham se divertido, eu estou há uma semana sem escrever e hoje, vou escrever algo não muito novo. O exemplo acontece em Java, mas é simples de replicar em C#, acredite.

Recebi um desafio na faculdade, de escrever uma estrutura de tomada de decisão, aquela famosa "coisa bizarra" chamada Switch.

Imagine o seguinte, nós temos 4 regiões, sendo elas: Sul, Norte, Leste e Oeste. E para cada valor setado, desejo retornar uma região diferente, por exemplo:

Região Valor
Sul 2
Norte 3
Leste 5
Oeste 7

Com essa tabela ficou mais claro, se eu passar como parâmetro o valor 2, quero receber a região Sul. Bom, escrevendo o teste, poderemos refatorar depois, certo?

Crie um projeto no Eclipse/Visual Studio, e dê o nome de SubstituindoSwitch, feito isso, crie um source folder de test e crie um pequeno teste de unidade, em seu interior:

public class SustituindoSwitchTest {

    @Test
    public void DeveBuscarRegiaoSul() {
        Assert.assertEquals("Sul", new SubstituindoSwitch().buscaRegiao(2));
    }

    @Test
    public void DeveBuscarRegiaoNorte() {
        Assert.assertEquals("Norte", new SubstituindoSwitch().buscaRegiao(3));
    }

    @Test
    public void DeveBuscarRegiaoLeste() {
        Assert.assertEquals("Leste", new SubstituindoSwitch().buscaRegiao(5));
    }

    @Test
    public void DeveBuscarRegiaoOeste() {
        Assert.assertEquals("Oeste", new SubstituindoSwitch().buscaRegiao(7));
    }

}

Agora vamos resolver da forma mais simples. E o Switch cai como uma luva certo? Olha ele aí:

public class SubstituindoSwitch {

    public String buscaRegiao(int valor) {

        switch (valor) {
        case 2:
            return "Sul";
        case 3:
            return "Norte";
        case 5:
            return "Leste";
        case 7:
            return "Oeste";
        default:
            return "Região não encontrada.";
        }
    }
}

Bom, resolvemos o problema certo? Sim! Mas se temos toda aquela história de orientação a objetos e polimorfismo, por que usamos essa estrutura forrada de responsabilidades e totalmente procedural?

Podemos começar a pensar apenas em dividir as responsabilidades, ali no switch ficou claro que nossa classe SubstituindoSwitch tem uma grande responsabilidade de avaliar e claro devolver o retorno esperado e isso não é nada vantajoso. Vamos tentar encontrar semelhanças na responsabilidade. Para todas as situações um determinado valor é avaliado e caso seja ele o correto, recebemos uma String. E aí identificamos uma responsabilidade, vamos construir uma interface para esses responsabilidade:

public interface Regiao {
    public boolean avalia(int valor);

    public String procedencia();
}

Pronto, já definimos a responsabilidade, agora precisamos delegar os respectivos comportamentos, sabemos que o quando o valor for 7, desejamos receber a string Oeste, ok?

public class Oeste implements Regiao {
    @Override
    public boolean avalia(int valor) {
        return valor == 7;
    }

    @Override
    public String procedencia() {
        return "Oeste";
    }
}

E podemos fazer isso para todas as outras três regiões esperadas(Sul, Norte e Leste), cada uma dessas regiões com a mesma responsabilidade mas diferentes comportamentos. Certo? Implemente as outras classes para podermos dar continuidade. Caso a preguiça domine, vá até meu Github.
Agora voltaremos a nossa classe SubstituindoSwitch, e faremos algumas pequenas modificações, a primeira de todas é apagar o devorador de responsabilidades switch:

public class SubstituindoSwitch {
    private List<Regiao> regioes;

    public SubstituindoSwitch() {
        regioes = new ArrayList<>();

        regioes.add(new Sul());
        regioes.add(new Norte());
        regioes.add(new Leste());
        regioes.add(new Oeste());

    }

    public String buscaRegiao(int valor) {

        for (Regiao regiao : regioes) {
            if (regiao.avalia(valor))
                return regiao.procedencia();
        }

        return "Região não encontrada.";
    }
}

Vou tentar ao máximo deixar claro o que está acontecendo no código acima, a primeira coisa que fizemos foi definir uma lista de regiões, ou seja, uma lista que armazenará todas as opções de regiões possíveis. Nosso método buscaRegiao continuou recebendo o parâmetro valor, mas ele não mais detém a responsabilidade de conter os valores das regiões, ele apenas delega a responsabilidade de acordo com uma avaliação também executada por cada responsável pelo valor, poxa, perdi até o fôlego. Detalhando:

if (regiao.avalia(valor)) return regiao.procedencia();

Esse if passa o valor para a região, a região detém o comportamento esperado e ela retorna o resultado desejado. Bom, só rodar os testes, e se maravilhar com o resultado. Bom, o próximo desafio é substituir o if, aí já envolve um pouco mais de estudo. :P

Qualquer dúvida, comente abaixo ou email-me: abner.terribili@lambda3.com.br.

Se surgir dúvidas, tem o exemplo lá no meu Github:
Para os Java: https://github.com/aterribili/SubstituindoSwitch
Para os C#: https://github.com/aterribili/SubstituindoSwitch-CSharp


Abraços!