terça-feira, dezembro 09, 2008

Bookmarklet para Google Reader

Por algumas razões estou utilizando no dia-a-dia o Google Chrome (sim, ele não tem add-ons e é *extremamente* minimalista). Para contornar a falta de uma maneira de adicionar o feed da página atual no leitor de feeds, fiz o seguinte bookmarklet, que pode ser utilizado em qualquer outro browser:



javascript:(function(){function fs(){var r=[];for(var i=0,ls=document.getElementsByTagName('link');i<ls.length;i++)if(ls[i].type in {'application/rss+xml':0,'application/atom+xml':0})r.push(ls[i]);return r}var ls=fs();if(ls.length>0)location.href='http://fusion.google.com/add?feedurl='+encodeURIComponent(ls[0].href);else alert('No feeds available!');})()

Como o engine do Blogger não me deixou criar um link com esse código, vais ter que copiar e criar na mão o bookmarklet na barra de favoritos.

Ah, se não sabe, Control+B mostra a barra de favoritos no Chrome.

quarta-feira, outubro 01, 2008

LINQ e SQL

Estava lendo uma das entrevistas da Computer World da série "The A-Z of Programming Languages", sobre a linguagem C#, e a parte abaixo me chamou a atenção:

"[I also learnt to] design the language to be well-toolable. [...] When you write your SELECT clause, you can’t tell what people are selecting from, or what they might select until after writing the FROM clause. There are things like that to keep in mind."[Anders Hejlsberg]
No mesmo momento liguei a síntaxe SQL:

SELECT nome FROM pessoas WHERE [clausula];

com a empregada no LINQ:

from nome in pessoas
where [clausula]
select nome;

Reparem que a seleção dos campos e as clausulas ficam após a especificação de onde eles vêm, logo a IDE se benefícia disso para fornecer dicas e auto-completação, algo que em ambientes para SQL só acontece se os campos no SELECT forem prefixados com o nome da tabela...

Isso demonstra o quão importante é o desenvolvimento da síntaxe da linguagem já pensando no que as ferramentas poderão auxiliar os desenvolvedores.

PS.: ando desaparecido por causa do meu trabalho de conclusão de curso, então entre trabalho e TCC não me sobra muito mais tempo além de ler alguns textos :)

terça-feira, agosto 28, 2007

Programação dinâmica & Concorrência

Como havia falado no post anterior, eis aqui a implementação de um processo servidor de resultados para cálculo de Fibonacci, juntamente com um "cache" dos resultados prévios.

-module(fibserver).
-export([fibserver/0, fibserver/1, fib/1, start/0]).

fibserver() ->
% Start the Fibonacci Server with some basic pre-defined values...
fibserver([{0,0}, {1,1}]).

fibserver(Values) ->
receive
{getValue, ReqPid, X} ->
ValueExists = lists:keymember(X, 1, Values),
if
ValueExists ->
{value, {_, V}} = lists:keysearch(X, 1, Values);
true ->
V = notFound
end,
% Send to the request process the atom notFound, or the Fibonacci of X.
ReqPid ! V,
fibserver(Values);
{putValue, ValueTuple} ->
fibserver(Values ++ [ValueTuple])
end.

fib(N) ->
% Ask the server for the Fibonacci of N...
fibServer ! {getValue, self(), N},
receive
% If the value doesn't exist yet, then...
notFound ->
% ...calculate it...
FibN = fib(N - 1) + fib(N - 2),
% ...update the server with this new value...
fibServer ! {putValue, {N, FibN}},
% ...return the calculated value.
FibN;
X ->
% The value was already in the server.
X
end.

start() ->
% Just start the process identified by the atom 'fibServer',
% as the execution of the fibserver:fibserver/0,
% that means, module fibserver, function fibserver
% that receives zero parameters.
register(fibServer, spawn(fibserver, fibserver, [])).

Coloquei alguns comentários, mas para o total entendimento do código, você deve ter uma noção básica sobre Erlang, qualquer dúvida só postar.

Para testar:
$ erl
Erlang (BEAM) emulator version 5.5.2 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.5.2 (abort with ^G)
1> c(fibserver).
{ok,fibserver}
2> fibserver:start().
true
3> fibserver:fib(1000).
43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875

O resultado é praticamente instantâneo :)

PS.: me esqueci de comentar como sair do shell do Erlang, basta pressionar Control-C, e então "a[enter]", ou então executar a função halt().

quarta-feira, agosto 22, 2007

Brincando com Erlang

Ultimamente tenho visto muitos posts comentando sobre a linguagem Erlang, que é uma linguagem funcional para programação concorrente, embora alguns defendam que também é orientada à objeto, já que Erlang oferece envio de mensagens como método para sincronização e comunicação entre processos, e orientação à objeto, na teoria, nada mais é do que troca de mensagens entre os objetos.

Como tive uma cadeira na faculdade sobre programação funcional (recomendo a todos aprenderem uma linguagem funcional ou de paradigma diferente do imperativo) usando Haskell, e gostei muito, resolvi começar a brincar com Erlang, que já tem um framework web e um banco de dados super escalável!

Para começar, instalei o pacote "erlang" no Debian Etch, muito simples.

Então vamos para nosso primeiro programa, "hello world" ou Fibonacci? Ok, ok...

  1. Crie um arquivo chamado hello.erl, com o seguinte código:
    -module(hello).
    -export([hello/0]).

    hello() -> io:format("Hello world!~n").
  2. Chame o interpretador Erlang com o comando "erl";
  3. Compile o programa:
    c(hello).
  4. Isto deve gerar um aviso {ok, hello};
  5. Vamos executar:
    hello:hello().
  6. Pronto, satisfeito?

Agora vamos ver como implementar o cálculo de Fibonacci de um número em Erlang, repare que o nome do arquivo deve ser fibonacci.erl, combinando com o nome do módulo:
-module(fibonacci).
-export([fib/1]).

fib(0) -> 0;
fib(1) -> 1;
fib(N) -> fib(N - 1) + fib(N - 2).

Reparem que há um pattern matching nos 2 casos básicos, e após a implementação recursiva para qualquer N > 1, com base disso podemos diminuir um pouco o código:

fib(N) when N =< 1 -> N;
fib(N) -> fib(N - 1) + fib(N - 2).

A chamada desde código após a compilação é trivial, por exemplo:
fibonacci:fib(10)

O código em Haskell é muito semelhante (como não seria com esse pingo de código? :D)

fib n
| n <= 1 = n
| otherwise = fib (n-1) + fib (n-2)

Vá brincando, tente números mais altos, com 50 já vai demorar bastante o resultado, o que me sugestiona implementar algum mecanismo de programação dinâmica, uma idéia para um próximo post é implementar isso usando um processo servidor de resultados, exercitando então o mecanismo de troca de mensagens.

Finalizo por aqui, e clique aqui se quiser conferir a lista dos 500 primeiros valores para a série de Fibonacci.

terça-feira, maio 01, 2007

Que linguagem você é?

You are PHP.  You enjoy the World Wide Web.  You are constantly changing the way you do things, and this tends to confuse people who work with you.
Which Programming Language are You?



Pô!!! PHP?!?! Sacanagem... :)

Vi isto no blog do Walter Cruz.

terça-feira, abril 24, 2007

Olá via FeedBurner

Adeus aos feeds não rastreáveis do blogger :D

Sempre ouvi (na realidade li) que o Feedburner oferece um excelente serviço, então decidi conferir, principalmente porque quero conferir quantas pessoas estão lendo meu blog.

Leio muitos feeds, muito raramente vou ao site ler algo, então acompanhar quantas pessoas estão lendo teus textos pelos page views não dá, uma solução de tracking dos feeds é necessária, e como pode ver (se estiver lendo através da página ;)) na direita está o "Feedburner FeedCount", que te informa o número de leitores do feed provido por este blog.

Outro serviço legal do FeedBurner é o PingShot, que notifica vários servidores quando um novo post é publicado, muito útil, por exemplo, para usuários do Blogger como eu, que não possuem um serviço como este disponível.

Para seguir a filosofia DRY, editei o template do blog para não disponibilizar o feed que o Blogger provê. Para fazer isto vi que existe uma tag <b:include data="'blog'" name="'all-head-content'"/> entre o <head> e o <title>, esta tag é depois substituida por tags <link> e <meta>. Apenas substitui esta tag pelo código gerado por ela, substituídos os <link> relacionados a feed RSS/Atom dos posts pelo <link> oferencendo feed Atom do FeedBurner.

domingo, abril 15, 2007

Concordo: IE6 deve morrer

Como o Blogger não suporta Trackback ainda, então vai na mão mesmo:
http://www.tableless.com.br/ie6-deve-morrer

Na última sexta-feira, 13 por coincidência, tive 2 dores de cabeça com o IE6.

Problema #1: um Javascript responsável por salvar alguns dados no servidor:


for (country in countries) { ... }


isso funciona no Firefox, porém o IE acusava um problema. Graças a um debugger de Javascript que tenho instalado, consegui constatar que era esta expressão a culpada, então um amigo falou: "Coloca um var ali na declaração de country". Dito e feito, o correto é:


for (var country in countries) { ... }


Problema #2: tags A com background-image, quando se passava o mouse por cima do link, algumas vezes, acontecia que a imagem desaparecia e aparecia novamente, em inglês flickering. Pesquisando vi que isso já é um bug conhecido do IE6, uma página fazia uma série de teorias explicando o porque daquele bug, outra apenas relatava a solução que foi adotada, a terceira e última foi mais útil, explica que a causa do problema está nos response headers HTTP, mais precisamente no Expires. Como queria uma solução mais rápida e que respondesse na mesma moeda ao IE, optei pela solução que usa um Javascript apenas no IE6, que altera um parâmetro não documentado do browser:

<!--[if IE 6]><script type="text/javascript">
try {
document.execCommand("BackgroundImageCache", false, true);
} catch(err) {}
</script><![endif]-->

Solucionado! Muito melhor que perder tempo² (meu tempo desenvolvendo uma solução para retornar as imagens com o header Expires, e o tempo do processador do servidor depois para servir as imagens através dessa solução e não do procedimento padrão do servidor HTTP).