Elmord's Magic Valley

Computers, languages, and computer languages. Às vezes em Português, sometimes in English.

Posts com a tag: em-portugues

Trocando de janela pelo nome

2015-06-23 02:50 -0300. Tags: comp, unix, em-portugues

Por uma série de acidentes enquanto experimentava window managers hoje,

  1. Eu me dei conta de que seria bem conveniente poder trocar de janela digitando uma parte do título ao invés de procurar na barra de tarefas ou dar vinte Alt+Tabs até encontrar a janela. (Eu me dei conta disso quando, depois de não conseguir achar a janela que eu queria no i3, a minha primeira reação foi querer dar C-x b (o comando switch-buffer do Emacs) e digitar o nome da janela.)
  2. Eu descobri ferramentas apropriadas para tornar isso possível.

[Screenshot do programa 'dmenu']

Você vai precisar de:

Com isso, podemos escrever um pequeno script para apresentar um menu e selecionar a janela escolhida.

O script

#!/bin/bash

option="$(
    wmctrl -xl |
        #         \1       \2       \3       \4       \5
        #         win-id   desktop  class    hostname title
        sed -r 's|([^ ]* +)([^ ]* +)([^ ]* +)([^ ]* +)(.*)|\1 \3 \5|' |
        sort -k 3 |
        dmenu -i -l 10
    )" || exit 1

wmctrl -ia "${option%% *}"

wmctrl -l lista as janelas existentes. A opção -x inclui a classe da janela na listagem. O sed não é estritamente necessário, mas deixa a lista menos poluída removendo campos desnecessários; você pode alterar essa linha para escolher os campos. O ID da janela é meio irrelevante para o usuário, mas precisamos dele para poder passá-lo ao wmctrl para ativar a janela.

sort -k 3 ordena o menu pelo título da janela. Você pode comentar essa linha fora se não quiser ordenar a lista, ou mudar os parâmetros para obter uma ordem diferente (e.g., sort -k 2 para ordenar pela classe).

Quanto ao dmenu, a opção -i faz com que ele ignore maiúsculas vs. minúsculas ao filtrar as opções pelo texto digitado pelo usuário. -l 10 indica que queremos uma opção por linha, e que no máximo 10 linhas devem ser mostradas de cada vez. Por padrão, o dmenu usa apenas uma linha e mostra as opções lado a lado. (Uma coisa meio ruim do dmenu é que ele não dá nenhuma indicação de que é possível scrollar o menu; ele só mostra as primeiras N opções e as demais ficam escondidas.)

wmctrl -a JANELA ativa a primeira janela cujo título contenha a string specificada. Como queremos que a seleção seja inambígua, utilizamos a opção -i, que permite especificar o ID da janela ao invés do título. Para extrair o ID da seleção, removemos tudo depois do primeiro espaço na string ("${option%% *}").

Instalação

Salve o script no local de sua preferência, dê permissão de execução a ele (chmod +x nome-do-script), e associe-o a alguma tecla de atalho no seu ambiente gráfico favorito. Por exemplo, no IceWM isso pode ser feito adicionando no ~/.icewm/keys uma linha como:

key "Super+Tab" /caminho/do/script

substituindo Super+Tab pelo atalho de sua preferência (Super é a tecla "janelinha").

Para mais informações e possibilidades, consulte a manpage dos programas.

2 comentários / comments

Ensinando inglês

2015-06-09 23:28 -0300. Tags: lang, comic, img, random, em-portugues

Quadrinho:

Quadro 1:

B: Como se diz "fazer" em inglês?

A: "Do".

B: Mas "do" não é pra fazer pergunta?

---

Quadro 2 (cena imaginada por A):

A: Ah, sim, o inglês usa "do" como um auxiliar dummy em perguntas, provavelmente como uma maneira de equilibrar a tendência histórica do inglês de deslocar o verbo para o começo em perguntas, como as demais línguas germânicas, com a tendência a  uma ordem SVO mais rígida, provavelmente motivada pela perda de morfologia que permita distinguir substantivos e verbos em inglês, o que pressiona a língua a desambiguar usando a sintaxe ...

---

Quadro 3:

A:

A: É, serve pra fazer pergunta também.

Baseado em fatos reais.

(E eu ia mudar o texto para "distinguir substantivos e verbos facilmente em inglês", mas já gastei meu estoque de paciência com o GIMP hoje.)

2 comentários / comments

Emacs, again

2015-06-05 02:30 -0300. Tags: comp, editor, emacs, em-portugues

No último sábado eu resolvi experimentar usar o Emacs de novo. O plano era ficar usando durante um mês e depois escrever um post relatando a experiência. Porém, como ao longo dos três anos de blog eu observei que em geral quando eu deixo um post para escrever depois eu acabo não escrevendo, em parte porque eu acabo esquecendo o que eu ia escrever, resolvi escrever um post inicial agora. (Além disso, quando eu comecei a escrever esse post eu não estava conseguindo dormir e precisava passar o tempo.)

So far, estou curtindo horrores.

Da primeira vez que eu tentei usar o Emacs, eu larguei de mão em dois ou três dias. Acho que o principal fator de diferença foi que dessa vez eu resolvi usar a versão gráfica do Emacs. Assim, quando eu não consigo fazer alguma coisa pelos comandos de teclado eu posso recorrer ao mouse e get stuff done. Dito isso, como eu não sou exatamente um fã do mouse, na prática eu acabo me motivando a aprender os comandos anyway.

(Um vício bem mais difícil de eu me livrar é usar as setas, Home/End e afins ao invés dos comandos "tradicionais" do Emacs. Right now eu larguei um pano de prato por cima do lado não-alfabético do teclado para ver se me habituo a não usar essas teclas.)

Mas por quê?

Tudo começou porque eu estava meio de saco cheio do Claws Mail, experimentei o Thunderbird e não gostei muito (não lembro mais por quê), e aí lembrei do Gnus e resolvi experimentar. No fim das contas eu consegui resolver o problema que eu estava tendo com o Claws comentando fora um teste no código-fonte e não curti muito o Gnus, mas a essas alturas eu já tinha mexido um bocado no Emacs e ressurgiu o interesse, reforçado pelos seguintes acontecimentos:

E aqui estamos.

Coming from Vim...

Em alguns aspectos, o Emacs pode ser mais "difícil" de usar do que o Vim. Seguem algumas observações nesse sentido.

Enquanto usar o Vim sem nenhuma customização é relativamente ok, usar o Emacs sem nenhuma customização não é uma experiência tão agradável. Desde que eu comecei a usar o Emacs, quase todo dia eu adiciono alguma coisa no meu ~/.emacs, que provavelmente vai continuar crescendo na mesma taxa por um bom tempo. (De certa forma o ponto do editor é ser customizado/reprogramado to death, então eu desconfio que enquanto eu usar o Emacs eu não vou parar de mexer no ~/.emacs; porém, eu espero mexer nele com menos freqüência depois de algum tempo de uso.)

Além disso, embora o Emacs ganhe bonito em flexibilidade, certas configurações simples são mais fáceis de fazer no Vim do que no Emacs. Por exemplo, no Vim define-se um keybinding novo em termos das teclas que teriam que ser pressionadas para realizar o comando desejado. No Emacs, cada tecla é associada a uma função que é executada quando a tecla é pressionada, o que por um lado é bem mais limpo do que a maneira como o Vim faz as coisas (definir uma ação complexa em termos de keypresses pode ser um inferno), mas por outro lado exige que uma função em Emacs Lisp seja definida sempre que se quer associar uma seqüência de comandos a uma tecla.

Dito isso, Emacs Lisp é uma linguagem infinitamente mais agradável de usar do que Vimscript. Além disso, é fácil descobrir qual é o nome da função associada a cada tecla, usando os comandos Ctrl-h k (describe-key) e Ctrl-h c (describe-key-briefly), o que facilita na hora de definir funções novas em termos das funções das teclas existentes.

Além disso, embora eu tenha mudado as cores do editor para texto branco no fundo preto, o restante do esquema de cores se adaptou sozinho, e eu achei o esquema de cores tão bom que nem desativei o syntax highlighting (que normalmente é a primeira coisa que eu faço quando uso o Vim em outro computador). A única exceção foi o AUCTeX, que escolheu umas cores diferentes do resto do editor por alguma razão.

Comandos

Enquanto o Vim possui um modo específico para dar comandos (o Normal mode), o que permite que os comandos sejam teclas simples1, o Emacs possui apenas um "modo" (no sentido Vim da palavra2), e os comandos de edição normalmente são introduzidos por um keystroke envolvendo Control ou Alt (Meta no linguajar emacsístico). Muitos comandos exigem uma seqüência de keystrokes: o comando para abrir um arquivo é Ctrl-x Ctrl-f, por exemplo, e o comando para abrir um arquivo em uma nova janela é Ctrl-x 4 Ctrl-f. Da primeira vez que eu experimentei o Emacs eu achei esses comandos totalmente bizarros e meio que larguei ele de mão por causa disso. Porém, agora que eu resolvi usar o editor de novo com a mente em um modo (heh) mais propenso a aceitar coisas novas (e com a interface gráfica para me salvar nos momentos difíceis), eu tenho me adaptado aos comandos novos relativamente fácil.

Embora seja tentador logo no começo alterar o keymap para usar comandos mais intuitivos, eu resolvi fazer um esforço para aprender os comandos convencionais do editor, e só definir keybindings novas para comandos que eu mesmo criei ou que não têm uma keybinding padrão, for most part. Até agora tem sido relativamente tranqüilo. Se depois de mais tempo de uso eu vir que algum keybinding realmente não me agrada, eu mudo. O mais difícil tem sido lembrar de usar Ctrl-s no Emacs e Ctrl-f no Firefox para procurar texto, e usar Ctrl-f (forward) para avançar um caractere e Ctrl-b (back) para voltar um caractere, e analogamente Meta-f e Meta-b para avançar e voltar uma palavra. Esses aí eu sou capaz de acabar rebindando para Ctrl-. e Ctrl-, ou algo do tipo (ou me conformar em usar as setas mesmo), se não me habituar nas próximas semanas.

O Emacs usa uma notação especial para descrever keystrokes. Basicamente, C-x significa Ctrl-x, M-x significa Meta-x (Alt-x), C-M-x significa Ctrl-Meta-x, RET é o Enter, SPC é o espaço, DEL é o backspace, e seqüências de teclas são escritas separadas por espaço (C-x C-f significa "tecle Ctrl-x, e depois tecle Ctrl-f"). Eu vou usar essa notação no restante do post.

Uma coisa legal do Emacs é que todo comando possui um nome (o nome da função Lisp que o implementa). Mesmo quando não se sabe o atalho de teclado que ativa o comando, é possível dar M-x e digitar o nome do comando (que freqüentemente é relativamente fácil de adivinhar, pois a nomenclatura é mais ou menos consistente; além disso é possível usar TAB para completar os nomes). Se o comando possui um atalho associado, após executar o comando o Emacs mostra uma mensagem como You can run the command `mark-paragraph' with M-h, e assim você aprende a tecla do comando.

Outra coisa que ajuda é que o help do Emacs é muito bom de usar. Todos os comandos de ajuda começam com C-h; C-h ? mostra todas as opções de ajuda. C-h f mostra a documentação de uma função ou comando, C-h k mostra a documentação do comando associado a uma tecla, C-h c mostra o nome do comando associado à tecla, C-h m mostra a documentação do modo atual, C-h r abre o manual do Emacs, entre outros. Como já mencionado, a documentação de uma função vem com um link para o código-fonte, quando disponível (no Debian, é necessário instalar o pacote emacs24-el). O link não é parte do texto da documentação, mas sim uma funcionalidade do próprio Emacs: se você pedir o help de uma função que você mesmo definiu no seu ~/.emacs, o Emacs vai mostrar um link para o ponto da definição no arquivo. (Até as poucas funções definidas em C têm links para a definição no fonte, mas nesse caso o Emacs abre uma janela perguntando o diretório onde se encontra o fonte C do Emacs, que eu não tenho aqui.)

Uma coisa um pouco ruim é que quase todos os keystrokes já têm um comando associado, seja por padrão, seja pelo modo em uso, o que limita as escolhas para novos keybindings que não conflitem com os existentes. Por convenção, o Emacs reserva C-c seguido por uma letra para o usuário, mas C-c seguido por outras coisas são reservados para os modos. Porém, existe um refúgio: a tecla C-z por padrão vem associada ao comando suspend-frame, que suspende o Emacs em modo texto e minimiza a janela no modo gráfico. Eu basicamente não uso esse comando no modo gráfico anyway (e ele também fica acessível via C-x C-z), então o que eu fiz foi rebindar ele como uma "prefix key" e colocar os comandos novos que eu defino sob o C-z (por exemplo, C-z C-z para salvar e fechar o arquivo e C-z d para inserir a data atual). Como C-z é um comando padrão do Emacs, isso tem a vantagem de que basicamente nenhum modo usa essa tecla.

Emacs as a daemon

Enquanto o modo de uso normal do Vim (e editores de texto em geral) é abrir o editor, editar arquivos e fechar, o modo de uso normal do Emacs (e sistemas operacionais em geral) é deixar o editor aberto o tempo inteiro enquanto se está trabalhando, em parte porque o editor tende a acumular estado (arquivos e aplicativos abertos, modos em uso), em parte porque ele demora um pouco mais para carregar do que o Vim (especialmente a versão gráfica, e especialmente se o ~/.emacs faz mil coisas na inicialização). Porém, é possível rodar o Emacs como um daemon, e aí pode-se usar o comando emacsclient para abrir um novo "frame" (janela) do Emacs conectado à sessão já em execução, o que é mais rápido do que iniciar o editor do zero. emacsclient -a "" inicia um daemon automaticamente se já não houver um rodando, e conecta-se a um existente se houver. Além disso, é possível passar as opções -t para rodar no terminal e -c para criar uma nova janela gráfica (por padrão ele abre o arquivo passado na linha de comando em uma janela existente, se houver). É um comando bem útil para setar como o valor da variável de ambiente EDITOR, que programas como git, crontab, etc., usam para determinar o editor a ser usado.

Shell mode

O Emacs possui um "modo shell" (M-x shell), que executa o bash ou afim dentro de um buffer do Emacs, onde os comandos normais de edição do Emacs ficam disponíveis. O modo tem algumas bizarrices (o texto é um buffer normal, o que significa que é possível editar a saída dos comandos que já foram executados, apagar o prompt [update: isso é controlável pela variável comint-prompt-read-only; mais informações no help da variável (C-h v comint-prompt-read-only)], etc.), mas é interessante se você quer realizar o máximo de tarefas possível sem sair do Emacs.

O shell mode toma conta do completion de nomes de arquivos e comandos, mas ele usa a função de completion do Emacs, que por padrão exclui certos tipos de arquivos que normalmente não se tem interesse em abrir num editor de textos (e.g., arquivos .o), o que não faz muito sentido em um shell. A solução que eu encontrei foi adicionar um "hook" (função que roda quando um modo é iniciado) no meu ~/.emacs que anula a lista de extensões a ignorar no buffer do shell.

Outro "gotcha" é que como o buffer usa os comandos normais do Emacs, coisas como Ctrl-C, seta para cima, etc., não têm o comportamento normal do terminal. Os comandos Ctrl-* devem ser precedidos de C-c (e.g., C-c C-c para interromper o processo, C-c C-z para suspender, etc.). Manipulação de histórico é feita através de M-p e M-n (de "previous" e "next", análogo ao C-p e C-n para trocar de linha no buffer).

Como trata-se de um buffer simples, coisas que exigem poderes "gráficos" do terminal, como aplicativos de tela cheia, não funcionam no shell mode. Porém, é possível adicionar suporte a cores no buffer (para coisas como ls --color) rodando a função ansi-color-for-comint-mode-on (seja via M-x, seja no ~/.emacsrc (lembrando de pôr parênteses em volta do comando nesse caso)). Vale ainda notar que o shell mode seta a variável de ambiente TERM para dumb, o que faz com que ls, grep e companhia não usem cores por default. É possível contornar isso alterando o ~/.bashrc para mudar o valor de TERM (para vt100, por exemplo) se a variável INSIDE_EMACS estiver setada, mas aí os programas que usam TERM para decidir se vão operar em modo tela cheia ou não vão incorretamente assumir que podem rodar em tela cheia dentro do shell mode. Não sei se há algum valor de TERM que indique suporte a cores mas não às demais funções gráficas do terminal.

Também existe um "modo terminal" (M-x term), que é um emulador de terminal de verdade (não apenas um buffer com um shell) onde se pode rodar qualquer programa de terminal, mas aí perdem-se os comandos normais do Emacs. Além disso, pelo que eu testei o emulador é pra lá de lento (o alsamixer leva uns três ou quatro segundos para abrir com o processador a 800MHz3).

M-x finish-post RET

Por hoje ficamos por aqui. Eu provavelmente hei de postar mais coisas à medida em que for descobrindo funções novas no editor, e atualizar meu ~/.emacs no GitHub ocasionalmente.

_____

1 Na verdade, faz uns cinco anos que eu uso o Vim com keybindings especiais para não ter que trocar de modo para os comandos de edição mais freqüentes, então eu já usava um editor não-modal for most part, o que significa que de certa forma eu não aproveitava muito das vantagens de usar o Vim.

2 O que o Emacs chama de modos são coisas como o html-mode, latex-mode, c-mode, etc., chamados major modes, que alteram o comportamento do editor (como comandos e syntax highlighting) para facilitar a edição de um certo tipo de arquivo, ou aplicações como o Gnus. Também há os minor modes, que são usados em conjunto com os major modes e se comportam mais ou menos como algumas opções ativadas com :set no Vim.

3 Normalmente eu uso a máquina em modo de economia de energia e só seto o governor do cpufreq para performance quando vou fazer alguma coisa mais pesada, primariamente porque com a freqüência baixa o fan faz menos barulho.

9 comentários / comments

Blog multilíngüe

2015-05-31 00:19 -0300. Tags: about, em-portugues

Faz uma porção de tempo que eu venho considerando a possibilidade de postar algumas coisas em inglês por aqui. Isso é uma coisa que ainda me deixa meio receoso, mas tem algumas situações em que eu acho que postar em inglês seria mais útil, seja para o mundo (e.g., posts sobre o Chicken, em que a comunidade de usuários é pequena (acho) e limitar a audiência a falantes de português seria muito... limitante), seja para mim (e.g., posts sobre design de linguagens de programação, em que eu hipoteticamente poderia ter feedback de mais gente se eu escrevesse em inglês), seja para ambos (e.g., posts sobre o lash, ou conlanging).

Pronto, falei.

Eu pensei em criar um blog separado para postar em inglês, mas aí pensei que isso seria inconveniente para os leitores usuais (todos os quais falam inglês anyway, dos que eu conheço), que teriam que olhar em dois lugares diferentes para ver se há posts novos. Por ora, o que eu provavelmente vou acabar fazendo é postar tudo aqui e usar uma tag english nos posts em inglês, até eu arranjar uma solução melhor.

Na verdade, desde antes dos primórdios deste blog, uma das motivações originais para eu escrever meu próprio blog system ao invés de usar um pronto era implementar suporte a multilingualismo "the right way". Eu estive pensando sobre isso e me dei conta de que é mais complicado do que parece. Por exemplo:

Enfim, nada muito difícil de implementar, na verdade, mas é um bocado de coisas que eu não tinha parado para pensar antes.

4 comentários / comments

lash status update

2015-05-14 23:42 -0300. Tags: comp, prog, pldesign, lash, life, em-portugues

Faz quase dois meses desde o primeiro commit do lash. O status do projeto é o seguinte:

No decorrer dessa última semana, o parser original, baseado na biblioteca Comparse de parser combinators, foi substituído por um parser descendente recursivo escrito à mão. Os motivos principais para a reescrita foram que a Comparse não mantém informação de linha e coluna dos elementos parseados, aparentemente não tem suporte nenhum a error reporting (o parser simplesmente "backtracka" quando se depara com um erro, até que o parser inicial backtracka e devolve #f), e o parser estava com uns comportamentos estranhos diante de algumas entradas (o que não é culpa da Comparse, mas não tinha por que eu perder tempo debugando se eu já teria que reescrever o parser uma hora ou outra pelos outros motivos citados). O handling de espaços e newlines no parser antigo também estava o caos, enquanto no atual aparentemente tudo funciona como deveria nesse quesito.

O parser novo reconhece quase toda a linguagem prevista para a "release inicial", lança exceções nos pontos certos do código ao encontrar erros de sintaxe (embora as exceções ainda não sejam muito descritiva, mas já é um começo), e armazena a linha e a coluna de cada construção nos nós da árvore sintática (com pequenos erros, mas nada difícil de resolver). O código ainda está meio crude, e tem muita coisa que ainda dá para refatorar (e.g., repetições que estão codificadas como loops explícitos ao invés de uma construção que abstraia a repetição), mas isso vai ir se resolvendo ao longo do tempo. De repente as partes mais abstratas do parser podem até virar uma biblioteca de parser combinators no futuro (com a diferença de que eu estou usando uma struct mutável e exceções ao invés de uma mônada para manter o estado do parser e indicar erros, o que seria meio unusual para uma biblioteca de parser combinators, mas whatever; ninguém disse que seriam parser combinators funcionais).

O parser novo reconhece mais construções do que o resto do shell é capaz de executar (por exemplo, pipelines, redirects, &, &&, ||, $()... em outras palavras, praticamente todas as funções do shell), o que de certa forma é bom, porque me compele a implementar as coisas que faltam. Nos últimos dias o desenvolvimento anda numa taxa mais ou menos ok (para mim), e acho que é mais ou menos realista prever uma release 0.1* mais ou menos funcional para julho. Pelo menos é (mais ou menos) isso que eu espero. Isso é bom, porque em um momento de otimismo em março eu submeti uma proposta de palestra para o FISL sobre o shell e, na vaga possibilidade de ela ser aceita, até lá seria bom o shell estar num estado usável. (Eu submeti a proposta sob a premissa de que se tudo desse errado com o shell e eu fosse aceito era só pedir para tirarem a palestra, mas a essa altura acho que isso não será mais necessário. Tudo isso assumindo que eu seja aceito, o que seria muito doido, na real.)

Comecei a usar a wiki do projeto no GitHub para fazer anotações. O plano que ela venha a conter:

Para editar a wiki é necessário criar uma conta no GitHub, aparentemente, mas acho que podemos conviver com isso. Contribuições são sempre bem-vindas.

Quanto à linguagem do shell, algumas coisas mudaram:

Durante o desenvolvimento do novo parser eu descobri um "bug" no Chicken que faz com que variáveis criadas com define dentro de um cond sejam declaradas como globais. A galera na mailing list parece ser da opinião de que isso não é um bug e sim uma feature, entretanto. Meanwhile, eu resolvi o problema no lash redefinindo o cond para wrappear as cláusulas em um (let () ...) implícito (o que cria um "scope boundary" que torna as definições locais), e de brinde ainda lançar uma exceção se nenhuma cláusula for verdadeira. Scheme, yay.

Enquanto o lash anda às mil maravilhas, o mestrado vai por água abaixo, mas isso é assunto possivelmente para outro post.

_____

* No momento eu não estou numerando as versões, mas pelo esquema de numeração previsto (<major>.<minor>.<número de commits desde o último update do minor>), estaríamos na versão 0.0.31. Parece bastante, mas é porque eu tenho o hábito de commitar loucamente enquanto estou mexendo no código.

1 comentário / comment

Breakup

2015-05-14 20:55 -0300. Tags: lang, img, random, comic, em-portugues

Para fins de conservação para a posteridade, inflijo-vos este quadrinho que eu postei no reddit mais ou menos um ano atrás.

Quadrinho:
A: So you and Mary are over?
B: Yeah.

A: Why? You made such a good couple.
B: It would never work out. She thinks Proto-Indo-European had an */a/.
A: Oh. What?

B: I told her: "Maybe in the latest stages, but not originally. */a/ is really just underlying */eh₂/". But she shook her head and said: "Not typologically plausible". It was horrible.
A: WTF?
B: Yeah, I know!

1 comentário / comment

You're doing it completely wrong

2015-04-28 22:03 -0300. Tags: comp, prog, wrong, ramble, em-portugues

Encontrei um e-mail de três anos atrás que explica uma das coisas que eu acho que estão "completely wrong" com os ambientes computacionais modernos. O texto era para ter servido de base para um post que nunca foi escrito. Reproduzo-o semi-intacto abaixo. (Fico feliz que a minha visão ainda seja a mesma, mas por outro lado o "plano para os próximos dez mil anos" parece longe de se realizar...)

* * *

From: Vítor De Araújo
To: Carolina Nogueira
Subject: You're doing it completely wrong
Date: Mon, 12 Mar 2012 00:37:18 -0300

[Core dump follows.]

Acho que eu não vou escrever o post tão cedo, então explico agora. O que há de completely wrong é que os programas em execução são "caixas pretas"; em geral um programa é um brinquedo estático, que tu não pode "olhar dentro" e modificar facilmente. Em um mundo ideal tu deveria poder alterar partes de qualquer programa sem ter que recompilar tudo, e de preferência sem sequer ter que fechar e abrir o programa para as mudanças entrarem em efeito.

Exemplo simples: o Pidgin a cada 60 segundos manda um "XMPP ping" pro servidor de XMPP (Jabber), para ver se a conexão ainda está de pé. Se eu quiser mudar de quanto em quanto tempo ele manda o request, ou quanto tempo ele espera por uma resposta, eu tenho que alterar o fonte. Idealmente:

  1. Isso poderia ser (e talvez já seja) uma variavelzinha feliz do programa, que eu deveria poder alterar durante a execução;
  2. Alterar o fonte não deveria ser nenhum grande mistério; o fonte deveria ser facilmente acessível e modificável a partir do programa, e eu deveria poder recompilar uma função ou módulo individual sem ter que recompilar o universo. (Mais de uma vez eu quis mudar coisinhas simples do Pidgin, e.g., eliminar o atalho Ctrl-Up, que bizonhamente exigem alterar o fonte, e falhei miseravelmente em conseguir fazer o troço compilar.)

Além disso, deveria ser fácil desfazer qualquer modificação. Versioning é uma tecnologia muito supimpa dos anos 60 que, como muitas tecnologias supimpas do passado, se perdeu com a popularização de maquininhas pequenas com recursos insuficientes pra suportar a coisa. Hoje em dia temos recursos sobrando, mas a tecnologia caiu no esquecimento.

Exemplo menos simples: o Claws Mail por padrão ordena as mensagens em ordem ascendente de data (da mais antiga pra mais recente), e ele lembra o critério de ordenação por pasta, o que quer dizer que o usuário tem que alterar pra ordem decrescente individualmente pra cada uma das mais de oito mil pastas que há (Inbox, Sent, Queue, Trash, Drafts pra cada mailbox, mais os feeds de RSS). Provavelmente 99.5% das pessoas esperam ordem decrescente por padrão, e provavelmente teria que alterar pouca coisa do código pra mudar o padrão, mas a barreira pra alterar o software é muito grande (baixar fontes, encontrar o trecho de código relevante, se entender com ./configures e bibliotecas da vida, recompilar o mundo, fechar e abrir o programa). Idealmente, eu deveria poder apontar para um menu relacionado com o que eu quero, teclar alguma combinação mágica, e ir parar na função que aquele menu ativa. Daí em diante eu deveria conseguir navegar pelo código até achar o trecho relevante; os nomes de funções e variáveis deveriam funcionar como links (coisa que acho que é possível com a maior parte das IDEs atuais). Tendo achado o dito cujo, eu deveria poder alterar o código, mandar recompilar aquele trecho, e as mudanças se tornarem imediatamente efetivas.

E aparentemente essa utopia toda já existiu, sob o nome de Lisp Machine. Este cara diz:

Within DW, you can move your mouse over any object or subobject that has been displayed, whether or not it was part of any GUI. You get this virtually for free and have to work hard to suppress it if you don't want it. But it doesn't require any special programming.

One of the most common ways to get a foothold in Genera for debugging something is to (1) find a place where the thing you want to use appears visually, (2) click Super-Left to get the object into your hands for read-eval-print, inspection, etc, (3) use (ed (type-of *)) to find its source reliably and with no foreknowledge of what the type is, who wrote the program, what their file conventions were, who loaded it, or any of myriad other things that other systems make me do.

Quer dizer, tu pode pegar um objeto qualquer presente na tela (e praticamente tudo é um objeto, pelo visto), descobrir o tipo/classe dele e mandar editar o código correspondente [(ed (type-of *))]. Eu queria rodar o simulador de Genera aqui pra ver isso funcionando na prática, mas não consegui fazer ele funcionar total... :-(

Enfim, muita tecnologia gloriosa do passado se perdeu. Um dos meus objetivos para os próximos dez mil anos é avançar o estado da arte a o que ele era nos anos 80... :P

Aí o camarada se pergunta: será que faz sentido ter essa tecnologia em um desktop? Será que o "usuário final" tem algum interesse nisso tudo? A resposta é a mesma que se pode dar para justificar a presença de uma linha de comando em um sistema visando o "usuário final" (e.g., Ubuntu, Mac OS):

  1. Mesmo que o usuário final não tenha interesse, se é de ajuda ao desenvolvedor e não prejudica o usuário de maneira alguma, não há por que não ter a feature.
  2. Alguns usuários têm interesse em explorar o funcionamento do sistema e usar as features mais avançadas. Em particular, se a barreira para editar os programas for pequena e for fácil desfazer quaisquer modificações, é bem possível que muito mais gente tenha interesse em bagunçar com os internals das coisas.
  3. Uma coisa muito legal que se vê com Ubuntus da vida é que mesmo um usuário que não saiba usar a linha de comando pode pedir ajuda num fórum e alguém que sabe pode ajudar o cara a resolver um problema que envolva brincar de linha de comando. Da mesma forma, um usuário poderia resolver problemas que envolvessem alterar um programa com a ajuda de pessoinhas em fóruns e afins.

Além de dar todo o poder para os cidadãos infra-vermelhos, o que lembra um pouco as idéias do camarada Alan Kay [1][2], a tendência é que a facilidade de alterar e testar os programas leve a programas mais bem testados, menos bugados e que tendam à perfeição mais rápido. Todos comemora.

Existem mil dificuldades envolvidas na criação de um sistema assim, especialmente se quisermos abandonar o modelo da Lisp Machine de uma máquina mono-usuário em que todos os processos podem tudo, mas isso fica pra outra discussão.

Escrevi bem mais do que eu pretendia. Parece que eu até tenho material para um post... :P

Comentários / Comments

Um teto

2015-04-20 23:05 -0300. Tags: misc, philosophy, em-portugues

Hoje de madrugada eu acordei com algumas cousas na cabeça que não tinham nenhum motivo aparente para estar lá. E foram as seguintes:

Você provavelmente já ouviu a teoria de que a vida na Terra veio de outro planeta. (Ignoremos o fato de que isso não explica absolutamente nada sobre a origem da vida.) Normalmente a idéia é que a vida surgiu em algum outro lugar e se espalhou pelo universo, veio de brinde num asteróide, etc.

Você também já deve ter ouvido a idéia de que nós vivemos dentro de uma simulação. A idéia é freqüentemente motivada pelo fato de que algumas coisas no nosso universo parecem ter comportamento discreto (i.e., "digital").

Mas e se fosse um pouco diferente...

* * *

Imagine que houvesse uma forma de vida inteligente completamente diferente da nossa (não baseada em DNA) em algum canto do universo. Um belo dia, meio que por acaso, os pesquisadores do planeta Xrbna descobrem essas cousas que nós chamamos ácidos nucléicos, aminoácidos, etc. Talvez inicialmente eles tivessem chegado nessas moléculas puramente teoricamente, i.e., alguém estava ponderando sobre "o que aconteceria se eu montasse uma molécula assim assado" e se deu conta de que ela tinha propriedades interessantes. A galera continua brincando com essas entidades, teorica ou fisicamente, mais ou menos como a galera começou a experimentar com configurações de Life nos anos 1970, até que alguém descobre uma configuração particular que é capaz de produzir cópias semi-idênticas de si mesma. Animados (ou o equivalente alienígena de animados), os xrbnanianos resolvem criar versões físicas da molécula e colocá-las em um ou alguns planetas (de preferência bem longe deles) para ver o que acontecia. Em (pelo menos) um desses planetas, ao longo de alguns bilhõezinhos de anos, aconteceu um bocado de coisas.

Now, eu não estou propondo que foi assim que a vida terrestre surgiu, mas eu estou interessado no cenário. Se a vida na Terra tivesse surgido assim:

Agora suponha que nós déssemos um jeito de criar um equivalente físico de Life ou algo similar. Será que em algum ponto esse sistema desenvolveria consciência? Será que nós reconheceríamos a consciência quando a víssemos? Nós seríamos capazes de entender o que se passa na "cabeça" desse sistema? Nós já temos dificuldade de entender o que se passa na cabeça de outras criaturas vivas mais distantes de nós; nós seríamos capazes de entender uma criatura de uma natureza completamente diferente da nossa? Que outras coisas podem ser "conscientes" à nossa volta sem que nós saibamos? Faz sentido usar o termo "consciente" nesse contexto, ou será que haveria outras propriedades tão interessantes quanto consciência nesses sistemas, mas tão diferentes de o que nós chamamos de consciência que esse termo não seria aplicável?

Quais seriam as implicações éticas de "matar" um jogo de Life "gone conscious"? O jogo só é consciente se for implementado fisicamente, ou uma simulação também é consciente? E se a simulação for feita com papel e caneta ao invés de por uma máquina? E se eu escrever uma fórmula fechada f(i) que calcula o estado do jogo para cada iteração i, a fórmula é consciente, ou "contém consciência" de alguma forma? Se não é, por que não? Em que ponto a informação contida na fórmula se torna consciência?

* * *

Esses questionamentos não são nenhuma novidade para os filósofos, e eu já tinha lido coisas similares na vida, mas acho que essa é a primeira vez que eu realmente entendo ("grok") o problema. Acho que é hora de eu ler o Gödel, Escher, Bach de novo.

7 comentários / comments

Ideogramas

2015-04-17 22:52 -0300. Tags: random, life, lang, em-portugues

me; hahahah, ganhei meu dia aqui
me: abri uma página que era pra ter um ícone de "loading"
µ: hm
me: mas a modinha agora é usar fontes com ícones ao invés de imagens
me: só que o meu browser tá setado pra forçar a usar as minhas fontes ao invés das da página
µ: hm
me: aí o loading virou um ideograma rotatório
µ: hsauoihasoihauias
me: e tu não vai achar graça nenhuma nisso, mas eu curti horrores :P
me: hmm, pelo visto tu achou graça :P
µ: HSAUOHSAIOSAHAOSIHASUOUI
µ: sim
µ: imaginei um ideograma chines significando "paz mundial que se iniciou na cozinha de um homem simplorio" rodando na tua tela

(Eu ainda não descobri que ideograma é esse, by the way.)

Update: O codepoint oficial do caractere (𤃉) é U+240C9. Consegui chegar nele procurando pelos componentes (氵厂禾禾心) no MDBG e depois no CHISE (que eu não conhecia até então). Mas ainda não descobri o que ele significa (o caractere mais próximo que encontrei com significado foi "trickle, drip; strain; dregs").

P.S.:

[Idegrama rotatório de significado desconhecido]

8 comentários / comments

Mind dump

2015-04-10 01:34 -0300. Tags: comp, prog, pldesign, lash, life, mind, ramble, music, em-portugues

Coloquei o lash no GitHub, for what it's worth. Eu me pergunto se foi uma coisa sensata publicar ele agora, mas já faz um tempo que eu vinha anunciando que ia publicar "em breve", então coloquei lá de uma vez. (Além disso, esses dias eu quis mexer nele fora de casa e não tinha o código.) O código está em um estágio bem inicial – vergonhosamente inicial, dado que já faz umas três semanas que comecei a trabalhar nele, e o que eu fiz até agora eu provavelmente poderia ter feito em uns três dias se tivesse tido a disciplina de trabalhar nele semi-diariamente. Por outro lado, o projeto está andando para frente, mesmo que devagar, o que já é melhor do que todos os anos anteriores em que eu disse "puxa, eu queria fazer um shell" e não escrevi uma linha de código. So, that's progress. Além disso, na atual conjuntura eu provavelmente deveria tentar relaxar um pouco a cuca e me preocupar menos com isso; afinal, isso é um projeto pessoal e eu não devo nada para ninguém. No final das contas, megalomanias de dominação mundial à parte, o principal afetado pelo bom sucesso do projeto sou eu mesmo.

Eu cheguei à brilhante e inaudita conclusão de que eu vou ter que reduzir bastante minha atividade twittereira e internética em geral se eu quiser começar a fazer alguma coisa produtiva com a minha vida (onde escrever um shell e estudar línguas obscuras contam como coisas produtivas). Por outro lado, a Internet atualmente é responsável por uns 95% das minhas interações sociais, especialmente agora que eu não tenho mais aulas, coisa que faz uma certa falta, a despeito da minha fama de anti-social. A solução provavelmente é (shudder) sair de casa e falar com pessoas.

Eu também cheguei à conclusão (igualmente brilhante) de que muita coisa nessa vida é questão de criar hábitos. Por exemplo, até algumas semanas atrás eu costumava usar toda a louça da casa até não ter mais louça limpa, momento em que eu aplicava o garbage collector e lavava tudo (ou, dependendo da preguiça, só o que eu precisasse na hora). Eu me dei conta de que isso não estava sendo muito conveniente e resolvi começar a lavar as coisas logo depois que uso, ou antes de ir dormir. No começo era meio ruim ter que me "obrigar" a fazer isso, mas agora eu já me habituei e isso não me incomoda mais tanto (além do que, como a louça não acumula, normalmente o esforço de lavar é pequeno). Talvez seja uma questão de criar o hábito de sentar uma hora do dia para programar/estudar/whatever. O flip side disso é que a gente também se habitua ao longo da vida a uma porção de coisas que a gente deveria questionar e/ou atirar pela janela, não só hábitos acionais como também (e principalmente) hábitos mentais. Estas são minhas (brilhantes e inauditas) palavras de sabedoria do dia. (Tecnicamente todo hábito é mental, mas deu pra entender. Acho.)

Escrever o lash em Chicken Scheme tem sido uma experiência bastante agradável. Eu estou aprendendo (a parte não-R5RS d)a linguagem "as I go", mas até agora a linguagem não me deixou na mão, a implementação é estável e gera executáveis pequenos e razoavelmente rápidos, e o sistema de pacotes funciona. (Rodar chicken-install pacote e consistentemente ver o pacote ser baixado e compilado sem erros era quase chocante no começo. O fato de que as bibliotecas são shared objects (a.k.a. DLLs) de verdade e carregam instantaneamente também muito alegrou o espírito, especialmente dada minha experiência anterior com bibliotecas em Common Lisp.) A única coisa que deixa um pouco a desejar é o error reporting, mas nada "deal-breaking".

Eu me dei conta de que uma das coisas que eu mais gosto em linguagens "dinâmicas" é a habilidade de rodar um programa incompleto. Eu já meio que escrevi sobre isso antes, mas eu já não lembrava mais quão deeply satisfying é poder rodar um programa pela metade e ver a parte que foi escrita até o momento funcionando. Por outro lado, é bastante incômodo errar um nome de função ou os argumentos e só descobrir o erro em tempo de execução. Faz muito tempo que eu acho que o ideal seria uma linguagem com análise estática de tipos, mas em que erros de tipo gerassem warnings ao invés de impedir a compilação, e que permitisse a declaração opcional dos tipos de variáveis e funções. Uma dificuldade que eu via nisso até agora é que enquanto em uma linguagem dinâmica os dados costumam ter uma representação uniforme em memória que carrega consigo alguma tag indicando o tipo do dado, e portanto é possível chamar uma função com argumentos do tipo errado e detectar isso em tempo de execução, em uma linguagem estaticamente tipada convencional os dados costumam ter uma representação untagged/unboxed e de tamanho variável, o que tornaria impossível compilar um programa com um erro de tipo sem violar a segurança da linguagem (e.g., se uma função f recebe um vetor e eu a chamo com um int, ou eu rejeito o programa em tempo de compilação, o que atrapalha minha habilidade de rodar programas incompletos/incorretos, ou eu gero um programa que interpreta o meu int como um vetor sem que isso seja detectado em tempo de execução, o que provavelmente vai causar um segfault ou algo pior). Porém, esses dias eu me dei conta de que ao invés de compilar uma chamada (insegura) a f(some_int), poder-se-ia simplesmente (além de gerar o warning) compilar uma chamada a error(f, some_int), onde error é uma função que avalia os argumentos e lança uma exceção descrevendo o erro de tipo. O resultado prático é que o executável gerado roda até o ponto em que é seguro rodar (inclusive avaliando a função e os argumentos) e interrompe a execução no ponto em que seria necessário chamar a função com um argumento de tipo/representação incompatível. Melhor dos dois mundos, não? Vai para o meu caderninho de idéias para a Linguagem Perfeita™.

Eu ia escrever mais umas notas sobre a vida, mas ultimamente eu ando mui receoso quanto a publicar coisas da minha vida pessoal – o que provavelmente é uma boa idéia. É fácil esquecer que qualquer um, no presente ou no futuro, pode ler o que a gente escreve nessa tal de Internet. Eu também já falei sobre isso mil vezes antes, which makes it all the more surprising que eu ainda tenha que me relembrar disso ocasionalmente. Anyway.

Unrelated com qualquer coisa, conheci recentemente uma bandinha chamada Clannad, na qual eu me encontro totalmente viciado no momento. Também conheci uma coisa totalmente excelente chamada Galandum Galundaina, uma banda mirandesa com certeza.

12 comentários / comments

Main menu

Recent posts

Recent comments

Tags

em-portugues (213) comp (148) prog (71) in-english (62) life (49) unix (38) pldesign (37) lang (32) random (28) about (28) mind (26) lisp (25) fenius (22) mundane (22) web (20) ramble (18) img (13) rant (12) hel (12) scheme (10) privacy (10) freedom (8) esperanto (7) music (7) lash (7) bash (7) academia (7) copyright (7) home (6) mestrado (6) shell (6) android (5) conlang (5) misc (5) emacs (5) latex (4) editor (4) etymology (4) php (4) worldly (4) book (4) politics (4) network (3) c (3) tour-de-scheme (3) security (3) kbd (3) film (3) wrong (3) cook (2) treta (2) poem (2) physics (2) x11 (2) audio (2) comic (2) lows (2) llvm (2) wm (2) philosophy (2) perl (1) wayland (1) ai (1) german (1) en-esperanto (1) golang (1) translation (1) kindle (1) pointless (1) old-chinese (1)

Elsewhere

Quod vide


Copyright © 2010-2024 Vítor De Araújo
O conteúdo deste blog, a menos que de outra forma especificado, pode ser utilizado segundo os termos da licença Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International.

Powered by Blognir.