12.12.08
Posted in Dojo, Haskell
at 10:32 pm
by ricardo
O Dojo iniciou com a votação do problema e da linguagem de programação. As linguagens sugeridas foram Haskell, Ruby e Java. A idéia de fazer o Dojo em java seria respeitando umas regras que o pessoal da Thoughtworks montou:
http://binstock.blogspot.com/2008/04/perfecting-oos-small-classes-and….
Essas 9 regras são exercícios para aperfeiçoar a escrita de boas implementações de Orientação a Objetos. São elas:
- Usar somente um nível de identação por método.
- Não usar a palavra reservada ‘else’.
- Envolver os tipos primitivos e Strings.
- Usar somene 1 ponto por linha de código.
- Não abreviar nomes.
- Manter entidades pequenas.
- Não usar mais que duas variáveis de instância na classe.
- Usar classes de coleções que sejam as mais genéricas.
- Não usar getters e setters.
Porém o problema escolhido por votação foi o Snap e a linguagem Haskell.
Problema
O problema Snap se trata de clicks (definidos como pontos) e desenhos de vértices. Sendo que se o click estiver em uma área de atração de um determinado ponto, a posição do click será a própria posição do ponto de atração. O site desse problema está detalhado aqui.
Codando
Teve uma novidade da rotação das duplas. Após os 7 minutos, entrava uma pessoa direto na programação e quem estava codando passaria a ser o “co-piloto”.
Para a resolução do problema, foram criados dois arquivos: Tests.hs (para os testes) e Snap.hs (implementação do problema). Bem ao estilo TDD, a classe de teste começou com as linhas:
Tests.hs
module Main where
import Test.HUnit
import Snap
main = runTestTT testes
testes = TestList [testeCalculaDistancias]
testeCalculaDistancias = TestList[
"Distancia entre um ponto e ele mesmo deveria ser 0" ~:
distancia (Ponto 0 0) (Ponto 0 0 ) ~?= 0
]
Esse código simplesmente significa que o teste vai assegurar que a distância entre o Ponto na posição x = 0 e y = 0, e outro Ponto na posição x = 0 e y = 0, a distância é zero (Linha 11). É claro, pois eles estão na mesma posição !
Disparando esse teste, vão ocorrer erros, pois não existe a definição de “Ponto” e “distância”. Portanto vamos implementá-los.
Snap.hs
module Snap where
data Ponto = Ponto Int Int
distancia :: Ponto -> Ponto -> Int
distancia _ _ = 0
Na linha 3 é definido o Ponto, que será representado por ‘Ponto’ seguido de dois valores numéricos (Int Int). Na linha 5 é definido a função ‘distância’ que recebe dois pontos por parâmetro. Na linha 6 diz que distância, que recebe qualquer coisa no primeiro parâmetro e qualquer coisa no segundo parâmetro, retorna 0 (zero). Agora o teste passa com sucesso!
Porém ainda não está correto dizer que a distância entre qualquer ponto é zero. Então vamos escrever mais testes.
Tests.hs
"Distancia entre o ponto 0 0 e 0 1 deveria ser 1" ~:
distancia (Ponto 0 0) (Ponto 0 1 ) ~?= 1
Incluindo essas duas linhas, agora o teste falha. A distância entre o ponto 0 0 e o ponto 0 1 é 1, porém o método ‘distancia’ sempre retorna zero. Vamos alterar a implementação desse método:
Snap.hs
distancia :: Ponto -> Ponto -> Int
distancia (Ponto 0 0) (Ponto 0 1 ) = 1
distancia (Ponto 0 0) (Ponto 0 2 ) = 2
distancia _ _ = 0
As linhas 2 e 3 foram incluídas e agora o teste passa! Porém, apesar de estarmos roubando para o teste passar, esses passos pequenos são muito importantes. São chamados de baby steps. Baby step é uma técnica de metodologias ágeis que facilita a simplicidade do código, pois só precisamos desenvolver o que é realmente necessário para passar no teste.
O ciclo do TDD é:

Portanto, agora que os testes estão passando, vamos refatorar para o código ficar menos hard coded. As linhas:
Snap.hs
distancia (Ponto 0 0) (Ponto 0 1 ) = 1
distancia (Ponto 0 0) (Ponto 0 2 ) = 2
distancia _ _ = 0
Podem agora ser substituídas por:
distancia (Ponto 0 a) (Ponto 0 b ) = b-a
Agora nossa regra está funcionando para vértices na vertical. Porém ainda não está pronto. Vamos escrever mais um teste:
Tests.hs
"Distancia entre o ponto 0 0 e 1 0 deveria ser 1" ~:
distancia (Ponto 0 0) (Ponto 1 0 ) ~?= 1
Está passando 2 testes mas esse último falha. Vamos à implementação para esse teste incluído passar:
Snap.hs
distancia :: Ponto -> Ponto -> Int
distancia (Ponto 0 a) (Ponto 0 b ) = b-a
distancia (Ponto a 0) (Ponto b 0 ) = b-a
Antes só passavam os testes para vértices na vertical. Agora está passando para vértices na horizontal também. Vamos fazer um teste e ver se passa na diagonal. Incluindo isso no teste ficaria:
Tests.hs
"Distancia entre o ponto 1 0 e 1 1 deveria ser 1" ~:
distancia (Ponto 1 0) (Ponto 1 1 ) ~?= 1
A implementação para passar nesse teste, ainda roubando, ficaria assim:
Snap.hs
distancia (Ponto 1 0) (Ponto 1 1 ) = 1
Essa implementação está hard coded, mas é importante que seja dessa maneira pois precisamos manter o foco em ficar verde no teste, e aí sim fazer a refatoração.
Ok, como os testes estão passando novamente e está tudo no verde, vamos refatorar. As linhas:
distancia (Ponto 0 a) (Ponto 0 b ) = b-a
distancia (Ponto a 0) (Ponto b 0 ) = b-a
distancia (Ponto 1 0) (Ponto 1 1 ) = 1
Porem ser substituídas pela linha:
distancia (Ponto x1 y1) (Ponto x2 y2 ) = x2-x1 + y2-y1
Tudo passando! Vamos escrever mais testes para ver se a regra está certa:
Tests.hs
"Distancia entre o ponto 0 3 e 4 0 deveria ser 5
distancia (Ponto 0 3) (Ponto 4 0 ) ~?= 5
Com esse teste o resultado falha, portanto a fórmula acima ainda não está pronta. O correto seria implementar o teorema de pitágoras para calcular a distância entre os pontos:
Snap.hs
data Ponto = Ponto Float Float
distancia :: Ponto -> Ponto -> Float
distancia (Ponto x1 y1) (Ponto x2 y2 ) = sqrt ((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))
Concluindo
Vamos parar por aqui. O problema ainda não está resolvido, mas mostrei esses passos para percebermos a importância do baby step e como a modelagem pode ficar melhor e com mais qualidade. Para ver o que foi codado, entre no site do Github aqui.
O TDD nos direciona para uma maior simplicidade para ser desenvolvido somente o necessário para passar no teste. Além de fornecer mais confiança para devidas refatorações.
Retrospectiva
No final teve, como de costume, a nossa retrospectiva e os pontos a melhorar foram:
• “Não precisa do b-a”, sobre um dos baby-steps que poderia ser desnecessário
• “Nano baby step => seguro mas muito lento”. Sobre passos muito pequenos.
• Alguns passos grandes/rápidos em alguns momentos.
• Faltaram mais explicações sobre o que é baby-step durante o código
• “Faltou tão pouco” para terminar o problema. Apesar que esse não é o objetivo final do Dojo.+
• Teve gente que não gostou desse esquema de rotação invertido.
• Projetor estava ruim.
• Baby-step? Não “grown-up wannabe steps”.
• Perdemos muito tempo criando templates do projeto.
• Emacs é melhor que Gedit para codar Haskell
Os pontos positivos foram:
• Tipos de dados no Haskell
• Haskell
• Pessoas gostaram no rodízio invertido.
• Problema legal, simples e bom para TDD
• Baby steps
• ” ˜ é sempre antes.” Sobre a notação no Haskell.
Assuntos em Parking lote foram
• TODOs ajudam ou atrapalham?
• Geradores do ruby são ótimos para gerar templates
Permalink
Posted in Dojo, Haskell
at 5:31 am
by marivb
Relato escrito pela Jac – obrigada, Jac!
- Data: 01/12/2008
- Participantes: Marcelo, Pedro, Thiago, Hugo, Mari, Jac, R, Aline, Bruno Gola
- Randori: Problema das Caixas Empilhadas (adaptado de Pile of Boxes). Utilizamos Haskell com HUnit.
- Carta de criatividade: “Listen your dreams”
- Código: http://github.com/dojosp/participant-s-projects/commits/master/59-pile-of-boxes
Problemas
Os problemas sugeridos foram:
- Caixas empilhadas: Dadas as dimensões de altura e largura de uma caixa com abertura no topo devemos empilhar as caixas. Se uma caixa menor for colocada em cima de uma caixa maior, a menor estará dentro da maior e a altura final da pilha é a altura da caixa maior.Se a caixa maior for colocada em cima da caixa menor, a altura final é a soma das alturas.
- Entertainment: Dada uma tabela de elementos char e uma posição da tabela que não seja um espaço em branco. Deve-se encontar os elementos identicos adjacentes recursivamente ao elemento escolhido e troca-los por espaços em branco. Depois de substituidos, os elementos restantes devem ser movidos para esquerda enquanto os espaços em branco são deslocados para direita e posteriormente devem ser deslocados para baixo enquanto os espaços em branco são deslocados para cima.
- Magnetics: Dado um ponto com sua região de atração, verificar se quando um clique for dado o clique pertence a região de atração do ponto e também verificar a distância mínima entre dois pontos. (Este problema está perto de se tornar o novo little bishops!!)
Entre os problemas sugeridos, o problema das caixas empilhadas foi o escolhido por ser o mais votado.
Read the rest of this entry »
Permalink
13.11.08
Posted in Dojo, Haskell
at 7:00 am
by marivb
- Data: 29/09/2008
- Participantes: Hugo, R, João, Mari, Thiago, Yoshi, Breno
- Problema: map, filter e foldr em Haskell com HUnit (cuidado! Links da Wikipedia mostram implementação!)
- Código: http://github.com/dojosp/participant-s-projects/tree/master/53-haskell-basico
Decidimos finalmente tentar implementar as clássicas funções map, filter e foldr em Haskell. Cada uma deve fazer o seguinte: Read the rest of this entry »
Permalink
11.11.08
Posted in Dojo, Haskell, Kata
at 7:39 am
by flores
- Data: 10/11/2008, no IME – USP
- Participantes: Pedro, Thiago, Hugo, Jorge, R, Flores, Fabs, Mari, Marcelo, Bruno Gola, Renato, Carlos e Ricardo.
- Kata: Blocks por Mari
- Carta da Criatividade: Experimente uma idéia aleatória.
- Código: Estará disponível em breve.
Warm up
Um primeiro Parking Lot que apareceu foi sobre a numeração atual do Dojo, e acabamos por decidir que esse seria o Dojo 57. Após isso fizemos a escolha do problema. Inicialmente houveram quatro sugestões:
- Kata do Blocks
- Randori do Dama
- Randori do Entertainement
- Randori do Amigo Secreto: Um programa para sortear amigos secretos com um teste de aleatoriedade.
Fizemos a votação e o Kata ganhou. Perguntaram da onde vinha o problema Blocks, e a Mari nos disse que é o segundo mais fácil do UVA (só perdendo para o 3n+1). Após isso, sorteamos a carta da criatividade: “Experimente uma idéia aleatória”, que falava sobre um médico indígena e estratégias aleatórias de caças.
Coding Time
Inicialmente, a Mari criou o tipo de dados bloco e um construtor. Com os testes passando, foi feita uma refatoração para funcionar com um número arbitrário de blocos.
No Kata, a Mari começou a criar as operações, iniciando com a pile. Para essa operação, foi criada uma função para tirar um bloco do mundo. Depois criou uma função para devolver os blocos ao mundo recebendo o bloco que deveria voltar e sobre que bloco este deveria entrar, depois a implementou a Operação Pile Over. Infelizmente não terminamos o problema, mas por mais que pareça que fizemos pouco, o Hugo nos disse que para terminar tudo só precisaria implementar mais uma função e todo o resto seria simples de se implementar. Para cada implementação de função, estas ficaram meio grandes, mas se tornaram sucintas com uma boa refatoração, o que tornou o código mais fácil de entender.
A sintaxe de Haskell e os recursos funcionais nos deram a oportunidade de aprender coisas novas como o $, let, map, elem, span e outras coisas.
Retrospectiva
Dessa vez, as pessoas receberam os post-its e canetas no início do Dojo, para escreverem os pontos bons e ruins durante o Kata.
Como pontos positivos
, os principais temas abordados foram:
- Haskell e coisas relacionadas a essa linguagem;
- Boas explicações;
- BrHackDay ;
- Pessoas Novas ;
- Pensar Funcional ;
- Refatoração Power ;
E como pontos negativos
, podemos citar:
- Haskell e coisas relacionadas a essa linguagem ;
- Sem testes para o mundo ;
- Emacs ;
- Giant Step ;
- Repositório (foi movido para o Parking Lot) ;
- Conversa Paralela ;
- Monads (foi movido para o Parking Lot) ;
- Moedas do Fabrício;
E para o Parking Lot, os principais temas foram:
- Discussão do reposítório;
- Monads;
- Começar pelo in no let … in (isso é o Where na verdade);
- Remove recursivo;
- $ tem precedência mínima;
- Map, elem;
- \lambda;
- Set up para os testes;
- Stick to time?;
- Como construir Show e Eq complexos?;
O Dojo teve alguns momentos engraçados, como o Fabricio dar sua contribuição para a Pizza em moedas (gerando o ódio do Hugo), a explicação do Hugo de porquê o \lambda é representado por “\” (“é só tirar o pézinho”), mas a frase da noite foi dirigida ao Fabricio pelo R “Prum cara preguiçoso que nem você, Lazy Evaluation é ótimo”.
Permalink
19.10.08
Posted in Haskell, Ruby, UberDojo
at 9:48 am
by hugo
Na última segunda-feira rolou a edição número 55 do Coding Dojo. Ela foi, em muitos sentidos, especial. Para começar, o Danilo Sato estava presente acompanhado de um colega da Toughtworks, George Malamidis. Além disso, o dojo não foi realizado no IME/USP e sim na casa do Thiago Colucci (que fica “perto” da USP). Por fim, o dojo foi feito no formato UberDojo que vou explicar a seguir.
Usamos duas mesas que representaram duas linguagens (Haskell e Ruby) e cada lado da mesa representou um problema (Bank OCR e Minesweeper). Tivemos então 4 notebooks nos quais 4 pares codaram ao mesmo tempo. Tivemos turnos de 7 minutos como sempre e, ao término do turno, o co-piloto virava piloto, o piloto ia para a “platéia” e alguém da platéia virava co-piloto. Isso era feito tentando evitar que as duplas se repetissem e que as pessoas caissem no mesmo conjunto problema/linguagem muito freqüentemente. Fizemos isso durante pouco mais de uma hora e estávamos em 10 pessoas da velha guarda (Danilo, Thiago além de Fabricio, Jacqueline, Yoshi, Mariana, Breno, Adolfo e eu) e 4 novatos (George, Renato Willi, Bruno Pedroso e Rafael Schouery). Assim sempre sobravam 6 pessoas não programando para fazer as pizzas que acompanharam (Yoshi, Breno e Jac principalmente cuidaram disso, valeu!) e aprender um pouco vendo os outros programarem.
Demoramos um bocado para escolher os problemas e linguagens assim como para configurar o ambiente inicial nas quatro máquinas para que eles ficassem fáceis de usar para todos. Os turnos foram muito intensos e a galera estava em animada e falando alto procurando ajuda do pessoal que estava livre. Rolou uma boa troca de conhecimentos apesar de não ter tido o telão. O pessoal se divertiu bastante inclusive os novatos que agüentaram muito bem o tranco apesar de terem achado o tempo dos turnos muito curtos.
Em retrospectiva, percebemos que boa parte dos nossos problemas vieram da pressa para tentar dar passos grandes e não gastar um tempinho explicando ao novo co-piloto o que estava acontecendo e quais eram os próximos passos. Também concordamos que esse exercício requer participantes que já saibam bem trabalhar com TDD (Desenvolvimento Dirigido por Testes) e que, apesar de ser mais divertido e excitante que o dojo normal, não podemos manter esse formato em todas as sessões. Decidimos então que faríamos uma sessão desse tipo por mês. Também gostaríamos de ter feito uma retrospectiva mais adequada (ficou só na conversa a retrospectiva que fizemos).
Acho que é isso. Se tentarem isso, por favor, mandem-nos feedback a respeito.
Até o próximo dojo pessoal!
Permalink
09.10.08
Posted in Dojo, Haskell
at 5:02 pm
by leo
Escolhemos um problema simples para, na verdade, aprender a ler da entrada padrão e escrever na saída padrão com Haskell.
Read the rest of this entry »
Permalink
07.10.08
Posted in Dojo, Haskell
at 11:19 am
by marivb
Mais um relato pelo Thiago. Muito bem & muito obrigada!! XD
- Data: 22/09/2008
- Participantes: Thiago, R, Hugo, Mari, Leo, Yoshi e Breno
- Randori: Problema Setun (ou conhecido também chamado de Trits original), retirado da segunda seletiva da XII Maratona de Programação da USP. Utilizamos Haskell com HUnit.
- Carta de criatividade: “Find What’s out of Whack”
- Código: http://github.com/dojosp/participant-s-projects/tree/master/52-setun
O problema: receber um número inteiro e devolver sua representação em uma base ternária, cujos algarismos válidos são “+”, “0″ e “-” (de valor, respectivamente, 1, 0 e -1). Um número nesta base ternária (ou seja, um “trit”) representado como a1a2…ak tem valor igual a a13k + a23(k-1) + … + ak-131 + ak30. Por exemplo, o trit “+0-” tem valor 1*32 + 0*31 + (-1)*30 = 8.
Após resolvermos em um dojo passado o problema inverso, ou seja, dado um número formado por Trits, convertê-lo para a base decimal, resolvemos encarar o problema original (denominado de Setun).
Iniciamos uma pequena discussão de qual seria a abordagem ideal. Assim ficou decidido que necessitaríamos de uma função que dado um número, retornasse a maior potência de três deste número. Começamos daí.
Codando
Apesar da abordagem “mandar” fazermos uma função que nos dava a maior potência de três de um número, ficou muito claro para todos que, na verdade, cada um tinha entendido uma coisa do que fazer de verdade. Portanto os primeiros a codarem levaram o problema para o lado de que a maior potência era o maior expoente com base três que coubesse no número dado. No entanto os que vieram depois entenderam que era o resultado de três elevado a este expoente.
Esta confusão no levou a um impasse de tal forma que chegou um momento que todos estavam “palpitando” no código, e os “coders” lá da frente ficaram perdidos e travados. Foi então que percebemos que havia algo muito errado, mas não paramos para tomar nenhuma atitude. Ao invés disso seguimos em frente com testes e código.
Mas já era tarde e não evoluímos muito mais, terminamos com uma função que devolvia potência propriamente dita e não o expoente de três. Além desta função, não andamos muito na resolução do problema propriamente dito.
Retrospectiva
Como tínhamos decidido no dojo anterior, iríamos pensar mais nos problemas do dojo (Post-its vermelhos) do que nas coisas que estão andando bem.
Dentre os pontos positivos mencionados:
- Elogios à Haskell, principalmente ao fato de podermos escrever “x | x < 3″ lendo “x, tal que x menor que 3″;
- Atalhos do Emacs;
- O equipamento de modelar vidro finalmente chegou para o Yoshi, ampulheta do Dojo em breve;
- Aprendemos bastante sobre o problema;
- Fizemos um git reverse na mão;
Dos pontos negativos, foram citados:
- Não definimos e seguimos uma abordagem única;
- Atrasos de pessoas;
- git revert não funcionou;
- Deveríamos usar o TAB no Emacs, ele identa;
- Perdemos tempo fazendo otimizações, ou pensando nelas;
- Desatenção fez com que escrevêssemos testes “inúteis”;
- “O que fazer quando os testes saem dos trilhos?”;
- Pessoas perdidas durante a resolução;
- Planejamento foi furado;
Ficamos ainda com algumas discussões para o Parking lot, como sempre.
- TV Dojo: Muitas pessoas de fora do dojo estão nos pressionando para criarmos algum vídeo para que eles possam assistir como é o nosso Dojo. Ficou decidido que iríamos dar um jeito de arrumar ao menos duas câmeras para filmarmos uma sessão, sessão esta que seria uma espécie de Randori//Kata, pois iríamos resolver um problema já conhecido e de fácil entendimento para todos, mas seria resolvido no estilo Randori.
- Dojo em silêncio é igual a Dojo pouco produtivo? A resposta geral foi não. O fato do problema ser “enrolado” e a abordagem-mal-desenhada foi o que gerou o silêncio e o pouco desenvolvimento de código, a lição foi: problema simples (pequeno) não significa problema fácil.
Permalink
17.09.08
Posted in Dojo, Haskell
at 3:18 pm
by rbp
- Data: 15/09/2008
- Participantes: Thiago, R, Hugo, Mari, Lameiro, Pac-Man, Vitor, Ramiro e Breno
- Randori: Problema dos Trits (na verdade, um derivado), retirado da segunda seletiva da XII Maratona de Programação da USP. Utilizamos Haskell com HUnit
- Carta de criatividade: “Challenge The Rules”
- Código: no repositório do dojo no github.
A votação inicial escolheu o problema dos “Trits”: receber um número inteiro e devolver sua representação em uma base ternária, cujos algarismos válidos são “+”, “0″ e “-” (de valor, respectivamente, 1, 0 e -1). Um número nesta base ternária (ou seja, um “trit”) representado como a1a2…ak tem valor igual a a1*3^k + a2*3^(k-1) + … + ak-1*3^1 + ak*3^0. Por exemplo, o trit “+0-” tem valor 1*3^2 + 0*3^1 + (-1)*3^0 = 8.
Encarando (e mudando) o problema
Começamos a discutir a abordagem para o problema, mas não surgiu nenhum caminho óbvio. O Hugo sugeriu, então, começarmos resolvendo o problema invertido (e mais simples): dado um trit, devolver seu valor inteiro. Como tínhamos alguns convidados, fizemos uma breve introdução ao Dojo antes de partirmos para o problema, e alguns esclarecimentos ao longo da sessão. Mas mantivemos as janelas de 7 minutos, com o ciclo “teste, código, teste, commit”. O código em Haskell foi evoluindo naturalmente, e soluções contendo “if” e estruturas semelhante saltaram à vista e foram rapidamente substituídas por construções mais eminentemente funcionais.
Quase ao final do horário, com todos os participantes já tendo comandado o teclado, terminamos a solução do problema, e todos se disseram confortáveis com a abrangência dos testes. Partimos para uma otimização da solução, que, a esta altura, calculava o tamanho do trit a cada passo da recursão, mas não conseguimos terminar em tempo.
Retrospectiva
Assim como no dojo anterior, a quantidade de cartões amarelos foi bem maior do que a de vermelhos (e chegamos a redimensionar os espaços de cada um, para que os amarelos coubessem no foco do projetor). Apesar de ser um indicador de que todos estão se divertindo, foi sugerido que talvez estejamos sendo complacente demais, e que devíamos nos focar mais em procurar oportunidades de melhoria. Foi mencionado um palestrante da AgileConf, que mencionou que, no Japão, nas retrospectivas só se discutiam os vermelhos; elogios ficavam para a hora de lazer. Levantou-se a idéia, então, de, nas nossas retrospectivas, discutirmos primeiro os vermelhos, e só discutirmos os amarelos e o parking lot junto com a comida.
Dentre os pontos positivos mencionados:
- A presença dos convidados (dois do Rio de Janeiro e um de Curitiba)
- Os convidados mencionaram que gostaram bastante das cartas de criatividade e da dinâmica do dojo
- Mais elogios ao Haskell
- O problema interessante e a solução a que chegamos
Dos pontos negativos, foram citados:
- não resolvemos o problema que escolhemos no início, mas o problema inverso.
- falta de música (!). Foi colocado no vermelho e no parking lot.
- avançamos um pouco no horário
- muita conversa
- foi sentida a falta da Jac, e das polarizações Yoshi vs. Fabs.
- falta de comentários no código (mas este ponto foi comentado em seguida, e foi mencionado que a idéia é que os testes sejam documentação adequada para o código produzido a partir deles).
Parking lot + Pizza
Uma característica particular deste dojo, elogiada na retrospectiva e discutida ao final, foi que cada um pôde escolher utilizar o editor de sua preferência (desde que fosse vi ou emacs, nada de smultron!) na sua vez de comandar o teclado. Isto gerou alguma demora nas transições, quando o piloto precisava iniciar e fazer as configurações mínimas em seu ambiente, mas, de resto, funcionou surpreendentemente bem, embora nem todos tenham ficado satisfeitos.
Ao fim, todos nos divertimos muito, solucionamos o problema e estamos mais confortáveis com Haskell. Foi bom termos convidados, que pareceram gostar bastante da experiência. Esperamos que iniciem seus próprios dojos!
Permalink
14.09.08
Posted in Dojo, Haskell
at 10:32 pm
by adolfo
- Data: 08/09/2008
- Participantes: Mari, Thiago, Jac, Hugo, Adolfo, Fabs (o desertor), Yoshi, R e Léo
- Randori: Problema do sanduíche, retirado da segunda seletiva da XII Maratona de Programação da USP. Utilizamos Haskell com HUnit
- Carta da inspiração: “Focus on the real truth”
- Código: repositório do Dojo no github
O problema deste último Dojo era a respeito de dois irmãos que brigavam porque um deles se sentia injustiçado pela divisão de um sanduíche-íche. Se bem me lembro, o chef que havia preparado o lanche argumentava que a divisão fora justa e dizia ser possível provar que a quantidade de recheio contida nas partes era idêntica. E como isso era possível? Bem, se a minha memória não estiver me traindo, a entrada era a primeira linha de uma matriz quadrada e a descrição do problema nos dizia como montar o resto da matriz e também como calcular a quantidade de recheio em uma parte do nosso sanduíche-matriz.
Encarando o problema
Com o problema definido, o nosso primeiro objetivo era montar a matriz. Teste, código, teste, commit no git. Este ciclo foi mantido com a já comprovada e importante rigidez dos 7 minutos. Conseguimos fazer com que todos os participantes codassem pelo menos uma vez, até que, pouco antes da hora da retrospectiva, começamos a discutir se o cálculo do produto cartesiano resolveria o nosso problema. Não conseguimos esta resposta pois a ampulheta (mal Yoshi
) o relógio já apontava a hora da retrospectiva.
Reclamações, elogios e incômodos
Ao dar a primeira olhada para os post-its, me surpreendi com o número de cartões verdes: era 3 vezes maior que o número de cartões vermelhos, o que indica que estamos conseguindo melhorar nossas sessões.
Os pontos positivos:
- Muitos elogios à linguagem. Pelo jeito, todo mundo está gostando de Haskell
- Elogios a algumas particularidades da linguagem, como “produto cartesiano em uma linha curta”, “sintaxe semelhante à linguagem matemática” e “bloco let pode facilitar a estruturação de idéias”
- O problema era legal
- Gente nova (Léo e R, que voltou ao Dojo e o reconheceram)
- Pessoas de bom humor e querendo ir logo ao Outback
Os pontos negativos:
- Ficamos muito longe de solucionar o problema
- Tentamos alguns passos muito grandes, o que resultou em grandes refatorações
- O ‘let’ é uma boa prática mas provavelmente indica que o passo é muito grande
- Produto Cartesiano x Produto Matricial
- Alguém pegando no pé da Mari porque ela é defensora extremista da linguagem
Parking Lot:
- Por que não podemos tirar 2 elementos do começo da lista?
- Dojo “round-the-table”, alta concentração, no restaurante!!!
Feeding the coders!
Terminada a retrospectiva, fomos ao Outback comemorar o aniversário da Jac e do Thiago. O Fabs, só na hora da comida, se juntou a nós. Comemos pão, carne, batatas, cebolas e ainda ganhamos 2 sorteves para cantar o parabéns aos aniversariantes. E assim, depois de códigos, risadas, comidas e doces, voltamos felizes para nossas casas.
Permalink
05.09.08
Posted in Dojo, Haskell
at 11:27 am
by marivb
Relato escrito pelo Thiago – escreveu rápido e bem, quase dá pra ouvir ele falando! Valeu, Thiago, está de parabéns!!
Empolgada pelo Dojo de Paris, a Mari resolveu apresentar uma introdução básica à Haskell para que quando ela for apresentar o Kata de verdade não ficassemos totalmente perdidos, como já aconteceu.
Portanto ela apresentou Haskell “formalmente”, dizendo que é uma linguagem funcional e lazy. Em sequida explicou os termos para as pessoas que não os conheciam:
- “…funcional pois tudo é função…”
- “…lazy porque ela só calcula o que for necessário quando for necessário…”
Feito isto iniciamos a parte legal: Código!
Codando
Mostrando no interpretador de Haskell como fazemos “atribuições” em “variáveis” (entre aspas porque na linguagem não ocorrem atribuições e as variáveis não variam depois de definidas), depois como criamos uma função no próprio interpretador. Função esta que explicitava o fato de ser lazy.
Depois de sabermos o básico do básico de Haskell, iniciamos um “micro-problema”: Calcular um fatorial.
Para calcular o fatorial iniciamos o TDD, e com baby-steps aprendemos o pattern matching das funções, e como este recurso deixa fácil, rápido e compreensível o “cheating” de fazer passar MUITO rapidamente qualquer teste (colocando o valor esperado como valor de retorno de uma funcao que recebe exatamente os valores testados para ela). Este fato foi mais comentado na “Retrospectiva”. Juntamente com o pattern matching discutimos como o uso de “lembrança” (ou “cache” sem invalidar) em uma linguagem funcional e lazy pode ser algo extremamente útil e poderoso, já que uma vez calculado um valor, não precisamos recalculá-lo.
Além disso, com o fatorial funcionando entendemos como funcionam os tipos de variáveis, e como controlar o uso das funções com estes tipos. Aqui começou a abstração interessante e nada trivial sobre a linguagem. Terminada a parte do fatorial, entramos na parte de estrutura de dados: Como calcular a soma dos elementos de uma lista.
Assim vimos novamente a combinação “pattern macthing de funções + recursão”, além de entender como controlar os elementos da lista com funções de primeiro, e resto da lista, além do “mágico” pattern macthing da lista, separando facilmente os elementos da lista.
E foi neste ponto que uma grande discussão próspera começou. Como usar a função ‘foldr’.
Para começar, a Mari mostrou o tipo da função. O que depois provou-se um GIANT-Step, pois consigo trouxe a idéia da função Lambda, ‘+’ como sendo uma função binária com “bagunça” nos parâmetros, como podemos usar o “mais” de mais de uma maneira, e assim o caos se perpetuou, já que pouquíssimas pessoas continuavam entendendo. Mas graças à paciência de Hugo e Mari tudo se resolveu rapidamente.
Começaram explicando como funciona (não o que é de verdade) uma função lambda, e como todos parâmetros de uma função se tornam no final uma função Lambda, e com várias chamadas de funções obscuras resultamos na funçao desejada.
Depois de claro como era o tipo e para que serve o ‘foldr’, vimos como esta é uma ferramenta poderosa e muito útil na iteração de listas.
Em seguida a Mari continuou mostrando o map e o filter. e assim percebemos o baby-step invertido… Já que estas últimas funções foram rapidamente compreendidas.
Neste ponto a Pizza chegou!
Retrospectiva
Como de praxe, para “atazanar” um certo membro do Dojo, fizemos retrospectiva COM comida… ^^
Aqui entendemos muito bem (mas não completamente) o conceito da Função Lambda e quão dificil é compreendê-la de fato. Para esta explicação o Hugo mostrou um Jogo apresentado na Agile 2008 para entender como funcionam as funções em Haskell.
Depois de um bom tempo desenhando na lousa e depois que todos tinham compreendido os conceitos, partimos para o outor assunto interessante: Roubando para o teste passar rápido.
Para fazer isto, podemos usar if’s e else’s para retornar logo de cara o valor esperado, ou simples e elegantemente usar o pattern macthing das funções. Esta tática foi motrada aos nossos “intercambistas” no dojo de Paris.
Lá eles fazem com que o teste passe extremamente rápido, assim tudo que mexe na estrutura e otimização do código, incluindo aqui algoritmos desconhecidos, faz parte da refatoração. Percebemos que é bom treinar deste modo, pois nossa refatoração só causa um efeito “estético” no código, quase nunca alterando o método de resolução do problema.
Assim ficou decidido que iremos tentar de vez em quando usar esta técnica “apelona”.
Depois de falarmos muito e de barriga cheia, cada um tomou seu rumo e assim terminou nosso dojo de número aproximadamente igual a 49.
Permalink