Páginas

Monday, May 30, 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?

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:

Tuesday, May 3, 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.