May 11, 2008

Nerd test

Eu acabei de fazer a nova versão do nerd test. Esse foi o resultado:

NerdTests.com says I'm a Nerd King.  What are you?  Click here!

Posted at 22:13

May 10, 2008

Paranóia nunca é demais

Depois que li o livro Unix Backup and Recovery eu fiquei extremamente paranóico com backups. Eu faço cópias de segurança periodicamente para DVDs de boa qualidade além de fazer uma cópia de todo meu $HOME para um disco rígido externo.

Essas medidas, além de me fazerm dormir melhor a noite, protegem meus dados contra possíveis problemas no meu computador. Contudo elas são ineficientes se um desastre maior acontecer onde guardo as mídias (incêndio, inundação, mofo, roubo, queda de meteoro, [coloque aqui sua catastrofe preferida]). E isso pertuba o meu sono :-)

Uma solução prática para isso é enviar as mídias de backup para um lugar seguro. Como eu ainda não achei um lugar para isso na cidade onde moro, resolvi experimentar um serviço de backup online. Para a minha surpresa, a maioria dos serviços que vi é nerd-unfriendly. Esses serviços necessitam de programas gráficos e propietários instalados na maquina do cliente. Esqueça.

O rsync.net é a solução perfeita para os meus problemas. Ele é bem nerd-friendly, tem um suporte ótimo, aceita backups com rsync em um linha encriptada. Além disso os backups podem ser armazenados encriptados.

Posted at 07:51

Sep 12, 2007

Carta favorita

Eu sou um grande fã de Richard Feynman. Depois de ler, reler e reler o delicioso Surely You're Joking, Mr. Feynman!, e ler What Do You Care What Other People Think?: Further Adventures of a Curious Character, No Ordinary Genius: The Illustrated Richard Feynman, Genius: The Life and Science of Richard Feynman, provavelmente minha citação favorita dele vem do livro com suas cartas em Perfectly Reasonable Deviations From The Beaten Track: The Letters Of Richard P. Feynman.

Feynman gostava muito de percussão e sempre se irritava quando as pessoas achavam curioso um cientista famoso gostar de algo artístico. Quando um editor escreveu pedindo uma fotografia dele tocando tambor para dar uma "abordagem humana para a apresentação da dificuldade que a física teórica representa", Feynman respondeu:

Caro Sr,

O fato que eu toco percussão não tem nada a ver com o fato que eu faço
física teórica. Física teórica é uma atividade humana, um dos maiores
desenvolvimentos dos seres humanos, e o desejo perpétuo de provar que
pessoas que fazem isso [física teórica] são humanos mostrando que eles
fazem outras coisas que alguns outros humanos fazem (como tocar bongô)
é insultante para mim.

Eu sou humano o suficiente para dizer para você ir para o inferno.

Atenciosamente,
RPF

Posted at 06:04

Aug 23, 2007

Lisp e parênteses

As pessoas sempre reclamam da quantidade de parênteses em Lisp. Contudo elas falham em perceber que outras linguagens tem tantos elementos sintáticos quanto lisp, ou até mais, só que como eles são diferentes entre si ficam "espalhados" pelo código não dando uma sensação tão presente como os parênteses de Lisp. Como um exemplo simples, comparemos uma função simples e não otimizada para calcular números de fibonacci em Pascal e em Common Lisp: O código em Pascal:
function fib(N : integer) : integer;
begin
  if N < 2 then 
    fib := N;
  else
    fib := fib (N - 1) + fib (N - 2);
end;
O código em Lisp:
(defun fib (n)
  (if (< n 2)
      n
      (+ (fib (- n 1))
         (fib (- n 2)))))
A primeira vista o código em Lisp parece mais "poluído", com inúmeros parênteses, né? Bom, se excluirmos todas as coisas que o código em Pascal tem em comum com o código em Lisp (por exemplo, function é equivalente a defun, if, +, e - tem em ambos, etc) deixamos somente os elementos sintáticos que Pascal tem mas Lisp não precisa, teremos algo como:
: integer : integer ;
begin
then
fib :=
else
fib := ;
end;
Ou seja, 15 elementos sintáticos. Por outro lado, se fizermos o mesmo com Lisp, isso é, tirarmos tudo que o código Lisp tem em comum com o código em Pascal, vamos terminar com isso:
(
(()
(()())))
ou seja, um total de 12 elementos sintáticos. Não apenas o código em Lisp tem menos elementos sintáticos, como eles são uniformes (apenas parênteses), enquanto o código em Pascal tem vários elementos diferentes que o programador tem que se lembrar. Esse é um ponto-chave ao se programar em Lisp; na superfície parece que a linguagem é inundada de parênteses, mas no fundo, o número de elementos sintáticos é o mesmo, ou até menor, que a maioria das linguagens. Com a vantagem de que os elementos sintáticos usados são mais uniformes (apenas parênteses), enquanto que outras linguagens usam diversas coisas como parênteses, virgulas, pontos, colchetes, etc.

Posted at 14:05

May 26, 2007

Comandos mais usados

O comando abaixo permite ver de maneira simples quais os comandos que você executa mais frequentemente no linux:
history | awk '{print $2}' | awk 'BEGIN {FS="|"} {print $1}'| \
        sort | uniq -c | sort -rn| head -10 
Só por diversão é comum alguns hackers verificarem seus comandos mais comuns e postarem em algum lugar. O Dorneles postou seus comandos mais comuns, e de quebra mostrou uma implementação em Python.

Como Lisp não é (erroneamente) considerada uma linguagem apropriada para escrever scripts de sistema eu gosto de fazer uma uma versão em Lisp de scripts como esse para ver como ela se sai. A minha implementação pode ser vista abaixo. Eu usei apenas ANSI Common Lisp. Se eu tivesse usado bibliotecas externas o código poderia ser ainda mais compacto.

(defun get-comandos ()
  (with-open-file (stream "/home/kroger/.bash_history")
    (loop for line = (read-line stream nil nil) while line
       collect (subseq line 0 (position #\Space line)))))

(defun conta-itens ()
  (let ((comandos (get-comandos)))
    (mapcar (lambda (item) (list (count item comandos :test #'string=) item))
            (remove-duplicates comandos :test #'string=))))

(format t "~{~{~a ~}~%~}" (sort (conta-itens) #'> :key #'first))
O objetivo aqui não é, naturalmente, fazer uma comparação com python (no estilo "minha linguagem é melhor que a sua"), mas sim ver como Lisp se sai nesse tipo de coisa. Eu acho que o resultado foi bem satisfatório. Lisp não tem nenhum comando padrão para ler todo o arquivo em uma string, mas dá para fazer isso com apenas 2 linhas de código. A função count conta quantas vezes um item aparece em uma sequencia, de modo que foi possivel implementar o código para contar os elementos de uma maneira funcional.

Um pouco de estatísticas: a implementação de python tem 14 linhas e 46 caracteres, enquanto a implementação em lisp tem 10 linhas e 52 caracteres. A implementação em lisp é mais curta, porém mais densa.

Eu não tenho dúvidas que é possível escrever um código em python ainda menor, mas como eu disse anteriormente, esse não é o objetivo aqui. Meu objetivo foi mostrar como é possível escrever um código simples, curto, e elegante em Lisp para lidar com coisas corriqueiras do dia-a-dia.

Posted at 12:15