Páginas

Tuesday, December 6, 2011

Como continuar um upload / download usando scp e rsync

Para minha referência futura e talvez ajudar mais alguém...

rsync -P --rsh=ssh nome-arquivo.tar.gz usuario@host:~/caminho/destinho/

Com este comando é possível continuar um upload ou download iniciado por scp, mas que por alguma razão foi interrompido.

O -P é equivalente a --partial (continuar transferências parciais) e --progress (exibe uma barra de progresso) e --rsh=ssh faz com que o rsync use o ssh (assim como o scp) para fazer a transferência de forma segura.

Sunday, November 20, 2011

Eu sou um dos autores do Perl 5

Depois de mais de 1 mês de espera pra ter meu patch no parser do Perl aceito, hoje eu entrei pra lista de autores! Fantástico!


Encontrei um bug com mais de 5 anos, que passou despercebido aos olhos de muitos programadores do core do Perl 5.
Acho que é uma virtude minha detectar erros em texto... eu poderia virar revisor de livro ou equivalente. Leio com atenção, presto atenção nos detalhes, detecto padrões e anomalias.

Quer contribuir você também para o Perl? Comece por aqui.

Friday, November 4, 2011

Perl no Dojo Rio

Wordle usando como base o código-fonte dos nossos dojos em Perl:

Wordle: Perl tests from Dojo Rio

Tuesday, October 25, 2011

Tuesday, October 4, 2011

O que é Coding Dojo?


O que é Coding Dojo?

Um Coding Dojo é um encontro no qual pessoas se juntam para trabalhar em um desafio de programação. O objetivo é a prática deliberada de programação como forma de melhorar habilidades pessoais e se divertir em grupo.

Premissa: o aprendizado é um processo contínuo e requer prática. Prática coletiva traz novos desafios e potencializa o aprendizado e a disseminação de conhecimento.

Características: o ambiente é colaborativo e divertido, adequado para testar novas ideias. Participantes com qualquer nível de conhecimento são bem-vindos.

Requisitos técnicos/físicos: sala com um computador e um projetor. Quadro branco ou flip-chart, post-its e comida são itens que ajudam ao longo do encontro.

O Coding Dojo é um espaço semanal na agenda para treinar boas práticas de programação, como Test-Driven Development (TDD), programação em par, código coletivo, passos de bebê, design incremental, entre outras práticas ligadas ao desenvolvimento Ágil de software.

A maioria das boas práticas do Dojo são derivadas da metodologia de desenvolvimento Ágil Extreme Programming. Mas o Dojo vai muito além quando consideramos os aspectos sociais, que envolvem convívio social, apresentação de ideias em voz alta para um público e trabalho em grupo para atingir um objetivo comum.

E o Coding Dojo Rio?

O Coding Dojo Rio iniciou seus encontros semanais em dezembro de 2008. Tudo começou em setembro daquele ano no encontro da comunidade brasileira de Python, o PyCon Brasil 2008, realizado no Rio de Janeiro.

Tuesday, September 20, 2011

Somos nossos conectomas

Resumo dos vídeos “Sebastian Seung, I am my connectome, TED Talk, 2010” e “Jeff Hawkins, MIT150 Symposium Brains, Minds and Machines, 2011

Introdução

Um conectoma é um mapa detalhado das conexões neurais do cérebro. O termo é inspirado no termo “genoma”, e refere-se aos esforços científicos para capturar, mapear e entender a organização das relações neurais no cérebro.
O conectoma humano tem um milhão de vezes mais conexões que a quantidade de letras do seu genoma. Não se sabe ao certo quais informações podemos obter desses dados, mas especula-se que nossas memórias possam estar codificadas nas conexões de nossos neurônios. Outros aspectos como personalidade, intelecto, podem estar lá codificados.
Sebastian Seung fez uma apresentação de divulgação científica, explicando alguns conceitos, citando estudos passados e atuais, e tentando mostrar a importância e relevância do tema. No fim ele chega discutir a viabilidade de se estender a vida através da criogenia.
Seung reforça a ideia de auto-percepção do ser. Ele sustenta que “Eu sou mais que meus genes”, e que “Eu sou meu conectoma”. As interações neurais viriam a explicar o que os nossos genes não são capazes de explicar.
Um fato que achei particularmente interessante é que, similar ao estudo de genomas, existem muitos desafios científicos envolvidos. Encontrar conectomas implica resolver outros problemas, incluindo obtenção e processamento de imagens, como colorir um grafo gigante, escaneamento em três dimensões, habilidade de fazer zoom in/out em objetos 3d de alta resolução, processamento de enorme quantidade de dados, etc.
Pensando em redes complexas, considerar os genes isoladamente seria como olhar e entender cada nó da rede em sua individualidade. Mas já vimos que as redes codificam nas ligações entre os nós informações e características que não podem ser explicadas tomando como base as características individuais dos nós.

Thursday, September 15, 2011

Perl, Ruby, Python & Racket: time matters

Estava aqui pensando em duas coisas:

  1. Qual o comportamento de diversas linguagens de programação quando fazemos um "import" ou "require", e o que acontece se um mesmo arquivo for requirido várias vezes na árvore de dependências.
  2. Qual o tempo que leva para executar um script mínimo.
A motivação vem da diferença que dá usar #lang racket x #lang racket/base em Racket. Quando usamos a linguagem completa, temos todas as baterias em nossas mãos, e como penalização carregamos um monte de código pra memória sem que este seja efetivamente necessário. A segunda opção é mais leve, tem apenas definido elementos mais centrais da linguagem, ideal para usar quando estamos criando nossas bibliotecas.

Há uns anos atrás já havia feito experimentos similares (provavelmente não documentados) com Python. Agora fiz pequenos scripts em Python, Racket, Ruby e Perl para comparar. Atenção não leve em consideração os números deste post como "benchmarks" ou classificadores/qualificadores de uma ou outra linguagem.

O procedimento experimental

Para reproduzir este experimento, crie 4 diretórios:
mkdir t{python,ruby,racket,perl}
(Não entendeu a linha acima? Veja meu post sobre o uso de chaves no Bash)

Em cada um, crie 3 arquivos, "a", "b" e "c", com a extensão da respectiva linguagem.
O resultado final fica assim:

./tperl
├── a.pl
├── b.pl
└── c.pl
./tracket
├── a.rkt
├── b.rkt
└── c.rkt
./truby
├── a.rb
├── b.rb
└── c.rb
./tpython
├── a.py
├── b.py
└── c.py

Cada arquivo contém:
tpython/a.py
::::::::::::::
print "a"

tpython/b.py
::::::::::::::
import a
print "b"

tpython/c.py
::::::::::::::
import a, b
print "c"

Para as outras linguagens é similar, veja:

c.pl (Perl)

require "a.pl";
require "b.pl";
print "c\n";
c.rkt (Racket)
#lang racket/base
(require "a.rkt" "b.rkt")
(displayln "c")
c.rb (Ruby)
require 'a.rb'
require 'b.rb'
puts 'c'

Resultado 1

Todas as 4 linguagens parecem ser consistentes em:
  1. executar todo o código do corpo de um arquivo importado (incluindo efeitos-colaterais)
  2. não re-executar código já importado anteriormente (mesmo que por dependência indireta)
Ou seja, o resultado visual da execução de todos os exemplos é:

a
b
c

Resultado 2

Entretanto, o tempo de execução é bem diferente. Usando o time, os melhores resultados encontrados após muitas execuções num Core2Duo 2.2GHz com Ubuntu 10.10 64bits:

time perl c.pl
real 0m0.007s
user 0m0.000s
sys 0m0.000s

time ruby c.rb
real 0m0.010s
user 0m0.000s
sys 0m0.000s

time python c.py
real 0m0.015s
user 0m0.010s
sys 0m0.000s

time racket c.rkt
real 0m0.084s
user 0m0.060s
sys 0m0.020s

Se compilarmos o código Racket usando o "raco make", temos:

raco make c.rkt
time racket c.rkt

real 0m0.053s
user 0m0.030s
sys 0m0.020s


Conclusão
  • Racket e Python permitem fazer importação de vários módulos num único comando, enquanto que Ruby e Perl não. (Sim, existe o gem require_all pro Ruby, e certamente existe algo similar pro Perl no milagroso CPAN -- mas pelo que sei não existe solução "built-in" na linguagem)


  • Meus amigos Perl Monges devem ficar felizes porque Perl despontou como o mais rápido, né  Breno, Diogo, Samir, Ronald, e cia?
  • Meus amigos adeptos do Ruby vão ficar felizes e dizer que Ruby é mais rápido do que Python :P
  • Meus amigos Pythonistas, pé no chão, vão concordar que Python é rápido o suficiente e é mais divertido que Ruby (e que a conclusão acima, dos rubistas, não pode ser considerada já que meus resultados não provam nada...)
  • Meus amigos que ainda estão conhecendo Racket podem fazer caretas, normal... não tô nem aí :)
    Não me importo em "pagar o preço" para programar numa linguagem mais poderosa e bonita.

Obs: como as diferentes linguagens usam diferentes terminologias, perdoem o uso nem sempre preciso de "módulo", "arquivo", "importar", "requerer", etc. Espero não causar ambiguidade para o leitor.

Wednesday, September 14, 2011

Grep e Less com cores!

Esta é uma nota mental.

egrep -r --include="*.rkt" "[a-z-]+#" . --color=always | less -R

Para usar o Grep com cores, geralmente temos um alias grep='grep --color=auto' no nosso ~/.bashrc.

Mas acontece que muitas das vezes o resultado é grande é fazemos um pipe pro less. Como triste consequência perdemos as cores...
Para forçar o grep (egrep, fgrep, ...) a exibir cores use o --color=always, assim ele manda o output pro less com cores.
A opção -R do less faz com que ele interprete os caracteres de escape de cores do terminal.

grep "alguma coisa" /caminho/da/busca --color=always | less -R

Nota: pode ser usado também com o more:

grep "alguma coisa" /caminho/da/busca --color=always | more

[Update]
Como meu amigo Breno Oliveira sugeriu, uma alternativa interessante ao grep é o ack.
http://betterthangrep.com/

Usando o ack o comando fica:

ack "regexp perl" [caminho] --color | less -R

Monday, September 5, 2011

Lista de números com o Bash

Quer executar um comando várias vezes no Bash?

Use o for! E como gerar números sequenciais?

Voltamos ao brace expansion que citei noutro post. Você pode usar chaves para gerar strings arbitrárias, e também sequência de números.

Veja:
rodolfo@lisa:/tmp/bash-tricks$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
rodolfo@lisa:/tmp/bash-tricks$ echo {5..0}
5 4 3 2 1 0
rodolfo@lisa:/tmp/bash-tricks$ echo {7..21..2}
7 9 11 13 15 17 19 21
rodolfo@lisa:/tmp/bash-tricks$ echo {30..-40..-5}
30 25 20 15 10 5 0 -5 -10 -15 -20 -25 -30 -35 -40

A sintaxe é {inicial..final..incremento}, e o incremento é opcional. Se inicial < final, o incremento é 1 por padrão, caso contrário é -1.

Com o for:

rodolfo@lisa:/tmp/bash-tricks$ for x in {1..3}; do echo "Hello $x"; done
Hello 1
Hello 2
Hello 3

Wednesday, August 31, 2011

Entrevista com r0ml na OSCON 2011

O David Mertz gravou uma conversa com o Robert Lefkowitz, também conhecido como r0ml, e está no YouTube. Eles falam sobre os pensamentos de Lefkowitz sobre Computer Programming Literacy.



Pena que os vídeos estão muito editados/cortados, em algumas partes a conversa se torna pouco natural. Mas de qualquer forma é um papo bem bacana.

E os meus amigos Caike Souza e Henrique Bastos tiraram uma foto com o Robert na OSCON em minha homenagem! Muito obrigado!

@201 this is for you, my friend! #oscon /cc @caike @r0ml  on Twitpic

Dark Networks

Resumo do artigo “The Topology of Dark Networks
Jennifer Xu, Hsinchun Chen, The topology of Dark Networks. Communications of the ACM, Vol. 51, 2008.

Introdução

Darks Networks são as redes de organizações terroristas, tráfico de drogas, tráfico de armas, gangues, etc.
Uma rede complexa de grande porte pode ser classificada em três tipos: aleatória, mundo pequeno, e livre de escala. A categorização é feita com base na topologia da rede, e esta é estudada através de estatísticas como comprimento médio de caminhos, coeficiente de clusterização médio, e distribuição de graus.
O artigo faz referência aos trabalhos de Réka Albert e Albert-László Barabási quando afirma que a maioria dos sistemas complexos não são aleatórios, e apresentam propriedades de redes de mundo pequeno e livres de escala. Em seguida, quatro “redes do mal” são estudadas a fim de discutir que propriedades elas apresentam, tentando justificar cada uma delas. São elas: GSJ (rede de terroristas, alguns da Al Qaeda), Meth World (traficantes de metanfetaminas), Gang Network (criminosos de gangues de Tucson, EUA), Dark Web (rede de sites de grupos terroristas).

Tuesday, August 30, 2011

Auto-completar Bash usando chaves { }

Bem, se você usa o terminal mesmo que pouco deve saber que a tecla TAB é usada para auto-completar nomes de arquivos e alguns comandos.

Mas o que você não deve saber é do uso das chaves como forma de construir strings arbitrárias. E mais, se você é como o meu amigo Flávio Amieiro e já sabia disso, aposto que você não sabia que pode usar auto-completar e as chaves {} {} {} {}!!!!

Digamos que estou num diretório assim:


rodolfo@lisa:/tmp/bash-tricks$ ls
foo_ball.egg  foobaz         foo_spam2.egg  foo_spam.egg  hello.c
foo-bar       foo_spam1.egg  foo_spam3.egg  foo.txt

Podemos auto-completar nomes com TAB. Por exemplo, digitar "h" seguido de TAB vai resultar em "hello.c".

Digamos que quero fazer um diff entre foo_spam2.egg e foo_spam3.egg. Uma forma de fazer isso seria digitar o comando completo:

diff foo_spam2.egg foo_spam3.egg


Depois de ler isto aqui, espero que sua forma de fazer seja assim:

diff foo_spam{2,3}.egg

O Bash expande automaticamente tudo que estiver dentro das chaves. Itens são separados por vírgula, sem espaços. Se quiser colocar um espaço ou vírgula na string gerada, escape com uma contra-barra \.

Exemplo:

rodolfo@lisa:/tmp/bash-tricks$ echo O Bash é {legal\,,muito\ poderoso,e\ divertido.}
O Bash é legal, muito poderoso e divertido.

Agora a cereja no topo do bolo! Como gerar uma string como a do exemplo acima a partir dos arquivos num diretório?

Digamos que queremos remover todos os arquivos que começam com "foo".
Começamos digitando:

rodolfo@lisa:/tmp/bash-tricks$ rm f

Agora tecle alt + { e você verá o Bash auto-completar usando a notação de {}:

rodolfo@lisa:/tmp/bash-tricks$ rm foo{-bar,.txt,_{ball.egg,spam{.egg,1.egg,2.egg,3.egg}},baz} 

Fantástico não? Note que você pode apontar para outros diretórios, e fazer combinações arbitrariamente complexas.
Não sei em que parte da documentação isto está, descobri por acaso!

Quer aprender mais? man bash

Decaimento exponencial e lei de potência

Numa aula de Redes Complexas estávamos observando numericamente o que quer dizer que uma função (no caso, uma função densidade de probabilidade) decai exponencialmente ou segundo uma lei de potência.

No caso exponencial temos: E lei de potência:
P(x) ~ e-x P(x) ~ x

Fiz uns gráficos de algumas funções que ajudam a entender um pouco do que está acontecendo. Compare as funções azul e vermelha com a violeta. As duas primeiras são leis de potência com expoente 2,5 e 1,4, respectivamente, que poderiam representar a distribuição de graus de nós em redes livres de escala. A última é uma curva gaussiana, que poderia representar a distribuição de graus de nós em uma rede aleatória.

Num artigo de Barabási e Bonabeau, Scale-free networks, eles dizem que o γ das redes livres de escala está geralmente entre 2 e 3. Já Xu e Chen em The topology of Dark Networks encontram redes com γ entre 1 e 2.

Se olharmos para as funções 1, 2, 3 e 4, notamos que a lei de potência com γ = 5.9 decai mais rápido que a exponencial 4, para as constantes envolvidas. Isto traz à tona o sentimento de que o efeito da cauda longa, ou cauda pesada, fica melhor caracterizado quando γ é pequeno.

Permalink para o gráfico


Update [31/08/2011]
Cometi um erro absurdo acima. A exponencial decai mais rápido. É claro! Se olharmos com um zoom de 10000x no eixo vertical, veremos que as curvas se cruzam e a exponencial se aproxima de zero muito mais rápido que a lei de potência.

Permalink para o gráfico
Apesar do deslize, o sentimento é o mesmo. Ter γ grande implica numa menor probabilidade de coisas "fora do normal" acontecerem, e o fato é que nas redes livres de escala as coisas acontecem.

Tuesday, August 16, 2011

Rede livre de escala

O desafio

Imagine-se como o imperador de um planeta de outra galáxia.



Conseguiu visualizar? Agora, sendo um imperador de um lugar tecnologicamente avançado, você tem uma tarefa pela frente: implantar uma rede de rotas de voo de naves espaciais no espaço aéreo de seu planeta.

Monday, August 1, 2011

Racket com readline


Para quem estava acostumado ao IPython, usar o interpretador do Racket no terminal pode ser um bocado decepcionante.

Isto porque por padrão o REPL é bem rudimentar, sem suporte a auto-completar, sem histórico, sem nada...

O que existe entretanto é um problema com licenças. O readline é distribuído em GPL, e o Racket em LGPL, e para não haver conflitos o suporte a readline vem desativado por padrão. Mas ele está lá.

A documentação em inglês dá os detalhes completos: Readline: Terminal Interaction.
Este módulo vai tornar sua experiência no REPL muito mais agradável, naqueles momentos em que você está no terminal e não quer abrir o DrRacket ou o Emacs.

Para usar basta iniciar o racket assim:

  racket -il readline

E se você não quiser ter que fazer isto toda vez, basta instalar permanentemente o suporte ao readline chamando uma função :D


Pronto. Agora toda vez que executar racket você entratá num REPL com histórico (que lembra inclusive as sessões anteriores), auto-completar usando tab, seta pra cima e pra baixo pra navegar nos comandos, etc.

Para ficar melhor ainda, adicione uma linha no arquivo ~/.inputrc:

set blink-matching-paren on

Esta sugestão do Eli Barzilay faz com que seu terminal indique qual "(" está relacionado com qual ")" quando você digita, e funciona tanto dentro do racket quanto em qualquer outro canto, inclusive no IPython. Também funciona com [] e {}.

E não pára por aí... o REPL vai ficar melhor ainda com o XREPL que vem aí na próxima release.
Com ele será possível fazer coisas já corriqueiras no IPython, agora em Racket.

Happy hacking!

Thursday, July 28, 2011

Estatísticas do Dojo Rio em 2011

Resolvi fazer uns gráficos para mostrar as linguagens que usamos nos dojos, mais como curiosidade que outra coisa.

Para conseguir gerar os dados tive que renomear alguns diretórios de dojos antigos que estavam sem a descrição de problema e linguagem. Depois, atualizei meu script para gerar as estatísticas.

Os gráficos

Este ano:


Todos os dados disponíveis:


Portanto as linguagens mais utilizadas neste ano, assim como em todos os tempos, são Python, Ruby e Javascript.

Alguma sugestão de gráfico que você gostaria de ver?

Tuesday, July 19, 2011

Escolhendo um Lisp: do Clojure ao Racket

Graças a um email de um amigo, o Lucas Teixeira, finalmente escrevi algumas coisas que já vinha comentando com algumas pessoas, geralmente nos pós-dojos.

Era pra ser um email pro Lucas, mas acabei expressando coisas que poderiam ficar públicas.

Bem, ele começou dizendo no email:
Então... sempre quis aprender programação funcional. Já tentei Haskell, LISP, Scheme, mas nunca pegou de verdade.

Tô tentando aprender Clojure agora. Baixei o Clojure Box e uns tutoriais da Internet. Tô resolvendo uns problemas do Project Euler e o clojure-koans.

Tem alguma dica de material?

Que tipo de coisa você tá / tava fazendo com Clojure?
Cara, foi muito surpreendente seu email.

Vamos a um apanhado de impressões sobre algumas linguagens da família lisp, começando com Clojure, passando por Common Lisp, Scheme e chegando em Racket.

Descrevendo objetos com Racket

O Racket é muito esperto, e com o auxílio de um módulo disponível no PLaneT é possível fazer coisas bem divertidas, como fazer contas:

#lang racket
(require (planet williams/describe/describe))

(displayln
 (string-join
  (map (λ (t) ((if (exact-integer? t)
                   integer->string
                   (curry format "~a")) t))
       `(I will show you how Racket knows how to count.,"\n"
           Racket knows that 3 + 4 is ,(+ 3 4),"\n"
           Racket knows that 5 * 9 is ,(* 5 9),"\n"
           and that 5 / 4 is ,(/ 5 4),"\n"
           and 2 ^ 10 is ,(expt 2 10),"\n"
           and much more...))
  " "))

(define (! n)
    (if (= n 0)
        1
        (* n (! (sub1 n)))))
(describe (- (! 40) (! 41)))

Tão esperando que pra instalar o Racket e ver o output?
(Alias, que tal implementarmos um "describe" no dojo?)

Veja a documentação do describe pra ver o que mais ele pode fazer...

Friday, June 10, 2011

Brainfuck com Racket

Esta é uma novidade fresquinha. O Danny Yoo está desenvolvendo uma versão de Brainfuck que roda na infraestrutura do Racket, para mostrar que é possível ter linguagens com sintaxe totalmente diferente de Lisp. Ele chamou a linguagem de Brainfudge, e o código está disponível no github.

Como podemos ver, o Racket é uma linguagem para escrever linguagens.

Para os curiosos de plantão, aqui vai um Hello World:

#lang planet dyoo/brainfudge

+++++ +++++             initialize counter (cell #0) to 10
[                       use loop to set the next four cells to 70/100/30/10
    > +++++ ++              add  7 to cell #1
    > +++++ +++++           add 10 to cell #2 
    > +++                   add  3 to cell #3
    > +                     add  1 to cell #4
    <<<< -                  decrement counter (cell #0)
]                   
> ++ .                  print 'H'
> + .                   print 'e'
+++++ ++ .              print 'l'
.                       print 'l'
+++ .                   print 'o'
> ++ .                  print ' '
<< +++++ +++++ +++++ .  print 'W'
> .                     print 'o'
+++ .                   print 'r'
----- - .               print 'l'
----- --- .             print 'd'
> + .                   print '!'
> .                     print '\n'

Como de costume, não é preciso instalar nada manualmente nem mesmo salvar o arquivo! Vejam:



Friday, June 3, 2011

Comunidade Racket em português

O Racket tem uma comunidade bastante ativa e receptiva.

Para abrir espaço para aqueles a fim de aprender um pouco mais sobre Racket, mas que tem dificuldades de se comunicar em inglês, criei o grupo Racket Brasil.

Apesar do nome, fica o convite e apelo à participação dos nossos amigos portugueses e demais falantes da nossa língua.

É a oportunidade de nos conhecermos melhor e trocar informações.

Sunday, May 29, 2011

Programando para Android com Racket

Numa possível "série" de posts que acaba de começar agora, vou mostrar as várias possibilidades de uso de Racket, a linguagem para criar linguagens.

Uma das coisas fantásticas de Racket é a documentação. Esta pode ser consultada online ou offline quando você instala o ambiente na sua máquina (existem instaladores para Windows, Linux e Mac OS X).

A instalação é fácil veja meu post para mais detalhes. Para escrever nosso programa para Android ou browser vamos usar o Moby, um compilador da linguagem Advanced Student Language (uma das linguagens do Racket) para Javascript/mobile.

Não precisa se preocupar com a instalação do Moby. Ele está disponível no PLaneT, o sistema de distribuição de pacotes do Racket. Isto quer dizer que o DrRacket (uma IDE que vem incluída) vai instalar o Moby pra você no primeiro uso e deixar tudo prontinho...

Ok, então você instalou o Racket, abriu o DrRacket, e agora?
Como sempre, muito fácil.

Como instalar o Racket

Neste post explico como instalar o Racket, incluindo os programas e utilitários de linha de comando e a IDE DrRacket.

Para começar, acesse a página de download do Racket, escolha sua plataforma, e clique no botão de download.

Friday, May 27, 2011

Sobre escolhas no projeto de linguagens de programação

Este tópico muito me atrái, e por vezes levanto esta discussão nos nossos encontros semanais do Dojo Rio.

Ontem fiz um post tentando esclarer que num mar de similaridades sintáticas podem existir muitas diferenças semânticas. O caso prático foi uma comparação envolvendo Boo, Python e Ruby.

A discussão seguiu na lista do Dojo, e um outro aspecto que marca a diferença entre escolhas feitas no projeto da linguagem Python e escolhas feitas no projeto da linguagem Boo surgiu num comentário do Juan. Este post é uma reflexão sobre este aspecto.

O Juan disse:
De qualquer forma, a coisa que mais me faz gostar de boo é não escrever "__init__", e sim "constructor".

Taí, gosto é um negócio bem abstrato e indiscutível muitas das vezes.

Seguindo a linha de papos que temos às vezes sobre as escolhas feitas no projeto de linguagens e as consequências que estas escolhas acarretam, ser "__init__" ou "constructor" é mais uma questão de escolha, na qual cabe-nos apenas declarar nosso gosto se o tivermos, e observar consequências.

Talvez por estar acostumado com a filosofia Python, o Zen of Python se quiserem, eu gosto da consistência ortogonal do "__whatever__" como disse o Berrondo.
E falar sobre gosto pára por aqui.


Mas e as consequências das escolhas?

Thursday, May 26, 2011

Mergulhando no Racket

Se tudo der certo vou escrever ainda muitos posts sobre Racket aqui no blog.
Simplesmente porque se eu achava Python muito legal, hoje Racket parece ser o novo Python na minha vida.

Continuo achando Python muito legal, mas acho que o problema é que muitos outros também, e isto tem tornado Python "a linguagem da vez" em algumas situações (muitas vezes acompanhados de Django), com trágicas consequências.

Talvez seja exagero meu, mas meu ouvido já doeu bastante ao ouvir alguns escrevendo "php em Python", pessoas que não entendem nem de PHP, nem de Python, nem de Web e nem de programação em níveis mais básicos.

Não estou aqui para reclamar disto, mas sim para fazer uma breve introdução à mudança - ou ao acréscimo de mais uma linguagem legal ao repertório.

Ah, os posts começaram quando falei sobre minha Introdução ao Racket no Coding Dojo Rio.

E dentro de alguns minutos terá mais um...

Boo não é Python

Ontem no Coding Dojo Rio no Centro do Rio de Janeiro tivemos uma nova linguagem para experimentar. Em linhas gerais o dojo foi sensacional, e não só os minutos que estávamos lá programando mas também as discussões que rolaram até tarde. Cheguei a casa já eram 2:40!

O problema que abordamos foi o do Caixa Eletrônico. Graças ao Juan Lopes nós usamos Boo e um super dojo timer novinho em folha. A idéia deste post é apenas discutir brevemente um aspecto da linguagem que me chamou a atenção.

Portanto, que fique claro que, apesar da maior parte da sintaxe ser parecida, as linguagens não são as mesmas, e algumas escolhas semânticas e gramaticais deixam isto claro. Também não se trata do que é melhor e o que é pior.

Ontem fiquei curioso pois numa parte obscura do nosso código tínhamos uma função mais ou menos assim:

def sacar(valor):
    return (valor,) if valor in (2, 5, 10, 20, 50, 100)
    
    raise EntradaInconsistente() if valor <= 0
    
    return (20, 20) if valor == 40
    
    return (2,) + sacar(valor - 2) if (valor - 2) in (2, 5, 10, 20, 50, 100)

Possívelmente não era exatamente isto, mas era algo muito parecido e equivalente. Tínhamos 4 linhas que eram raise ou return, seguido de um valor de retorno, seguido de um if e uma condição.

Não demorou para percebermos que a legibilidade estava ruim, pois para saber o que cada linha fazia era preciso ler a linha inteira. Se os if's estiverem em suas próprias linhas, fica mais fácil ler a condição e "ignorar" o bloco de código (mesmo que uma expressão curta...) que se segue.

    if valor in (2, 5, 10, 20, 50, 100):
        return (valor,)

Mas isto pode ser considerada apenas uma questão estilistica...

O ponto é que eu jurava que "return (20, 20) if valor == 40" não é uma linha válida de Python! Sim, de Python... mas estávamos programando em Boo.

Acabou que nós não testamos lá, e ficou o suspense. Em Ruby reza a lenda que isto funciona e é super normal, mas em Python... em Python a história é outra.
Eu fui testar agora no ipython:

In [1]: def foo(x, y):
   ...:     return "x par" if x%2==0
------------------------------------------------------------
   File "", line 2
     return "x par" if x%2==0
                             ^
SyntaxError: invalid syntax


In [3]: def foo(x, y):
    return "x par" if (x%2==0)
------------------------------------------------------------
   File "", line 2
     return "x par" if (x%2==0)
                               ^
SyntaxError: invalid syntax


In [5]: def foo(x, y):
    return "x par" if (x%2==0) else 0
   ...:

E foram confirmadas minhas expectativas de que isso não funciona em Python :D

Tanto return quanto raise são palavras-chave que formam gramaticalmente uma declaração (statement) em Python. E a declaração é "return truthy_value if condition else falsy_value", como pode ser visto na gramática.

A semântica quando se começa uma linha por return é que a função vai retornar o que quer que seja o valor avaliado para o que vem depois da palavra-chave (a não ser claro que antes disso ocorrer uma exceção seja lançada).

E é só isso...

Nota: não encontrei a gramática do Boo para linkar...
Nota mental: espero fazer mais desses posts ao invés de mandar emails longos :D


[update 26/05/2011 20:08]
O Juan acrescentou na lista do Dojo sobre a gramática de Ruby:

STMT : STMT if EXPR
STMT : EXPR
EXPR : ARG
ARG : PRIMARY
PRIMARY : return [`(' [CALL_ARGS] `)']

E então, comparando com Python (já que eu tinha só linkado antes):

return_stmt: 'return' [testlist]
testlist: test (',' test)* [',']
test: or_test ['if' or_test 'else' test] | lambdef

Agora só fica faltando formalizar a gramática do Boo. Fiz uma busca de novo no Google e no site oficial do Boo, mas não achei! Será que você tem mais sorte?

Wednesday, May 18, 2011

Introdução ao Racket no Coding Dojo Rio

Hoje no Dojo Rio no Centro farei uma apresentação de introdução à linguagem Racket.
Fiz um post no blog do Dojo Rio e replico ele aqui:

O que é “Racket”?
É uma linguagem relativamente nova, antes chamada PLT Scheme, que mostra sua origem em Scheme, um dos dois mais conhecidos dialetos de Lisp (o outro sendo Common Lisp).

Racket pode ser considerado também como uma família de linguagens, já que existem diversas sublinguagens para fazer as mais diversas coisas, como escrever documentação, apresentação de slides, ensinar programação, programação em lógica, etc.

Por que esta apresentação?
Já faz um tempo que queria compartilhar meu entusiasmo com programação funcional e Lisp, e por vezes pensei em levar lá pro Dojo o Common Lisp. Entretanto, a forma mais legal de trabalhar com CL seria usando o editor Emacs e o SLIME.

Acontece que configurar tudo isso e esperar que as pessoas consigam usar numa boa é complicado — principalmente esta segunda parte. Já basta a resistência com a sintaxe diferente e com ideias e formas de programar diferentes, ainda ter que lidar com um ambiente “hostil” certamente traria desânimo, revolta e incompreensão.

Se você já está habituado a usar o Emacs, programar em qualquer dialeto de Lisp certamente vai ser “mamão-com-açúcar”!

Por que Racket?
Então, por que Racket? O Racket além de funcionar bem em Linux, Mac OS e Windows, vem com um ambiente de desenvolvimento, oDrRacket, que torna a experiência de programar divertida e produtiva (ymmv). E mais, a documentação é muito boa, e a comunidade muito receptiva (você sempre pode tirar dúvidas via IRC ou lista de emails).
Screenshot do DrRacket
Screenshot do DrRacket

Racket não é só uma linguagem educacional! Também é possível fazer aplicações reais, em diversas áreas, e elas existem. Abaixo uma lista de alguns usos de Lisp/Scheme/Racket:

Monday, May 2, 2011

Dica: como terminar uma sessão de SSH congelada

Algumas vezes por algum problema na rede ou qualquer outra coisa ficamos com o nosso terminal bloqueado por conta de uma conexão SSH morta.
O que podemos fazer é matar o processo com um "kill" ou simplesmente fechar a janela do console (exemplo: gnome-terminal).

Mas existe uma forma melhor de terminar esta sessão mal-sucedida. Basta digitar ENTER, seguido de ~..
Pode parecer bizarro à primeira vista, mas funciona. Você vai encerrar o SSH e voltar para o seu bash.

Thursday, April 21, 2011

Lisp e o futuro da Web

Ultimamente tenho "namorado" desenvolvimento web com Common Lisp. Já usei Clojure lá na Intelie e foi uma experiência excelente.

O Google antecipa, o futuro é Lisp-based :D
Será?

http://hop.inria.fr/

Nota: o botão de "back" do browser não funciona no site do HOP... :|

[]'s

Rodolfo Carvalho

Tuesday, April 19, 2011

Saturday, March 19, 2011

Como desligar o monitor do seu notebook com Ubuntu

Se você quer desligar o monitor sem ter que suspender ou desligar ou fechar a tampa do seu notebook, aqui está a solução:

$ sleep 1 && xset dpms force off




O monitor será desligado. Para religar, basta mover o mouse ou apertar qualquer tecla.


Funcionou pra mim, espero que seja útil pra você também!