<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7213650200249361122</id><updated>2011-11-27T16:08:39.239-08:00</updated><category term='musica'/><category term='markerpen'/><category term='scheme'/><category term='amplificador'/><category term='spiffy'/><category term='FURG'/><category term='pastiche'/><category term='sacanagem'/><category term='postgresql'/><category term='emacs'/><category term='javascript'/><category term='americanas'/><category term='web'/><category term='apple'/><category term='sqlite'/><category term='macros'/><category term='sawfish'/><category term='repl'/><category term='lisp'/><category term='benchmark'/><category term='música'/><category term='wful'/><category term='chicken-doc'/><category term='ldap'/><category term='awful'/><category term='python'/><category term='org'/><category term='Engenharia de Computação'/><category term='latinoware'/><category term='gcc'/><category term='cow'/><category term='elisp'/><category term='ubuntu'/><category term='chicken'/><category term='woof'/><category term='gazette'/><category term='web-scheme'/><category term='gnus'/><category term='chicken.scheme'/><category term='doctests'/><category term='humor'/><title type='text'>call/hc</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>87</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-5040496016016246245</id><published>2011-09-12T15:02:00.000-07:00</published><updated>2011-09-12T15:09:46.727-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><title type='text'>I don't always use Lisp...</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-akkb-oPR5UM/Tm6Cew0vsbI/AAAAAAAAAGE/M1LgVGXvg2w/s1600/id.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 400px;" src="http://3.bp.blogspot.com/-akkb-oPR5UM/Tm6Cew0vsbI/AAAAAAAAAGE/M1LgVGXvg2w/s400/id.jpg" alt="" id="BLOGGER_PHOTO_ID_5651598047410368946" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;By Jim.&lt;br /&gt;&lt;br /&gt;(Image generated by quickmeme.com)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-5040496016016246245?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/5040496016016246245/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=5040496016016246245' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5040496016016246245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5040496016016246245'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2011/09/i-dont-always-use-lisp.html' title='I don&apos;t always use Lisp...'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-akkb-oPR5UM/Tm6Cew0vsbI/AAAAAAAAAGE/M1LgVGXvg2w/s72-c/id.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-9121872835613420030</id><published>2011-06-07T17:59:00.000-07:00</published><updated>2011-06-07T18:10:32.500-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='awful'/><category scheme='http://www.blogger.com/atom/ns#' term='pastiche'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>paste.call-cc.org (pastiche)</title><content type='html'>Hoje foi &lt;a href="http://lists.nongnu.org/archive/html/chicken-users/2011-06/msg00026.html"&gt;anunciado&lt;/a&gt; o serviço de &lt;span style="font-style:italic;"&gt;pasting&lt;/span&gt; em &lt;a href="http://call-cc.org"&gt;call-cc.org&lt;/a&gt; (o servidor do projeto &lt;a href="http://call-cc.org"&gt;Chicken&lt;/a&gt;), disponibilizado através de &lt;a href="http://paste.call-cc.org"&gt;http://paste.call-cc.org&lt;/a&gt;.  Em linhas gerais, o serviço permite colar trechos de código para que outras pessoas possam ver.  É bem útil em discussões via IRC.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://paste.call-cc.org"&gt;paste.call-cc.org&lt;/a&gt; executa &lt;a href="https://github.com/ckeen/pastiche"&gt;pastiche&lt;/a&gt;, uma aplicação para a web desenvolvida por &lt;a href="http://wiki.call-cc.org/users/christian-kellermann"&gt;Christian Kellermann&lt;/a&gt;. É feita em &lt;a href="http://call-cc.org"&gt;Chicken Scheme&lt;/a&gt;, usando &lt;a href="http://wiki.call-cc.org/egg/awful"&gt;awful&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-9121872835613420030?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/9121872835613420030/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=9121872835613420030' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/9121872835613420030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/9121872835613420030'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2011/06/pastecall-ccorg-pastiche.html' title='paste.call-cc.org (pastiche)'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-7184074245862033234</id><published>2011-05-26T03:49:00.000-07:00</published><updated>2011-05-26T04:01:53.362-07:00</updated><title type='text'>Chicken 4.7.0</title><content type='html'>Ontem foi lançada a versão 4.7.0 do sistema Chicken, com várias correções de problemas e melhorias.  A lista de novidades está no arquivo &lt;a href="http://code.call-cc.org/releases/4.7.0/NEWS"&gt;NEWS&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Uma das mais significativas modificações foi a substituição do sistema de expressões regulares.  A unidade antiga (regex), agora é um &lt;a href="http://wiki.call-cc.org/eggref/4/regex"&gt;egg&lt;/a&gt;. A implementação nova é &lt;a href="http://synthcode.com/scheme/irregex/"&gt;irregex&lt;/a&gt;, em Scheme puro.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-7184074245862033234?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/7184074245862033234/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=7184074245862033234' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7184074245862033234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7184074245862033234'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2011/05/chicken-470.html' title='Chicken 4.7.0'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-7339160101377443364</id><published>2011-04-28T16:33:00.000-07:00</published><updated>2011-04-28T16:48:03.372-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='amplificador'/><category scheme='http://www.blogger.com/atom/ns#' term='música'/><title type='text'>"Novo" equipamento</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-Sia-udvPIzE/Tbn73oMdO5I/AAAAAAAAAFw/dEKeXVU-h7M/s1600/s2.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/-Sia-udvPIzE/Tbn73oMdO5I/AAAAAAAAAFw/dEKeXVU-h7M/s320/s2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5600784544712965010" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-e8jSsXz98EA/Tbn739zA9cI/AAAAAAAAAF4/GkZ-ow4B-ak/s1600/s1.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/-e8jSsXz98EA/Tbn739zA9cI/AAAAAAAAAF4/GkZ-ow4B-ak/s320/s1.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5600784550511834562" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Amplificador de microfones Stevaux (50W, com 6L6 na saída).&lt;br /&gt;&lt;br /&gt;Alguém sabe mais sobre esta marca?  Até onde sei, foi (é?) um fabricante de transformadores e caixas metálicas.&lt;br /&gt;&lt;br /&gt;Todo o circuito é valvulado, inclusive a fonte.&lt;br /&gt;&lt;br /&gt;Fotos em resolução maior podem ser vistas em &lt;a href="http://parenteses.org/mario/fotos/stevaux"&gt;http://parenteses.org/mario/fotos/stevaux&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-7339160101377443364?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/7339160101377443364/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=7339160101377443364' title='3 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7339160101377443364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7339160101377443364'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2011/04/novo-equipamento.html' title='&quot;Novo&quot; equipamento'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-Sia-udvPIzE/Tbn73oMdO5I/AAAAAAAAAFw/dEKeXVU-h7M/s72-c/s2.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-8179047621337413980</id><published>2011-04-21T06:17:00.000-07:00</published><updated>2011-04-21T06:19:32.296-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Chicken no Twitter</title><content type='html'>&lt;a href="http://call-cc.org"&gt;Chicken&lt;/a&gt; entrou no moderno mundo da web social com uma &lt;a href="http://www.twitter.com/chickenscheme"&gt;conta no twitter&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-8179047621337413980?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/8179047621337413980/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=8179047621337413980' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8179047621337413980'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8179047621337413980'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2011/04/chicken-no-twitter.html' title='Chicken no Twitter'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-6220287595671984542</id><published>2011-04-16T03:52:00.000-07:00</published><updated>2011-04-16T04:11:21.274-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Primeiro esboço de R7RS</title><content type='html'>Ontem foi &lt;a href="https://groups.google.com/forum/#!topic/comp.lang.scheme/MCfPoeir90s/discussion"&gt;anunciado&lt;/a&gt; o primeiro &lt;a href="http://trac.sacrideo.us/wg/raw-attachment/wiki/WikiStart/r7rs-draft-1.pdf"&gt;esboço&lt;/a&gt; [PDF] da nova versão da especificação de Scheme.&lt;br /&gt;&lt;br /&gt;O comitê responsável por preparar a nova versão da especificação decidiu dividi-la em duas partes: uma &lt;a href="http://scheme-reports.org/2009/working-group-1-charter.html"&gt;básica&lt;/a&gt; e &lt;a href="http://scheme-reports.org/2009/working-group-2-charter.html"&gt;outra&lt;/a&gt; com funcionalidades opcionais que podem não ser necessárias ou adequadas em alguns contextos. O documento anunciado é referente à parte básica (&lt;span style="font-style:italic;"&gt;small language&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Felizmente, &lt;a href="http://scheme-reports.org/"&gt;R7RS&lt;/a&gt; baseia-se em &lt;a href="http://www.schemers.org/Documents/Standards/R5RS/HTML/"&gt;R5RS&lt;/a&gt;, e não em &lt;a href="http://www.r6rs.org/final/html/r6rs/r6rs.html"&gt;R6RS&lt;/a&gt;.  O texto preliminar da nova especificação é de leitura agradável, não sendo tão "denso" quanto o das versões anteriores.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-6220287595671984542?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/6220287595671984542/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=6220287595671984542' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6220287595671984542'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6220287595671984542'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2011/04/primeiro-esboco-de-r7rs.html' title='Primeiro esboço de R7RS'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-2180031044656904040</id><published>2011-04-12T04:22:00.000-07:00</published><updated>2011-04-12T04:34:02.551-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='awful'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Novas versões para awful e extensões de suporte a bancos de dados</title><content type='html'>Há pouco foram lançadas versões novas das extensões &lt;a href="http://wiki.call-cc.org/egg/awful"&gt;awful&lt;/a&gt;, &lt;a href="http://wiki.call-cc.org/egg/awful-sql-de-lite"&gt;awful-sql-de-lite&lt;/a&gt;, &lt;a href="http://wiki.call-cc.org/egg/awful-sqlite3"&gt;awful-sqlite3&lt;/a&gt; e &lt;a href="http://wiki.call-cc.org/egg/awful-postgresql"&gt;awful-postgresql&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Os destaques da nova versão de awful são as melhorias significativas para possibilitar a instalação de múltiplos aplicativos em um mesmo &lt;span style="font-style:italic;"&gt;virtual host&lt;/span&gt;, uma interface sobre &lt;a href="http://wiki.call-cc.org/egg/spiffy-request-vars"&gt;spiffy-request-vars&lt;/a&gt; e a correção de um bug crítico devido ao reuso de threads feito pelo servidor web &lt;a href="http://wiki.call-cc.org/egg/spiffy"&gt;Spiffy&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;As &lt;a href="http://wiki.call-cc.org/egg/awful#version-031"&gt;notas sobre a nova versão de awful (0.31)&lt;/a&gt; estão abaixo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;* Added a tiny wrapper around spiffy-request-vars, adding the&lt;br /&gt;   with-request-variables macro and exporting&lt;br /&gt;   spiffy-request-vars's converters.&lt;br /&gt;* Updated JQuery from version 1.5.1 to 1.5.2.&lt;br /&gt;* Better support for multiple applications under the same virtual&lt;br /&gt;  host (add-request-handler-hook! and remove-request-handler-hook!)&lt;br /&gt;* $db checks if database access is enabled via (enable-db) and&lt;br /&gt;  throws an error if it is not.&lt;br /&gt;* Fixed critical bug regarding to parameters and thread reuse by Spiffy&lt;br /&gt;* Fixed redirect-to but introduced in version 0.29&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As novas versões das extensões de suporte a sistemas de bancos de dados exportam um novo procedimento para permitir o chaveamento entre bases de diferentes bancos.  Assim, o uso de múltiplos sistemas de bancos de dados (e múltiplas bases de dados) em awful fica facilitado.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-2180031044656904040?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/2180031044656904040/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=2180031044656904040' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2180031044656904040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2180031044656904040'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2011/04/novas-versoes-para-awful-e-extensoes-de.html' title='Novas versões para awful e extensões de suporte a bancos de dados'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-8038374900838943008</id><published>2011-04-08T04:26:00.000-07:00</published><updated>2011-04-08T04:36:07.787-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Alinhamento de astros</title><content type='html'>Uma coincidência: atualmente as duas mais expressivas implementações de compilador de Scheme-&gt;C (&lt;a href="http://call-cc.org"&gt;Chicken&lt;/a&gt; e &lt;a href="http://www.iro.umontreal.ca/~gambit/"&gt;Gambit&lt;/a&gt;) e um dos mais importantes compiladores de C (&lt;a href="http://gcc.gnu.org/"&gt;GCC&lt;/a&gt;) estão na mesma versão: 4.6.&lt;br /&gt;&lt;br /&gt;A expectativa é que Chicken quebre esse alinhamento nos próximos dias com o lançamento da versão 4.7.&lt;br /&gt;&lt;br /&gt;Hoje a versão &lt;span style="font-style:italic;"&gt;release candidate&lt;/span&gt; para 4.7.0 foi atualizada no &lt;a href="http://code.call-cc.org/cgi-bin/gitweb.cgi?p=chicken-core.git;a=shortlog;h=refs/heads/prerelease"&gt;branch prerelease&lt;/a&gt; do repositório git do compilador.&lt;br /&gt;&lt;br /&gt;Também hoje foi lançado o &lt;a href="http://code.call-cc.org/dev-snapshots/2011/04/08/chicken-4.6.7.tar.gz"&gt;tarball de desenvolvimento, versão 4.6.7&lt;/a&gt;, com as funcionalidades que farão parte da versão 4.7.0.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-8038374900838943008?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/8038374900838943008/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=8038374900838943008' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8038374900838943008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8038374900838943008'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2011/04/alinhamento-de-astros.html' title='Alinhamento de astros'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-2447814038618732134</id><published>2011-02-27T10:58:00.000-08:00</published><updated>2011-02-27T11:06:12.684-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='awful'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Awful 0.29</title><content type='html'>Há pouco foi lançada a versão 0.29 de &lt;a href="http://wiki.call-cc.org/egg/awful"&gt;awful&lt;/a&gt;. Nada de muito revolucionário nesta nova versão, mas correção de pelo menos um bug crítico e novas funcionalidades/atualizações menores.  O &lt;i&gt;changelog&lt;/i&gt; para a versão 0.29 está abaixo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;* Updated JQuery from version 1.5.0 to 1.5.1.&lt;br /&gt;* ajax and periodical-ajax bugfix (for situations when they&lt;br /&gt;  are used simultaneously, or periodical-ajax and add-javascript).&lt;br /&gt;* The default URI for ajax-library is now protocol-relative&lt;br /&gt;  (thanks to Peter Bex).&lt;br /&gt;* Added the javascript-position parameter.&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-2447814038618732134?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/2447814038618732134/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=2447814038618732134' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2447814038618732134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2447814038618732134'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2011/02/awful-029.html' title='Awful 0.29'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-1019181714569932547</id><published>2011-02-26T18:41:00.000-08:00</published><updated>2011-02-26T19:15:36.604-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>REPL ilustrado</title><content type='html'>O &lt;a href="http://en.wikipedia.org/wiki/REPL"&gt;REPL&lt;/a&gt; (&lt;b&gt;R&lt;/b&gt;ead, &lt;b&gt;E&lt;/b&gt;val, &lt;b&gt;P&lt;/b&gt;rint, &lt;b&gt;L&lt;/b&gt;oop), vulgar e erroneamente conhecido como &lt;i&gt;interpretador&lt;/i&gt; (existem compiladores com ambiente interativo), é uma das ferramentas mais indispensáveis para programadores. É o tipo de coisa que, depois que nos acostumamos a usar, é difícil viver sem.&lt;br /&gt;&lt;br /&gt;Abaixo está uma implementação simplificada e graficamente comentada em Chicken Scheme que ilustra o conceito:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-nVmSQcXjvd8/TWm7l93auhI/AAAAAAAAAFg/0FBRLiS4FLU/s1600/repl-e.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 267px;" src="http://1.bp.blogspot.com/-nVmSQcXjvd8/TWm7l93auhI/AAAAAAAAAFg/0FBRLiS4FLU/s400/repl-e.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5578195874411624978" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-vASbsqvGPc8/TWnBpGnNv1I/AAAAAAAAAFo/uBMVh0u2dB8/s1600/repl2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 339px; height: 76px;" src="http://1.bp.blogspot.com/-vASbsqvGPc8/TWnBpGnNv1I/AAAAAAAAAFo/uBMVh0u2dB8/s400/repl2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5578202525368958802" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;O código acima é executável:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ csi -s repl.scm&lt;br /&gt;(define (fatorial n) (if (&lt; n 2) 1 (* n (fatorial (- n 1)))))&lt;br /&gt;#&amp;lt;unspecified&amp;gt;&lt;br /&gt;(fatorial 6)&lt;br /&gt;720&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-1019181714569932547?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/1019181714569932547/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=1019181714569932547' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1019181714569932547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1019181714569932547'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2011/02/repl-ilustrado.html' title='REPL ilustrado'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-nVmSQcXjvd8/TWm7l93auhI/AAAAAAAAAFg/0FBRLiS4FLU/s72-c/repl-e.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-4411465050491172754</id><published>2011-02-07T13:05:00.000-08:00</published><updated>2011-02-07T13:08:10.074-08:00</updated><title type='text'>Recarregando aplicações em awful através do Emacs</title><content type='html'>Abaixo está um &lt;i&gt;hackzinho&lt;/i&gt; para recarregar aplicações em &lt;a href='http://wiki.call-cc.org/egg/awful'&gt;awful&lt;/a&gt; através do &lt;a href='http://www.gnu.org/software/emacs'&gt;Emacs&lt;/a&gt;, o qual pode ser bem útil quando usando awful no modo desenvolvimento (&lt;code&gt;--development-mode&lt;/code&gt;).  No modo de desenvolvimento, awful automaticamente define o caminho &lt;code&gt;/reload&lt;/code&gt;, o qual, quando requisitado, recarrega as aplicações.&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;defun&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;awful-reload&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;  (interactive)&lt;br /&gt;  (shell-command &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;lynx -dump http://localhost:8080/reload&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;&lt;br /&gt;(add-hook 'scheme-mode-hook&lt;br /&gt;   #'(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;       (local-set-key &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;\C-cR&amp;quot;&lt;/FONT&gt;&lt;/B&gt; 'awful-reload)))&lt;/pre&gt; &lt;br /&gt;O código acima define uma função interativa (&lt;code&gt;awful-reload&lt;/code&gt;) que pode ser invocada no Emacs através de &lt;code&gt;C-cR&lt;/code&gt; estando-se no modo Scheme.&lt;br /&gt; &lt;br /&gt;O cliente HTTP pode ser qualquer um de linha de comando. O &lt;code&gt;lynx&lt;/code&gt; serve bem a este propósito por fornecer a opção &lt;code&gt;-dump&lt;/code&gt;, que gera a saída sem formatação, a qual pode ser exibida com facilidade no &lt;i&gt;buffer&lt;/i&gt; do Emacs.&lt;br /&gt; &lt;br /&gt;Abaixo está um &lt;i&gt;screenshot&lt;/i&gt; do Emacs logo após a execução de &lt;code&gt;awful-reload&lt;/code&gt; através de &lt;code&gt;C-cR&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ade5bioRWEE/TVBe1--37EI/AAAAAAAAAFY/TzJRAt9-S5E/s1600/awful-reload-emacs.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 239px;" src="http://1.bp.blogspot.com/_ade5bioRWEE/TVBe1--37EI/AAAAAAAAAFY/TzJRAt9-S5E/s400/awful-reload-emacs.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5571057020590091330" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-4411465050491172754?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/4411465050491172754/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=4411465050491172754' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4411465050491172754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4411465050491172754'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2011/02/recarregando-aplicacoes-em-awful.html' title='Recarregando aplicações em awful através do Emacs'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_ade5bioRWEE/TVBe1--37EI/AAAAAAAAAFY/TzJRAt9-S5E/s72-c/awful-reload-emacs.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-5925362243303556218</id><published>2011-02-06T15:10:00.000-08:00</published><updated>2011-02-06T15:16:41.304-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='awful'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Awful 0.28 e awful-ssl</title><content type='html'>Hoje foi lançada a versão 0.28 de &lt;a href="http://wiki.call-cc.org/egg/awful"&gt;awful&lt;/a&gt;. A &lt;a href="http://wiki.call-cc.org/egg/awful#version-history"&gt;nova versão&lt;/a&gt; apresenta correções de &lt;i&gt;bugs&lt;/i&gt;, soluções para algumas limitações e algumas novas funcionalidades.&lt;br /&gt;&lt;br /&gt;Também foi lançada a versão inicial da extensão &lt;a href="http://wiki.call-cc.org/egg/awful-ssl"&gt;awful-ssl&lt;/a&gt;, a qual permite o uso de awful com SSL de forma fácil.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-5925362243303556218?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/5925362243303556218/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=5925362243303556218' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5925362243303556218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5925362243303556218'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2011/02/awful-028-e-awful-ssl.html' title='Awful 0.28 e awful-ssl'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-7502185898458937946</id><published>2010-11-18T15:08:00.000-08:00</published><updated>2010-11-18T15:10:42.322-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>accents-substitute</title><content type='html'>Seguidamente tenho a necessidade de remover acentos de textos em português.  Há umas semanas fiz uma extensão para &lt;a href='http://www.call-cc.org'&gt;Chicken&lt;/a&gt; chamada &lt;a href='http://wiki.call-cc.org/egg/accents-substitute'&gt;accents-substitute&lt;/a&gt; substituir caracteres acentuados pelos correspondentes sem acento (ou com entidades de HTML).&lt;br /&gt; &lt;br /&gt;A extensão aceita textos em Latin1 (ISO-8859-1) ou UTF-8, havendo um módulo para cada codificação, ambos provendo o mesmo procedimento: &lt;code&gt;accents-substitute&lt;/code&gt; (nome inspirado em &lt;a href='http://wiki.call-cc.org/eggref/4/regex#string-substitute'&gt;string-substitute&lt;/a&gt;, da extensão &lt;a href='http://wiki.call-cc.org/eggref/4/regex'&gt;regex&lt;/a&gt;).&lt;br /&gt; &lt;br /&gt;Para facilitar o uso no dia-a-dia, fiz um pequeno script que usa o procedimento {{accents-substitute}}.  Abaixo estão alguns exemplos de uso:&lt;br /&gt; &lt;pre&gt;$ accents-substitute --help&lt;br /&gt;Usage: accents-substitute [ --encoding=&lt;utf8|latin1&gt; ] [ --mode=&lt;ascii|html&gt; ] [ input file ]&lt;br /&gt;&lt;br /&gt;Default values:&lt;br /&gt;   mode: ascii&lt;br /&gt;   encoding: utf8&lt;/pre&gt; &lt;pre&gt;$ cat lisp-br&lt;br /&gt;Lisp-BR é um projeto que tem por objetivo divulgar linguagens de&lt;br /&gt;programação da família Lisp no Brasil e formar uma comunidade de&lt;br /&gt;usuários que tenham vontade de aprender não só uma nova forma de&lt;br /&gt;programar, mas também uma nova maneira de pensar!&lt;/pre&gt; &lt;pre&gt;$ cat lisp-br | accents-substitute &lt;br /&gt;Lisp-BR e um projeto que tem por objetivo divulgar linguagens de&lt;br /&gt;programacao da familia Lisp no Brasil e formar uma comunidade de&lt;br /&gt;usuarios que tenham vontade de aprender nao so uma nova forma de&lt;br /&gt;programar, mas tambem uma nova maneira de pensar!&lt;/pre&gt; &lt;pre&gt;$ accents-substitute --mode=html lisp-br&lt;br /&gt;Lisp-BR &amp;amp;eacute; um projeto que tem por objetivo divulgar linguagens de&lt;br /&gt;programa&amp;amp;ccedil;&amp;amp;atilde;o da fam&amp;amp;iacute;lia Lisp no Brasil e formar uma comunidade de&lt;br /&gt;usu&amp;amp;aacute;rios que tenham vontade de aprender n&amp;amp;atilde;o s&amp;amp;oacute; uma nova forma de&lt;br /&gt;programar, mas tamb&amp;amp;eacute;m uma nova maneira de pensar!&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;O código da ferramenta de linha de comando está a seguir:&lt;br /&gt; &lt;pre&gt;#!/bin/sh&lt;br /&gt;#| -*- scheme -*-&lt;br /&gt;exec csi -s $0 &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;$@&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;|#&lt;br /&gt;&lt;br /&gt;(use&lt;br /&gt; (rename&lt;br /&gt;  accents-substitute-latin1&lt;br /&gt;  (accents-substitute accents-substitute-latin1))&lt;br /&gt; (rename&lt;br /&gt;  accents-substitute-utf8&lt;br /&gt;  (accents-substitute accents-substitute-utf8)))&lt;br /&gt;&lt;br /&gt;(use posix regex (srfi 1 13))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;command-line-argument&lt;/FONT&gt;&lt;/B&gt; option args)&lt;br /&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; Return the argument associated to the command line option OPTION&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; in ARGS or #f if OPTION is not found in ARGS or doesn't have any&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; argument.&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((val (any (cut string-match (string-append option &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;=(.*)&amp;quot;&lt;/FONT&gt;&lt;/B&gt;) &amp;lt;&amp;gt;) args)))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; val (cadr val))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;usage&lt;/FONT&gt;&lt;/B&gt; #!optional exit-code)&lt;br /&gt;  (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Usage: &amp;quot;&lt;/FONT&gt;&lt;/B&gt; (pathname-strip-directory (program-name))&lt;br /&gt;         &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; [ --encoding=&amp;lt;utf8|latin1&amp;gt; ] [ --mode=&amp;lt;ascii|html&amp;gt; ] [ input file ]&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;\nDefault values:\n&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;         &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;    mode: ascii\n&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;         &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;    encoding: utf8&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (when exit-code (exit exit-code)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((args (command-line-arguments))&lt;br /&gt;       (mode (command-line-argument &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;--mode&amp;quot;&lt;/FONT&gt;&lt;/B&gt; args))&lt;br /&gt;       (encoding (command-line-argument &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;--encoding&amp;quot;&lt;/FONT&gt;&lt;/B&gt; args))&lt;br /&gt;       (paramless-args (remove (cut string-prefix? &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;--&amp;quot;&lt;/FONT&gt;&lt;/B&gt; &amp;lt;&amp;gt;) args))&lt;br /&gt;       (accents-substitute accents-substitute-utf8))&lt;br /&gt;&lt;br /&gt;  (when (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; (member &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;-h&amp;quot;&lt;/FONT&gt;&lt;/B&gt; args) (member &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;--help&amp;quot;&lt;/FONT&gt;&lt;/B&gt; args))&lt;br /&gt;    (usage 0))&lt;br /&gt;&lt;br /&gt;  (when (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; encoding (not (member encoding '(&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;utf8&amp;quot;&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;latin1&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;br /&gt;    (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;'&amp;quot;&lt;/FONT&gt;&lt;/B&gt; encoding &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;' is not a valid encoding.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;    (exit 1))&lt;br /&gt;&lt;br /&gt;  (when (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; mode (not (member mode '(&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;ascii&amp;quot;&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;html&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;br /&gt;    (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;'&amp;quot;&lt;/FONT&gt;&lt;/B&gt; mode &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;' is not a valid mode.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;    (exit 1))&lt;br /&gt;&lt;br /&gt;  (when (equal? encoding &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;latin1&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; accents-substitute accents-substitute-latin1))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((port (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? paramless-args)&lt;br /&gt;                  (current-input-port)&lt;br /&gt;                  (open-input-file (car paramless-args)))))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; loop ()&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((line (read-line port)))&lt;br /&gt;        (unless (eof-object? line)&lt;br /&gt;          (print (accents-substitute line mode: (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; mode (string-&amp;gt;symbol mode))))&lt;br /&gt;          (loop))))&lt;br /&gt;    (unless (null? paramless-args)&lt;br /&gt;      (close-input-port port))))&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;Adicionei este exemplo de aplicação à seção &lt;i&gt;Examples&lt;/i&gt; da &lt;a href='http://wiki.call-cc.org/eggref/4/accents-substitute'&gt;documentação de &lt;code&gt;accents-substitute&lt;/code&gt;&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-7502185898458937946?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/7502185898458937946/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=7502185898458937946' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7502185898458937946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7502185898458937946'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/11/accents-substitute.html' title='accents-substitute'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-699135791815313495</id><published>2010-10-05T04:09:00.000-07:00</published><updated>2010-10-05T04:23:36.582-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='awful'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Awful no Windows ("That's too awful")</title><content type='html'>Com a &lt;a href="http://bugs.call-cc.org/ticket/380"&gt;correção&lt;/a&gt; da extensão &lt;a href="http://wiki.call-cc.org/egg/sendfile"&gt;sendfile&lt;/a&gt; (por &lt;a href="http://wiki.call-cc.org/users/david-krentzlin"&gt;David Krentzlin&lt;/a&gt;) para Windows, &lt;a href="http://wiki.call-cc.org/egg/awful"&gt;awful&lt;/a&gt; passa a funcionar também no sistema das telas azuis.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ade5bioRWEE/TKsJZp1GGkI/AAAAAAAAAFI/BwCUzy6Hljs/s1600/awful-win-crop.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 274px;" src="http://2.bp.blogspot.com/_ade5bioRWEE/TKsJZp1GGkI/AAAAAAAAAFI/BwCUzy6Hljs/s400/awful-win-crop.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5524519704229976642" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As correções ainda não foram oficialmente lançadas (i.e., ainda não estão disponíveis para serem instaladas via &lt;code&gt;chicken-install&lt;/code&gt;), mas podem ser obtidas em &lt;a href="http://code.call-cc.org/svn/chicken-eggs/release/4/sendfile/trunk/"&gt;http://code.call-cc.org/svn/chicken-eggs/release/4/sendfile/trunk/&lt;/a&gt; (usuário: &lt;code&gt;anonymous&lt;/code&gt;, sem senha).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-699135791815313495?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/699135791815313495/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=699135791815313495' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/699135791815313495'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/699135791815313495'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/10/awful-no-windows-thats-too-awful.html' title='Awful no Windows (&quot;That&apos;s too awful&quot;)'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ade5bioRWEE/TKsJZp1GGkI/AAAAAAAAAFI/BwCUzy6Hljs/s72-c/awful-win-crop.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-5650969869172291646</id><published>2010-09-13T04:27:00.000-07:00</published><updated>2010-09-13T04:30:04.962-07:00</updated><title type='text'>Chicken 4.6.0</title><content type='html'>Foi lançada hoje a versão 4.6.0 de &lt;a href="http://www.call-cc.org"&gt;Chicken&lt;/a&gt;. O download da nova versão pode ser feito de &lt;a href="http://code.call-cc.org"&gt;http://code.call-cc.org&lt;/a&gt;.  As novidades estão listadas no arquivo &lt;a href="http://code.call-cc.org/releases/4.6.0/NEWS"&gt;NEWS&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-5650969869172291646?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/5650969869172291646/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=5650969869172291646' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5650969869172291646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5650969869172291646'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/09/chicken-460.html' title='Chicken 4.6.0'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-5796655479605902256</id><published>2010-09-11T12:42:00.000-07:00</published><updated>2010-09-11T12:56:17.459-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='wful'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Migração de site estático para awful: tratando requisições por index.html</title><content type='html'>Até pouco tempo atrás a minha página pessoal era totalmente estática.  Depois que comecei a desenvolver &lt;a href='http://wiki.call-cc.org/egg/awful'&gt;awful&lt;/a&gt; achei que seria meio vergonhoso se a minha própria página não usasse o software que produzo.  Então resolvi refazê-la usando &lt;a href='http://wiki.call-cc.org/egg/awful'&gt;awful&lt;/a&gt; (eu poderia simplesmente jogar os arquivos estáticos para o servidor web disponibilizá-los, mas não teria graça).&lt;br /&gt; &lt;br /&gt;Um problema que ocorreu na migração do site estático para o com use de &lt;a href='http://wiki.call-cc.org/egg/awful'&gt;awful&lt;/a&gt; foi a ausência de arquivos &lt;code&gt;index.html&lt;/code&gt;. Várias páginas eram disponibilizadas e referenciadas através um arquivo &lt;code&gt;index.html&lt;/code&gt;, e esses arquivos não existem mais na nova estrutura com &lt;a href='http://wiki.call-cc.org/egg/awful'&gt;awful&lt;/a&gt;.  A solução que adotei foi redirecionar os acessos aos arquivos &lt;code&gt;index.html&lt;/code&gt; para o nome do "diretório" que os contém (na verdade não são diretórios, mas URIs associadas a procedimentos em Scheme).&lt;br /&gt; &lt;br /&gt;Por exemplo, antes havia &lt;code&gt;http://parenteses.org/mario/index.html&lt;/code&gt;.  Hoje há um procedimento associado a &lt;code&gt;http://parenteses.org/mario&lt;/code&gt;.&lt;br /&gt; &lt;br /&gt;Com a possibilidade de associar procedimentos a URIs que casa com uma expressão regular, fazer com que &lt;code&gt;http://parenteses.org/mario&lt;/code&gt; responda por &lt;code&gt;http://parenteses.org/mario/index.html&lt;/code&gt; se torna bem fácil:&lt;br /&gt; &lt;pre&gt;(use awful)&lt;br /&gt;&lt;br /&gt;(define-page (regexp &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;/mario/.*index.html&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (path)&lt;br /&gt;    (redirect-to (string-chomp path &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;index.html&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;/pre&gt;&lt;br /&gt;Assim, todas as requisições por recursos &lt;code&gt;/index.html&lt;/code&gt; disponíveis no caminho &lt;code&gt;/mario/&lt;/code&gt; serão redirecionadas para &lt;code&gt;/&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-5796655479605902256?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/5796655479605902256/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=5796655479605902256' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5796655479605902256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5796655479605902256'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/09/migracao-de-site-estatico-para-awful.html' title='Migração de site estático para awful: tratando requisições por index.html'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-4600397284255009930</id><published>2010-09-09T16:52:00.000-07:00</published><updated>2010-09-09T17:23:37.550-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='música'/><title type='text'>Substituindo ferrugem por bolhas</title><content type='html'>Neste domingo recebi um inesperado telefonema do Douglas, guitarrista da &lt;a href="http://parenteses.org/mario/musica/"&gt;Crossfire&lt;/a&gt;, convidando para reunirmos a banda e fazer um som. Não tocávamos juntos desde o final de 2008 e eu havia parado de tocar no ano passado.&lt;br /&gt;&lt;br /&gt;Depois de um ano sem tocar &lt;a href="http://parenteses.org/mario/fotos/baixo/"&gt;baixo&lt;/a&gt;, decidi arriscar para ver no que daria.  Surpreendentemente, tocamos durante duas horas como se estivéssemos tocando regularmente.  Fiquei impressionado.&lt;br /&gt;&lt;br /&gt;Impressionante também foram as seqüelas.  Esta é a foto dos meus dedos logo após o término do ensaio:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ade5bioRWEE/TIl1cyzJPQI/AAAAAAAAAEo/GQJhBAWgXPU/s1600/d.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 250px; height: 187px;" src="http://4.bp.blogspot.com/_ade5bioRWEE/TIl1cyzJPQI/AAAAAAAAAEo/GQJhBAWgXPU/s400/d.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5515068356224957698" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Esse é o estado dos meus dedos hoje:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ade5bioRWEE/TIl3Kpz8dJI/AAAAAAAAAE4/8hEMabgvWT8/s1600/d2.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 250px; height: 187px;" src="http://2.bp.blogspot.com/_ade5bioRWEE/TIl3Kpz8dJI/AAAAAAAAAE4/8hEMabgvWT8/s400/d2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5515070243598005394" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Fica a dica: se fores tocar depois de um ano parado(a), use palheta. :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-4600397284255009930?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/4600397284255009930/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=4600397284255009930' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4600397284255009930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4600397284255009930'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/09/substituindo-ferrugem-por-bolhas.html' title='Substituindo ferrugem por bolhas'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_ade5bioRWEE/TIl1cyzJPQI/AAAAAAAAAEo/GQJhBAWgXPU/s72-c/d.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-360758798395007958</id><published>2010-09-09T16:37:00.000-07:00</published><updated>2010-09-09T16:39:32.848-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='gazette'/><title type='text'>Chicken Gazette</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://gazette.call-cc.org/logo.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 445px; height: 208px;" src="http://gazette.call-cc.org/logo.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;Há algumas semanas foi lançada a &lt;a href='http://gazette.call-cc.org'&gt;Chicken Gazette&lt;/a&gt;, uma publicação semanal de notícias sobre o sistema &lt;a href='http://www.call-cc.org'&gt;Chicken&lt;/a&gt;. Até agora já foram publicadas duas edições, as quais tratam de vários assuntos relacionados a &lt;a href='http://www.call-cc.org'&gt;Chicken&lt;/a&gt;, desde aspectos técnicos a questões sociais, de infraestrutura, últimos acontecimentos no desenvolvimento e curiosidades em geral.&lt;br /&gt; &lt;br /&gt;A elaboração das edições é rotativa, ou seja, a cada semana há um editor diferente.  A &lt;a href='http://gazette.call-cc.org/issues/1.html'&gt;primeira edição&lt;/a&gt; ficou por conta de &lt;a href='http://wiki.call-cc.org/users/christian-kellermann'&gt;Christian Kellerman&lt;/a&gt;, a &lt;a href='http://gazette.call-cc.org/issues/2.html'&gt;segunda&lt;/a&gt; por &lt;a href='http://wiki.call-cc.org/users/moritz-heidkamp'&gt;Moritz Heidkamp&lt;/a&gt; e a terceira está sendo elaborada por &lt;a href='http://wiki.call-cc.org/users/alaric-blagrave-snellpym'&gt;Alaric Snell-Pym&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;As edições da &lt;a href='http://gazette.call-cc.org'&gt;Chicken Gazette&lt;/a&gt; podem ser acompanhadas através de &lt;a href='http://gazette.call-cc.org/feed.atom'&gt;&lt;i&gt;feeds&lt;/i&gt; atom&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-360758798395007958?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/360758798395007958/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=360758798395007958' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/360758798395007958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/360758798395007958'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/09/chicken-gazette.html' title='Chicken Gazette'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-5536453792213801360</id><published>2010-08-28T09:29:00.000-07:00</published><updated>2010-08-28T09:46:08.637-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='awful'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Awful 0.26</title><content type='html'>Há pouco lancei a versão 0.26 de &lt;a href="http://wiki.call-cc.org/egg/awful"&gt;awful&lt;/a&gt;.  A principal novidade é a integração de um &lt;a href="http://codemirror.net"&gt;editor em javascript&lt;/a&gt; para o web REPL (o &lt;a href="http://call-with-hopeless-continuation.blogspot.com/2010/08/awful-fancy-web-repl.html"&gt;texto anterior&lt;/a&gt; é sobre isso).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://parenteses.org/mario/img/awful/fancy-web-repl.png"&gt;&lt;img style="margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 515px; height: 552px;" src="http://parenteses.org/mario/img/awful/fancy-web-repl.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;Houve algumas modificações para tornar o web REPL mais útil para desenvolvimento interativo, como a possibilidade de redefinir e eliminar definições de páginas em tempo de execução.&lt;br /&gt;&lt;br /&gt;Coloquei em &lt;a href="http://wiki.call-cc.org/video/awful-guess.ogv"&gt;http://wiki.call-cc.org/video/awful-guess.ogv&lt;/a&gt; um vídeo mostrando o desenvolvimento de um simples jogo de adivinhação de números, com o uso de ajax e do web REPL.&lt;br /&gt;&lt;br /&gt;Em &lt;a href="http://parenteses.org/jogos"&gt;http://parenteses.org/jogos&lt;/a&gt; há versões mais elaboradas de jogos no mesmo estilo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-5536453792213801360?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/5536453792213801360/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=5536453792213801360' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5536453792213801360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5536453792213801360'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/08/awful-026.html' title='Awful 0.26'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-3291818080506198923</id><published>2010-08-20T17:58:00.001-07:00</published><updated>2010-08-20T18:23:30.123-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='awful'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Awful fancy web REPL</title><content type='html'>Estou pensando em adicionar um editor de código em Javascript ao web REPL de &lt;a href="http://wiki.call-cc.org/egg/awful"&gt;awful&lt;/a&gt;.  A idéia é facilitar a prototipação rápida, execução de testes, depuração e correção de problemas de forma fácil e com o servidor em execução.&lt;br /&gt;&lt;br /&gt;A versão de desenvolvimento de awful contém um código inicial para isso. Abaixo está um &lt;i&gt;screencast&lt;/i&gt; do que está implementado até agora.&lt;br /&gt;&lt;br /&gt;&lt;object width="320" height="266" class="BLOG_video_class" id="BLOG_video-41dcaf54f94df57f" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="movie" value="http://www.youtube.com/get_player"&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;param name="flashvars" value="flvurl=http://v2.nonxt4.googlevideo.com/videoplayback?id%3D41dcaf54f94df57f%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1330347884%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D4FD0625D0E36BF50D1B326CAD1823C3571BEB06E.5715ACEABA737209B21E8723B6AA298F72266169%26key%3Dck1&amp;amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3D41dcaf54f94df57f%26offsetms%3D5000%26itag%3Dw160%26sigh%3Dk4WDeZZd8FsKfRDhhalszb7_eHM&amp;amp;autoplay=0&amp;amp;ps=blogger"&gt;&lt;embed src="http://www.youtube.com/get_player" type="application/x-shockwave-flash"width="320" height="266" bgcolor="#FFFFFF"flashvars="flvurl=http://v2.nonxt4.googlevideo.com/videoplayback?id%3D41dcaf54f94df57f%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1330347884%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D4FD0625D0E36BF50D1B326CAD1823C3571BEB06E.5715ACEABA737209B21E8723B6AA298F72266169%26key%3Dck1&amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3D41dcaf54f94df57f%26offsetms%3D5000%26itag%3Dw160%26sigh%3Dk4WDeZZd8FsKfRDhhalszb7_eHM&amp;autoplay=0&amp;ps=blogger"allowFullScreen="true" /&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;O arquivo do vídeo, com uma qualidade significativamente melhor do que o mostrado acima, pode ser obtido em &lt;a href="http://parenteses.org/mario/misc/fancy-web-repl.ogv"&gt;http://parenteses.org/mario/misc/fancy-web-repl.ogv&lt;/a&gt; (~6.1MB).&lt;br /&gt;&lt;br /&gt;O editor em Javascript que estou utilizando é o &lt;a href="http://codemirror.net/"&gt;Codemirror&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-3291818080506198923?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/3291818080506198923/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=3291818080506198923' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/3291818080506198923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/3291818080506198923'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/08/awful-fancy-web-repl.html' title='Awful fancy web REPL'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-3254130171764915886</id><published>2010-08-20T17:32:00.000-07:00</published><updated>2010-08-23T03:35:32.514-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><title type='text'>Emacs rápido</title><content type='html'>Uma dica para usuários de &lt;a href="http://www.gnu.org/software/emacs/"&gt;Emacs&lt;/a&gt; que apelam para editores mais limitados como zile, nano e &lt;a href="http://www.dina.kvl.dk/~abraham/religion/vi-tutorial.html"&gt;vi&lt;/a&gt; (risada sarcástica aqui) para edição rápida de arquivos (e.g., arquivos de configuração):&lt;br /&gt;&lt;pre&gt;emacs -Q -nw&lt;/pre&gt;&lt;br /&gt;Um rápido e impreciso &lt;i&gt;benchmark&lt;/i&gt; na máquina que estou usando agora mostra os seguintes resultados para abrir e fechar o Emacs 10 vezes:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ time for i in `seq 10`; do \&lt;br /&gt;&gt;     emacs -Q -nw --eval '(save-buffers-kill-emacs)'; \&lt;br /&gt;&gt; done&lt;br /&gt;real    0m0.753s&lt;br /&gt;user    0m0.596s&lt;br /&gt;sys     0m0.140s&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Menos de 1 segundo para abrir e fechar o Emacs 10 vezes.&lt;br /&gt;&lt;br /&gt;Habilitar modos que tornam o uso do Emacs mais confortável, como &lt;code&gt;transient-mark-mode&lt;/code&gt;, &lt;code&gt;global-font-lock-mode&lt;/code&gt; e &lt;code&gt;show-paren-mode&lt;/code&gt; não custa caro:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ time for i in `seq 10`; do\&lt;br /&gt;&gt;      emacs -Q -nw --eval \&lt;br /&gt;&gt;        '(progn (global-font-lock-mode t)&lt;br /&gt;&gt;                (transient-mark-mode t)&lt;br /&gt;&gt;                (show-paren-mode t)&lt;br /&gt;&gt;                (save-buffers-kill-emacs))'; \&lt;br /&gt;&gt; done&lt;br /&gt;real    0m0.800s&lt;br /&gt;user    0m0.616s&lt;br /&gt;sys     0m0.168s&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Novamente, menos de um segundo para abrir e fechar o Emacs 10 vezes, com coloração de sintaxe e tudo (inclusive um interpretador de Lisp). :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-3254130171764915886?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/3254130171764915886/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=3254130171764915886' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/3254130171764915886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/3254130171764915886'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/08/emacs-rapido.html' title='Emacs rápido'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-4858864941455485179</id><published>2010-08-17T15:59:00.000-07:00</published><updated>2010-08-17T16:09:23.004-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='awful'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Awful 0.25</title><content type='html'>Há pouco foi lançada a versão 0.25 de &lt;a href='http://wiki.call-cc.org/egg/awful'&gt;awful&lt;/a&gt;.  A seguir são descritas as novidades.&lt;br /&gt; &lt;br /&gt;O servidor awful admite novos parâmetros de linha de comando: &lt;code&gt;--development-mode&lt;/code&gt;, &lt;code&gt;--ip-address&lt;/code&gt; e &lt;code&gt;--port&lt;/code&gt;. Os parâmetros &lt;code&gt;--development-mode&lt;/code&gt; e &lt;code&gt;--port&lt;/code&gt; servem, respectivamente, para fazer com que o servidor escute nos dados endereço IP e porta.&lt;br /&gt;&lt;br /&gt;O parâmetro &lt;code&gt;--development-mode&lt;/code&gt; ativa o modo de desenvolvimento de awful.  Neste modo, funcionalidades como o &lt;a href='http://wiki.call-cc.org/egg/awful#web-repl'&gt;Web REPL&lt;/a&gt; e o &lt;a href='http://wiki.call-cc.org/egg/awful#session-inspector'&gt;Session inspector&lt;/a&gt; são automaticamente ativadas.  O caminho &lt;code&gt;/reload&lt;/code&gt; também é automaticamente criado para que as aplicações possam ser recarregadas sem que seja necessário reiniciar o servidor.  No modo de desenvolvimento, mensagens de erro das aplicações são exibidas no cliente (e.g., navegador). Abaixo está um exemplo (&lt;code&gt;erro.scm&lt;/code&gt;):&lt;br /&gt; &lt;pre&gt;#!/usr/bin/awful&lt;br /&gt;&lt;br /&gt;(use awful)&lt;br /&gt;&lt;br /&gt;(define-page (main-page-path)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;    (++ &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Oops &amp;quot;&lt;/FONT&gt;&lt;/B&gt; 'erro)))&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;Para executar no modo de desenvolvimento:&lt;br /&gt;&lt;pre&gt;$ awful --development-mode erro.scm&lt;/pre&gt; &lt;br /&gt;Ao acessar &lt;code&gt;http://localhost:8080/&lt;/code&gt; a mensagem de erro do &lt;i&gt;screenshot&lt;/i&gt; abaixo é exibida no navegador, seguida de um link para o Web REPL.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ade5bioRWEE/TGsVfDXbMuI/AAAAAAAAAEY/WAh5Xpq6-os/s1600/awful-erro.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 272px;" src="http://1.bp.blogspot.com/_ade5bioRWEE/TGsVfDXbMuI/AAAAAAAAAEY/WAh5Xpq6-os/s400/awful-erro.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5506518592614249186" /&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;Quando executado em modo de desenvolvimento, o parâmetro &lt;code&gt;development-mode?&lt;/code&gt; tem como valor &lt;code&gt;#t&lt;/code&gt;.&lt;br /&gt; &lt;br /&gt;Outra novidade é o parâmetro &lt;code&gt;awful-response-headers&lt;/code&gt; o qual permite ajustar os campos do cabeçalho de resposta para o cliente.  Abaixo está um exemplo de um procedimento para associar URIs a respostas &lt;a href='http://en.wikipedia.org/wiki/JSON'&gt;JSON&lt;/a&gt;:&lt;br /&gt; &lt;pre&gt;#!/usr/bin/awful&lt;br /&gt;&lt;br /&gt;(use awful)&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;define-json&lt;/FONT&gt;&lt;/B&gt; path body)&lt;br /&gt;  (define-page path&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;      (awful-response-headers '((content-type &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;text/json&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;      (body))&lt;br /&gt;    no-template: #t))&lt;br /&gt;&lt;br /&gt;(define-json (main-page-path)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;{a: 1}&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A menos que explicitamente fornecido, awful calcula automaticamente o tamanho da resposta e o atribui ao campo &lt;code&gt;Content-Length&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Hoje também disponibilizei um pequeno texto com &lt;a href='http://wiki.call-cc.org/deploying-awful'&gt;instruções sobre como instalar awful em sistemas Unix[-like]&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-4858864941455485179?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/4858864941455485179/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=4858864941455485179' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4858864941455485179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4858864941455485179'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/08/awful-025.html' title='Awful 0.25'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_ade5bioRWEE/TGsVfDXbMuI/AAAAAAAAAEY/WAh5Xpq6-os/s72-c/awful-erro.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-4787102190138631326</id><published>2010-08-11T15:24:00.000-07:00</published><updated>2010-08-11T15:27:09.586-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='elisp'/><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><title type='text'>Operações em caminhos para arquivos em buffers do Emacs</title><content type='html'>Seguidamente sinto a falta de funções no &lt;a href='http://www.gnu.org/software/emacs'&gt;Emacs&lt;/a&gt; para ver o caminho completo para o arquivo aberto no &lt;i&gt;buffer&lt;/i&gt; que estou editando (poder copiar o caminho completo seria um &lt;i&gt;plus&lt;/i&gt;).  A seguir estão duas pequenas funções para fazer isso.&lt;br /&gt; &lt;br /&gt;&lt;code&gt;show-buffer-file-name&lt;/code&gt; exibe na &lt;i&gt;echo area&lt;/i&gt; do &lt;a href='http://www.gnu.org/software/emacs'&gt;Emacs&lt;/a&gt; o caminho completo para o arquivo. &lt;code&gt;copy-buffer-file-name&lt;/code&gt; coloca o caminho completo do para o arquivo no topo do &lt;i&gt;kill ring&lt;/i&gt; do &lt;a href='http://www.gnu.org/software/emacs'&gt;Emacs&lt;/a&gt; (no X Window, também copia para a área de seleção primária, o que pode ser útil para quem, como eu, usa bastante a combinacao &lt;a href='http://www.gnu.org/software/emacs'&gt;Emacs&lt;/a&gt; + emulador de terminal).&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;defun&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;show-buffer-file-name&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;  (interactive)&lt;br /&gt;  (message buffer-file-name))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;defun&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;copy-buffer-file-name&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;  (interactive)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; buffer-file-name&lt;br /&gt;      (kill-new buffer-file-name)))&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-4787102190138631326?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/4787102190138631326/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=4787102190138631326' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4787102190138631326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4787102190138631326'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/08/operacoes-em-caminhos-para-arquivos-em.html' title='Operações em caminhos para arquivos em buffers do Emacs'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-3283329494766117872</id><published>2010-07-20T16:05:00.000-07:00</published><updated>2010-07-20T16:28:50.794-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='awful'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Awful 0.24</title><content type='html'>Há pouco foi lançada a versão 0.24 de &lt;a href="http://chicken.wiki.br/eggref/4/awful"&gt;awful&lt;/a&gt;.  As novidades que mais se destacam, além de algumas pequenas melhorias e da correção de alguns &lt;span style="font-style:italic;"&gt;bugs&lt;/span&gt; que ocorriam em casos especiais, há o suporte inicial a armazenamento de identificadores de sessão em &lt;span style="font-style:italic;"&gt;cookies&lt;/span&gt; (via &lt;a href="http://chicken.wiki.br/eggref/4/spiffy-cookies"&gt;spiffy-cookies&lt;/a&gt;) e o suporte a redirecionamentos de forma fácil (procedimento &lt;code&gt;redirect-to&lt;/code&gt;).&lt;br /&gt;&lt;br /&gt;A seguir está um exemplo de definição de um redirecionador:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(define-page "/mario"&lt;br /&gt;  (lambda ()&lt;br /&gt;    (redirect-to "http://parenteses.org/mario")))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A definição do redirecionador pode ser encurtada com o uso de &lt;code&gt;cut&lt;/code&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(define-page "/mario" (cut redirect-to "http://parenteses.org/mario"))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Também aproveitei para dar uma embelezada no web REPL e no inspetor de sessão (&lt;span style="font-style:italic;"&gt;screenshots&lt;/span&gt; abaixo).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://parenteses.org/mario/img/awful/repl.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 577px; height: 513px;" src="http://parenteses.org/mario/img/awful/repl.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://parenteses.org/mario/img/awful/session-inspector.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 573px; height: 354px;" src="http://parenteses.org/mario/img/awful/session-inspector.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-3283329494766117872?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/3283329494766117872/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=3283329494766117872' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/3283329494766117872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/3283329494766117872'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/07/awful-024.html' title='Awful 0.24'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-3269078713806234889</id><published>2010-07-20T03:47:00.000-07:00</published><updated>2010-07-20T04:03:29.066-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>10 anos de Chicken!</title><content type='html'>Há dez anos foi publicado o anúncio da primeira versão pública de &lt;a href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt;: &lt;a href="http://groups.google.com/group/comp.lang.scheme/msg/edfb2da16fd89fae"&gt;http://groups.google.com/group/comp.lang.scheme/msg/edfb2da16fd89fae&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Em &lt;a href="http://web.archive.org/web/20000824034645/http://www.anu.ie/felix/chicken.html"&gt;http://web.archive.org/web/20000824034645/http://www.anu.ie/felix/chicken.html&lt;/a&gt; está a página do projeto, como era na época.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-3269078713806234889?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/3269078713806234889/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=3269078713806234889' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/3269078713806234889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/3269078713806234889'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/07/10-anos-de-chicken.html' title='10 anos de Chicken!'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-9021046603568083914</id><published>2010-05-17T18:55:00.000-07:00</published><updated>2010-05-17T19:01:24.534-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><title type='text'>Chicken 4.5.0</title><content type='html'>Alguns minutos atrás foi anunciado o lançamento da versão &lt;a href="http://chicken.wiki.br/releases/4.5.0/chicken-4.5.0.tar.gz"&gt;4.5.0&lt;/a&gt; de &lt;a href="http://www.call-with-current-continuation.org/"&gt;Chicken&lt;/a&gt;.  A lista de novidades está em &lt;a href="http://chicken.wiki.br/releases/4.5.0/NEWS"&gt;http://chicken.wiki.br/releases/4.5.0/NEWS&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-9021046603568083914?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/9021046603568083914/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=9021046603568083914' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/9021046603568083914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/9021046603568083914'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/05/chicken-450.html' title='Chicken 4.5.0'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-6470859408612194103</id><published>2010-05-12T06:57:00.000-07:00</published><updated>2010-05-12T06:59:55.461-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>Há cinqüenta anos...</title><content type='html'>&lt;a href="http://history.siam.org/sup/Fox_1960_LISP.pdf"&gt;LISP I, PROGRAMMER'S MANUAL&lt;/a&gt; (PDF).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-6470859408612194103?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/6470859408612194103/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=6470859408612194103' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6470859408612194103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6470859408612194103'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/05/ha-cinquenta-anos.html' title='Há cinqüenta anos...'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-8669918066457404232</id><published>2010-05-09T16:03:00.000-07:00</published><updated>2010-05-12T10:49:57.506-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='awful'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><title type='text'>Awful: expressões regulares para dispatching de URLs</title><content type='html'>Há pouco fiz o &lt;i&gt;commit&lt;/i&gt; da mais nova versão de &lt;a href='http://chicken.wiki.br/eggref/4/awful'&gt;awful&lt;/a&gt; (0.18) . A novidade mais significativa desta versão é o suporte a &lt;i&gt;dispatching&lt;/i&gt; de URLs através de expressões regulares.  Em outras palavras, agora é possível associar uma expressão regular a um procedimento a ser executado.  Assim, se o caminho da URL da requisição bate com a expressão regular, o procedimento é invocado com o caminho como argumento.&lt;br /&gt; &lt;br /&gt;Abaixo está um exemplo simples que ilustra o que a nova versão pode fazer:&lt;br /&gt; &lt;pre&gt;(use awful srfi-1 regex)&lt;br /&gt;&lt;br /&gt;(define-page (regexp &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;/add/.*&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (path)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((numbers (filter-map string-&amp;gt;number (string-split path &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;/&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;br /&gt;      (number-&amp;gt;string (apply + numbers)))))&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;Se acessarmos o servidor executando o código acima através da URL &lt;code&gt;http://host:port/add/1/2/3&lt;/code&gt; o resultado exibido será &lt;code&gt;6&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-8669918066457404232?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/8669918066457404232/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=8669918066457404232' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8669918066457404232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8669918066457404232'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/05/awful-expressoes-regulares-para.html' title='Awful: expressões regulares para dispatching de URLs'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-6074616337547917913</id><published>2010-05-09T10:34:00.000-07:00</published><updated>2010-05-09T10:39:07.413-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='org'/><category scheme='http://www.blogger.com/atom/ns#' term='gnus'/><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><title type='text'>Org mode e links para mensagens no Gnus</title><content type='html'>Esses dias passei os olhos sobre um &lt;a href="http://emacsworld.blogspot.com/2010/05/all-new-compact-org-mode-guide.html"&gt;guia compacto sobre o Org mode&lt;/a&gt; e&lt;br /&gt;achei uma coisa super útil: a possibilidade de fazer links do&lt;br /&gt;documento em &lt;a href="http://orgmode.org/"&gt;Org&lt;/a&gt; para mensagens do &lt;a href="http://www.gnus.org/"&gt;Gnus&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;A sintaxe é a seguinte:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;[[gnus:&amp;lt;mailbox&amp;gt;#&amp;lt;mensagem id&amp;gt;][&amp;lt;texto&amp;gt;]]&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Onde:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;tt&gt;&amp;lt;mailbox&amp;gt;&lt;/tt&gt; é a mailbox aonde está armazenada a mensagem&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;tt&gt;&amp;lt;mensagem id&amp;gt;&lt;/tt&gt; é o número da mensagem na mailbox&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;tt&gt;&amp;lt;texto&amp;gt;&lt;/tt&gt; é o texto que aparecerá no link&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Exemplo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;[[gnus:lists.chicken-users#2045 [Coisa para ler sobre Chicken]]&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Algumas combinações de teclas:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;C-c C-l: cria um link interativamente&lt;/li&gt;&lt;br /&gt;&lt;li&gt;C-C C-o: segue o link sob o cursor&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-6074616337547917913?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/6074616337547917913/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=6074616337547917913' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6074616337547917913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6074616337547917913'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/05/org-mode-e-links-para-mensagens-no-gnus.html' title='Org mode e links para mensagens no Gnus'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-2631998650951772270</id><published>2010-04-26T19:18:00.000-07:00</published><updated>2010-04-26T19:23:56.457-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='awful'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Awful scripts</title><content type='html'>Uma dica rápida para executar aplicações web em &lt;a href='http://chicken.wiki.br/eggref/4/awful'&gt;awful&lt;/a&gt; como scripts em sistemas Unix[-compatíveis]: usando a linha com &lt;a href='http://en.wikipedia.org/wiki/Shebang_%28Unix%29'&gt;shebang&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;Dessa forma, basta executar o arquivo com a aplicação web como se fosse um arquivo executável qualquer:&lt;br /&gt; &lt;pre&gt;$ cat hello-world.scm&lt;br /&gt;#! /usr/bin/awful&lt;br /&gt;&lt;br /&gt;(use awful)&lt;br /&gt;&lt;br /&gt;(define-page (main-page-path)&lt;br /&gt;  (lambda ()&lt;br /&gt;    "Hello, world!"))&lt;br /&gt;&lt;br /&gt;$ ./hello-word.scm&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-2631998650951772270?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/2631998650951772270/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=2631998650951772270' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2631998650951772270'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2631998650951772270'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/04/awful-scripts.html' title='Awful scripts'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-4826373739492041144</id><published>2010-04-16T16:38:00.000-07:00</published><updated>2010-05-12T10:54:21.795-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Sintaxe para definição de "curried procedures"</title><content type='html'>A definição de &lt;i&gt;curried procedures&lt;/i&gt; é bastante usual em Scheme.  Consiste em fazer com que o valor produzido por um procedimento seja outro procedimento.&lt;br /&gt; &lt;br /&gt;Abaixo está um exemplo de um criador de objetos que respondem a mensagens:&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;make-obj&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (message)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;case&lt;/FONT&gt;&lt;/B&gt; message&lt;br /&gt;      ((hello) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Hello!&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;      ((bye) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Bye bye!&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;else&lt;/FONT&gt;&lt;/B&gt; (error &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Unknown message.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))))&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;O código acima já está com uma sintaxe simplificada para definições de procedimentos.  A forma mais longa seria:&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;make-obj&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (message)&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;case&lt;/FONT&gt;&lt;/B&gt; message&lt;br /&gt;        ((hello) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Hello!&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;        ((bye) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Bye bye!&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;else&lt;/FONT&gt;&lt;/B&gt; (error &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Unknown message.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))))&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;Não está na especificação da linguagem, mas algumas implementações oferecem a possibilidade de usar uma sintaxe mais simplificada para a definição de &lt;i&gt;curried procedures&lt;/i&gt;:&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; ((make-obj) message)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;case&lt;/FONT&gt;&lt;/B&gt; message&lt;br /&gt;    ((hello) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Hello!&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;    ((bye) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Bye bye!&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;else&lt;/FONT&gt;&lt;/B&gt; (error &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Unknown message.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;Das implementações em que testei, &lt;a href='http://www.call-with-current-continuation.org'&gt;Chicken&lt;/a&gt;, &lt;a href='http://www.gnu.org/software/guile/guile.html'&gt;Guile&lt;/a&gt;, &lt;a href='http://www.gnu.org/software/mit-scheme/'&gt;MIT Scheme&lt;/a&gt; e &lt;a href='http://www.plt-scheme.org/'&gt;PLT&lt;/a&gt; admitem essa sintaxe para definição de &lt;i&gt;curried procedures&lt;/i&gt;. &lt;a href='http://code.google.com/p/ypsilon/'&gt;Ypsilon&lt;/a&gt; e &lt;a href='http://www.iro.umontreal.ca/~gambit/'&gt;Gambit&lt;/a&gt; não admitem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-4826373739492041144?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/4826373739492041144/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=4826373739492041144' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4826373739492041144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4826373739492041144'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/04/sintaxe-para-definicao-de-curried.html' title='Sintaxe para definição de &quot;curried procedures&quot;'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-7053251465152939923</id><published>2010-04-15T17:16:00.000-07:00</published><updated>2010-04-15T19:14:23.896-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken-doc'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><title type='text'>Documentação de Chicken com chicken-doc</title><content type='html'>&lt;a href="http://chicken.wiki.br/eggref/4/chicken-doc"&gt;chicken-doc&lt;/a&gt; é uma extensão do sistema &lt;a href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; para pesquisa e navegação na documentação do compilador e das extensões através da linha de comando.&lt;br /&gt;&lt;br /&gt;É bem parecida com uma extensão que eu havia feito há uns anos: &lt;a href="http://www.call-with-current-continuation.org/eggs/man.html"&gt;man&lt;/a&gt;. Na época da extensão &lt;a href="http://www.call-with-current-continuation.org/eggs/man.html"&gt;man&lt;/a&gt;, a documentação de &lt;a href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; era no formato textinfo.  &lt;a href="http://www.call-with-current-continuation.org/eggs/man.html"&gt;man&lt;/a&gt;, então, fazia o &lt;i&gt;parsing&lt;/i&gt; do arquivo texinfo e gerava um arquivo com expressões simbólicas de fácil pesquisa em Scheme.  Depois da adoção de &lt;a href="http://chicken.wiki.br"&gt;wiki&lt;/a&gt; para a documentação do compilador, a extensão &lt;a href="http://www.call-with-current-continuation.org/eggs/man.html"&gt;man&lt;/a&gt; caiu em desuso.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://chicken.wiki.br/eggref/4/chicken-doc"&gt;chicken-doc&lt;/a&gt;, diferentemente da extensão &lt;a href="http://www.call-with-current-continuation.org/eggs/man.html"&gt;man&lt;/a&gt;, faz o &lt;i&gt;parsing&lt;/i&gt; de arquivos fonte do &lt;a href="http://chicken.wiki.br"&gt;wiki&lt;/a&gt;, incluindo a documentação das &lt;a href="http://chicken.wiki.br/eggs"&gt;extensões&lt;/a&gt;, &lt;a href="http://chicken.wiki.br/man/4/The%20R5RS%20standard"&gt;R5RS&lt;/a&gt; e algumas &lt;a href="http://srfi.schemers.org"&gt;SRFIs&lt;/a&gt;!  Hoje foi lançada a versão 0.3.2 com a funcionalidade de pesquisa na documentação.&lt;br /&gt;&lt;br /&gt;O uso de &lt;a href="http://chicken.wiki.br/eggref/4/chicken-doc"&gt;chicken-doc&lt;/a&gt; depende da geração da base de dados onde serão feitas as pesquisas.  Para gerar a base de dados, é necessária a extensão &lt;a href="http://chicken.wiki.br/eggref/4/chicken-doc-admin"&gt;chicken-doc-admin&lt;/a&gt;.  Em &lt;a href="http://chicken.wiki.br/eggref/4/chicken-doc-admin#quick-start"&gt;http://chicken.wiki.br/eggref/4/chicken-doc-admin#quick-start&lt;/a&gt; há um passo-a-passo sobre como gerar a base.&lt;br /&gt;&lt;br /&gt;Após gerada a base, pode-se usar a ferramenta de linha de comando &lt;code&gt;chicken-doc&lt;/code&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ chicken-doc&lt;br /&gt;usage: chicken-doc -s|-c|-i path&lt;br /&gt;       chicken-doc -f id&lt;br /&gt;       chicken-doc -m re&lt;br /&gt;       chicken-doc id | path&lt;br /&gt;   -s path        Show signature&lt;br /&gt;   -c path        Show table of contents (child IDs)&lt;br /&gt;   -i path        Show documentation&lt;br /&gt;   -f id          Show all matching paths for ID&lt;br /&gt; where ID is a single identifier and PATH is zero or&lt;br /&gt; more IDs comprising a path from the documentation root,&lt;br /&gt; separated by spaces or the # character.&lt;br /&gt;&lt;br /&gt;   -m re          Show all matching paths for RE&lt;br /&gt; where RE is a POSIX regular expression.  Similar to -f.&lt;br /&gt;&lt;br /&gt;When no option is given, guess the user's intent.  With&lt;br /&gt;a single ID, find the ID (as with -f) and show its&lt;br /&gt;documentation (as with -i) or show all matching paths&lt;br /&gt;if multiple matches exist.  If more than one ID is&lt;br /&gt;provided, show documentation on the path (as with -i).&lt;br /&gt;&lt;br /&gt;Examples:&lt;br /&gt;  -f open/rdonly           # Show matches for open/rdonly&lt;br /&gt;  -s posix open/rdonly     # Show signature of open/rdonly in Unit posix&lt;br /&gt;  -s 9p open/rdonly        # Show signature of open/rdonly in 9p egg&lt;br /&gt;  -i 9p#open/rdonly        # Show documentation for same&lt;br /&gt;  -c posix                 # Show TOC for Unit posix&lt;br /&gt;  -c                       # Show toplevel TOC&lt;br /&gt;  -m call-                 # Show identifiers containing call-&lt;br /&gt;  -m -file$                # Show identifiers ending in -file&lt;br /&gt;  use                      # Show doc for "use" in chicken core&lt;br /&gt;  posix                    # Show doc for Unit posix&lt;br /&gt;  open/rdonly              # Show matches for open/rdonly&lt;br /&gt;  posix open/rdonly        # Show doc for open/rdonly in Unit posix&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Alguns exemplos de uso:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ chicken-doc reverse&lt;br /&gt;path: (scheme reverse)&lt;br /&gt;&lt;br /&gt;-- procedure: (reverse list)&lt;br /&gt;&lt;br /&gt;Returns a newly allocated list consisting of the elements of list in&lt;br /&gt;reverse order.&lt;br /&gt;&lt;br /&gt;    (reverse '(a b c))                      ===&gt;  (c b a)&lt;br /&gt;    (reverse '(a (b c) d (e (f))))&lt;br /&gt;                    ===&gt;  ((e (f)) d (b c) a)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A primeira linha indica o "caminho" para o símbolo procurado. O primeiro símbolo do caminho pode ser &lt;code&gt;scheme&lt;/code&gt; (indicando que é o símbolo é um componente da especificação da linguagem), o nome de uma &lt;i&gt;&lt;a href="http://chicken.wiki.br/man/4/Supported%20language"&gt;unit&lt;/a&gt;&lt;/i&gt; de &lt;a href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt;, uma &lt;a href="http://srfi.schemers.org/"&gt;SRFI&lt;/a&gt; ou uma &lt;a href="http://chicken.wiki.br/eggs"&gt;extensão&lt;/a&gt;. É possível que ele possa ser encontrado em mais de um módulo.  Neste caso, &lt;code&gt;chicken-doc&lt;/code&gt; apresenta uma lista de opções:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ chicken-doc enable-db&lt;br /&gt;Found 3 matches:&lt;br /&gt;(awful-sql-de-lite enable-db)  (enable-db)&lt;br /&gt;(awful-sqlite3 enable-db)      (enable-db)&lt;br /&gt;(awful-postgresql enable-db)   (enable-db)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;$ chicken-doc awful-postgresql enable-db&lt;br /&gt;&lt;br /&gt;-- procedure: (enable-db)&lt;br /&gt;&lt;br /&gt;Enable Postgresql support for awful&lt;br /&gt;(http://chicken.wiki.br/eggref/4/awful). This procedure basically sets&lt;br /&gt;up awful to use the connection, disconnection, query and query escaping&lt;br /&gt;procedures for Postgresql databases.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Com a versão lançada hoje, é possivel pesquisar na base de identificadores de procedimentos, macros e parâmetros.  Exemplos:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ chicken-doc -m '^string-&gt;'&lt;br /&gt;(library string-&gt;blob)               (string-&gt;blob STRING)&lt;br /&gt;(byte-blob string-&gt;byte-blob)        (string-&gt;byte-blob STRING) =&gt; BYTE-BLOB&lt;br /&gt;(sxml-transforms string-&gt;goodHTML)   (string-&gt;goodHTML html)&lt;br /&gt;(library string-&gt;keyword)            (string-&gt;keyword STRING)&lt;br /&gt;(scheme string-&gt;list)                (string-&gt;list string)&lt;br /&gt;(scheme string-&gt;number)              (string-&gt;number string radix)&lt;br /&gt;(scheme string-&gt;symbol)              (string-&gt;symbol string)&lt;br /&gt;(posix string-&gt;time)                 (string-&gt;time TIME [FORMAT])&lt;br /&gt;(library string-&gt;uninterned-symbol)  (string-&gt;uninterned-symbol STRING)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;O argumento para o parâmetro &lt;code&gt;-m&lt;/code&gt; é uma expressão regular.&lt;br /&gt;&lt;br /&gt;Algumas das funcionalidades de &lt;a href="http://chicken.wiki.br/eggref/4/chicken-doc"&gt;chicken-doc&lt;/a&gt; podem também ser usadas no REPL:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ csi&lt;br /&gt;&lt;br /&gt;CHICKEN&lt;br /&gt;(c)2008-2010 The Chicken Team&lt;br /&gt;(c)2000-2007 Felix L. Winkelmann&lt;br /&gt;Version 4.4.4 &lt;br /&gt;linux-unix-gnu-x86 [ manyargs dload ptables ]&lt;br /&gt;compiled 2010-03-30 on dellito (Linux)&lt;br /&gt;&lt;br /&gt;; loading ./.csirc ...&lt;br /&gt;csi&gt; (use chicken-doc)&lt;br /&gt;csi&gt; ,doc string-intersperse&lt;br /&gt;path: (data-structures string-intersperse)&lt;br /&gt;&lt;br /&gt;-- procedure: (string-intersperse LIST [STRING])&lt;br /&gt;&lt;br /&gt;Returns a string that contains all strings in `LIST` concatenated together.&lt;br /&gt;`STRING` is placed between each concatenated string and defaults to `" "`.&lt;br /&gt;&lt;br /&gt;    (string-intersperse '("one" "two") "three")&lt;br /&gt;&lt;br /&gt;is equivalent to&lt;br /&gt;&lt;br /&gt;    (apply string-append (intersperse '("one" "two") "three"))&lt;br /&gt;&lt;br /&gt;csi&gt; ,wtf concatenate&lt;br /&gt;(srfi-1 concatenate)            (concatenate  list-of-lists) -&gt; value&lt;br /&gt;(srfi-1 concatenate!)           (concatenate! list-of-lists) -&gt; value&lt;br /&gt;(ports make-concatenated-port)  (make-concatenated-port PORT1 PORT2 ...)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;O comando &lt;code&gt;,doc&lt;/code&gt; mostra a documentação do símbolo dado como argumento.  O comando &lt;code&gt;,wtf&lt;/code&gt; (de &lt;i&gt;where to find&lt;/i&gt; ;-)) é equivalente à opção de linha de comando &lt;code&gt;-m&lt;/code&gt; de &lt;code&gt;chicken-doc&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Uma opção interessante para uso de &lt;a href="http://chicken.wiki.br/eggref/4/chicken-doc"&gt;chicken-doc&lt;/a&gt; é associar uma tecla de atalho para executá-lo no emacs.  Em &lt;a href="http://chicken.wiki.br/eggref/4/chicken-doc"&gt;http://chicken.wiki.br/eggref/4/chicken-doc&lt;/a&gt; há dicas sobre como fazer isso.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-7053251465152939923?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/7053251465152939923/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=7053251465152939923' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7053251465152939923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7053251465152939923'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/04/documentacao-de-chicken-com-chicken-doc.html' title='Documentação de Chicken com chicken-doc'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-713330841145307792</id><published>2010-03-30T17:06:00.000-07:00</published><updated>2010-12-13T11:35:39.625-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='benchmark'/><title type='text'>Lies, damn lies and benchmarks</title><content type='html'>Esses dias me deparei com um &lt;a href="http://antoniocangiano.com/2007/11/28/holy-shmoly-ruby-19-smokes-python-away/"&gt;texto&lt;/a&gt; que mostra um benchmark simplificado (bastante ingênuo, na verdade) cujo título é "&lt;i&gt;Holy Shmoly, Ruby 1.9 smokes Python away!&lt;/i&gt;". O benchmark baseia-se na execução do cálculo da série de Fibonacci.  A implementação é recursiva e exercita, basicamente, chamadas de função e aritmética básica.  São comparadas as implementações de &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt; e &lt;a href="http://ruby-lang.org/"&gt;Ruby&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Embora seja muito simplificado, este benchmark desencadeou várias surpresas.&lt;br /&gt;&lt;h2&gt;Surpresa 1 -- A implementação de &lt;a href="http://ruby-lang.org/"&gt;Ruby&lt;/a&gt; está ficando mais rápida&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Esta surpresa, na realidade, foi dupla para mim.  Eu tinha idéia de que a implementação de &lt;a href="http://ruby-lang.org/"&gt;Ruby&lt;/a&gt; era "meio lenta", mas não sabia que era &lt;b&gt;tão&lt;/b&gt; lenta.  A parte boa da surpresa é que a versão 1.9 está consideravelmente mais rápida.&lt;br /&gt;&lt;br /&gt;Como referência para as próximas medições, abaixo estão os tempos de execução que obtive na minha máquina com as implementações em &lt;a href="http://ruby-lang.org/"&gt;Ruby&lt;/a&gt; para Fibonacci de 0 a 39 (Ruby 1.8 e 1.9):&lt;br /&gt;&lt;pre&gt;&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;def&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fib&lt;/span&gt;&lt;/b&gt;(n)&lt;br /&gt;    &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;if&lt;/span&gt;&lt;/b&gt; n == 0 || n == 1&lt;br /&gt;         n&lt;br /&gt;    &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;else&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;        fib(n-1) + fib(n-2)&lt;br /&gt;    &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;40.times &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;do&lt;/span&gt;&lt;/b&gt; |i|&lt;br /&gt;    puts &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"n=#{i} =&amp;gt; #{fib(i)}"&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;/pre&gt; &lt;table style="width: 435px; height: 86px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Ruby 1.8&lt;/td&gt;&lt;td&gt;Ruby 1.9&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;real    9m26.377s&lt;br /&gt;user    8m11.039s&lt;br /&gt;sys     1m15.273s&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;real    1m14.576s&lt;br /&gt;user    1m14.565s&lt;br /&gt;sys     0m0.020s&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;h2&gt;Surpresa 2 -- O desempenho de &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Ao longo deste texto vou mostrar algumas extensões que fiz ao benchmark original, o que acabou gerando mais surpresas.  A primeira dela foi medir o desempenho de &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt; usando o &lt;a href="http://en.wikipedia.org/wiki/Just-in-time_compilation"&gt;JIT&lt;/a&gt; &lt;a href="http://psyco.sourceforge.net/"&gt;Psyco&lt;/a&gt;. Abaixo estão o código utilizado e os resultados obtidos na minha máquina:&lt;br /&gt;&lt;h4&gt;Python puro (sem Psyco)&lt;/h4&gt;&lt;br /&gt;&lt;table style="width: 494px; height: 183px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;#! /usr/bin/env python&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;def&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fib&lt;/span&gt;&lt;/b&gt;(n):&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;if&lt;/span&gt;&lt;/b&gt; n == 0 &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;or&lt;/span&gt;&lt;/b&gt; n == 1:&lt;br /&gt;  &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;return&lt;/span&gt;&lt;/b&gt; n&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;else&lt;/span&gt;&lt;/b&gt;:&lt;br /&gt;  &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;return&lt;/span&gt;&lt;/b&gt; fib(n-1) + fib(n-2)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;for&lt;/span&gt;&lt;/b&gt; i &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;in&lt;/span&gt;&lt;/b&gt; xrange(40):&lt;br /&gt;    &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;print&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"n=%d =&amp;gt; %d"&lt;/span&gt;&lt;/b&gt; % (i, fib(i))&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;time ./fib.py&lt;br /&gt;n=0 =&gt; 0&lt;br /&gt;n=1 =&gt; 1&lt;br /&gt;...&lt;br /&gt;n=39 =&gt; 63245986&lt;br /&gt;&lt;br /&gt;real    2m21.908s&lt;br /&gt;user    2m21.349s&lt;br /&gt;sys     0m0.016s&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Python com Psyco&lt;/h4&gt;&lt;br /&gt;&lt;table style="width: 537px; height: 243px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;#! /usr/bin/env python&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;import&lt;/span&gt;&lt;/b&gt; psyco&lt;br /&gt;psyco.full()&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;def&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fib&lt;/span&gt;&lt;/b&gt;(n):&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;if&lt;/span&gt;&lt;/b&gt; n == 0 &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;or&lt;/span&gt;&lt;/b&gt; n == 1:&lt;br /&gt;  &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;return&lt;/span&gt;&lt;/b&gt; n&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;else&lt;/span&gt;&lt;/b&gt;:&lt;br /&gt;  &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;return&lt;/span&gt;&lt;/b&gt; fib(n-1) + fib(n-2)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;for&lt;/span&gt;&lt;/b&gt; i &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;in&lt;/span&gt;&lt;/b&gt; xrange(40):&lt;br /&gt;    &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;print&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"n=%d =&amp;gt; %d"&lt;/span&gt;&lt;/b&gt; % (i, fib(i))&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;time ./fib.py&lt;br /&gt;n=0 =&gt; 0&lt;br /&gt;n=1 =&gt; 1&lt;br /&gt;...&lt;br /&gt;n=39 =&gt; 63245986&lt;br /&gt;&lt;br /&gt;real    0m6.998s&lt;br /&gt;user    0m6.948s&lt;br /&gt;sys     0m0.008s&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Com o uso de Psyco, o tempo de execução foi de ~2m22s para ~7s.  Impressionante.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Surpresa 3 -- O desempenho de &lt;a href="http://www.call-with-current-continuation.org/"&gt;Chicken&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Decidi estender o benchmark um pouco mais e implementar o algoritmo em Scheme, com &lt;a href="http://www.call-with-current-continuation.org/"&gt;Chicken&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;(&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; (&lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fib&lt;/span&gt;&lt;/b&gt; n)&lt;br /&gt;  (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;if&lt;/span&gt;&lt;/b&gt; (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;or&lt;/span&gt;&lt;/b&gt; (= n 0) (= n 1))&lt;br /&gt;    n&lt;br /&gt;    (+ (fib (- n 1)) (fib (- n 2)))))&lt;br /&gt;&lt;br /&gt;(&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;let&lt;/span&gt;&lt;/b&gt; loop ((n 0))&lt;br /&gt;  (when (&amp;lt; n 40)&lt;br /&gt;    (print &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"n="&lt;/span&gt;&lt;/b&gt; n &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;" =&amp;gt; "&lt;/span&gt;&lt;/b&gt; (fib n))&lt;br /&gt;    (loop (+ n 1))))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;O desempenho de &lt;a href="http://www.call-with-current-continuation.org/"&gt;Chicken&lt;/a&gt;, quando interpretando código, é violentamente lento (e esperado, pelo menos por mim):&lt;br /&gt;&lt;pre&gt;time csi -s fib.scm&lt;br /&gt;n=0 =&gt; 0&lt;br /&gt;n=1 =&gt; 1&lt;br /&gt;...&lt;br /&gt;n=39 =&gt; 63245986&lt;br /&gt;&lt;br /&gt;real    5m21.635s&lt;br /&gt;user    5m20.696s&lt;br /&gt;sys     0m0.916s&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Quando o código é compilado com &lt;a href="http://www.call-with-current-continuation.org/"&gt;Chicken&lt;/a&gt;, há uma melhora significativa no desempenho:&lt;br /&gt;&lt;pre&gt;$ csc fib.scm&lt;br /&gt;time ./fib&lt;br /&gt;n=0 =&gt; 0&lt;br /&gt;n=1 =&gt; 1&lt;br /&gt;...&lt;br /&gt;n=39 =&gt; 63245986&lt;br /&gt;&lt;br /&gt;real    0m29.996s&lt;br /&gt;user    0m29.938s&lt;br /&gt;sys     0m0.060s&lt;/pre&gt;&lt;br /&gt;Usando um pouco de agressividade na otimização:&lt;br /&gt;&lt;pre&gt;$ csc -O5 fib.scm&lt;br /&gt;time ./fib&lt;br /&gt;n=0 =&gt; 0&lt;br /&gt;n=1 =&gt; 1&lt;br /&gt;...&lt;br /&gt;n=39 =&gt; 63245986&lt;br /&gt;&lt;br /&gt;real    0m21.506s&lt;br /&gt;user    0m21.405s&lt;br /&gt;sys     0m0.012s&lt;/pre&gt;&lt;br /&gt;Com a compilação do código em &lt;a href="http://www.call-with-current-continuation.org/"&gt;Chicken&lt;/a&gt;, foi possível baixar o tempo de execução de mais de 5 minutos para pouco mais de 20 segundos.&lt;br /&gt;&lt;br /&gt;Por curiosidade, resolvi ver o tempo que uma implementação em C, nos mesmos moldes, levaria:&lt;br /&gt;&lt;pre&gt;#&lt;b&gt;&lt;span style="color: rgb(95, 158, 160);"&gt;include&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(34, 139, 34);"&gt;int&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fib&lt;/span&gt;&lt;/b&gt;(&lt;b&gt;&lt;span style="color: rgb(34, 139, 34);"&gt;int&lt;/span&gt;&lt;/b&gt; n) {&lt;br /&gt;    &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;if&lt;/span&gt;&lt;/b&gt; (n == 0 || n == 1) {&lt;br /&gt;        &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;return&lt;/span&gt;&lt;/b&gt; n;&lt;br /&gt;    } &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;else&lt;/span&gt;&lt;/b&gt; {&lt;br /&gt;        &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;return&lt;/span&gt;&lt;/b&gt; fib(n - 1) + fib(n - 2);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(34, 139, 34);"&gt;int&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;main&lt;/span&gt;&lt;/b&gt;() {&lt;br /&gt;    &lt;b&gt;&lt;span style="color: rgb(34, 139, 34);"&gt;int&lt;/span&gt;&lt;/b&gt; n;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;for&lt;/span&gt;&lt;/b&gt; (n=0; n&amp;lt;40; n++) {&lt;br /&gt;        printf(&lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"n=%d =&amp;gt; %d\n"&lt;/span&gt;&lt;/b&gt;, n, fib(n));&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt; &lt;pre&gt;$ gcc -O3 -ffast-math -fomit-frame-pointer -o fib-c fib-c.c&lt;br /&gt;$ time ./fib-c&lt;br /&gt;n=0 =&gt; 0&lt;br /&gt;n=1 =&gt; 1&lt;br /&gt;...&lt;br /&gt;n=39 =&gt; 63245986&lt;br /&gt;&lt;br /&gt;real    0m1.374s&lt;br /&gt;user    0m1.372s&lt;br /&gt;sys     0m0.004s&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Até aqui, temos C, &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt; + Psyco e &lt;a href="http://www.call-with-current-continuation.org/"&gt;Chicken&lt;/a&gt; (compilado) nas três primeiras colocações em tempo de execução. Porém, há um detalhe na implementação em &lt;a href="http://www.call-with-current-continuation.org/"&gt;Chicken&lt;/a&gt; que faz uma certa diferença: o operadores numéricos (e.g., &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;=&lt;/code&gt;) aceitam um número arbitrário de argumentos, diferentemente dos operadores numéricos das outras linguagens, que são binários.  Obviamente, há um custo para isso.  Entretanto, &lt;a href="http://www.call-with-current-continuation.org/"&gt;Chicken&lt;/a&gt; dispõe de procedimentos binários para operações numéricas com inteiros (com prefixo &lt;code&gt;fx&lt;/code&gt;):&lt;br /&gt;&lt;pre&gt;(&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; (&lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fib&lt;/span&gt;&lt;/b&gt; n)&lt;br /&gt;  (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;if&lt;/span&gt;&lt;/b&gt; (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;or&lt;/span&gt;&lt;/b&gt; (fx= n 0) (fx= n 1))&lt;br /&gt;    n&lt;br /&gt;    (fx+ (fib (fx- n 1)) (fib (fx- n 2)))))&lt;br /&gt;&lt;br /&gt;(&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;let&lt;/span&gt;&lt;/b&gt; loop ((n 0))&lt;br /&gt;  (when (fx&amp;lt; n 40)&lt;br /&gt;    (print &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"n="&lt;/span&gt;&lt;/b&gt; n &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;" =&amp;gt; "&lt;/span&gt;&lt;/b&gt; (fib n))&lt;br /&gt;    (loop (fx+ n 1))))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;compilando e executando este código, temos:&lt;br /&gt;&lt;pre&gt;$ csc -O5 fibfx.scm&lt;br /&gt;$ time ./fibfx&lt;br /&gt;n=0 =&gt; 0&lt;br /&gt;n=1 =&gt; 1&lt;br /&gt;...&lt;br /&gt;n=39 =&gt; 63245986&lt;br /&gt;&lt;br /&gt;real    0m1.088s&lt;br /&gt;user    0m1.088s&lt;br /&gt;sys     0m0.000s&lt;/pre&gt;&lt;br /&gt;A surpresa aqui é que o &lt;b&gt;tempo de execução&lt;/b&gt; de uma implementação em Scheme é &lt;b&gt;menor&lt;/b&gt; do que o de uma implementação em C. E, mais intrigante ainda, é que &lt;a href="http://www.call-with-current-continuation.org/"&gt;Chicken&lt;/a&gt; compila para C. :-)  Porém, a estratégia de compilação usada por &lt;a href="http://www.call-with-current-continuation.org/"&gt;Chicken&lt;/a&gt; gera código C mais otimizado do que um humano programando.&lt;br /&gt;&lt;br /&gt;No final das contas, temos os seguintes tempos, ordenados por ordem decrescente de tempo de execução:&lt;br /&gt;&lt;table style="width: 511px; height: 163px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Ruby 1.8&lt;/td&gt;&lt;td&gt;9m26.377s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Chicken (interpretado)&lt;/td&gt;&lt;td&gt;5m21.635s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Python puro&lt;/td&gt;&lt;td&gt;2m21.908s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Ruby 1.9&lt;/td&gt;&lt;td&gt;1m14.576s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Python + Psyco&lt;/td&gt;&lt;td&gt;0m6.998s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;C&lt;/td&gt;&lt;td&gt;0m1.374s&lt;/td&gt;&lt;/tr&gt;&lt;tr style="font-weight: bold;"&gt;&lt;td&gt;Chicken (compilado)&lt;/td&gt;&lt;td&gt;0m1.088s&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;As seguintes versões de interpretadores e compiladores foram usadas:&lt;br /&gt;&lt;table style="width: 359px; height: 117px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Python&lt;/td&gt;&lt;td&gt;2.6.4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Psyco&lt;/td&gt;&lt;td&gt;1.6&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Ruby&lt;/td&gt;&lt;td&gt;1.8 e 1.9&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Chicken&lt;/td&gt;&lt;td&gt;4.4.4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;GCC&lt;/td&gt;&lt;td&gt;4.4.1&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;As medições foram feitas em um processador de 2.4GHz com sistema operacional Ubuntu Linux.&lt;br /&gt;&lt;br /&gt;Vale ressaltar, novamente, que esse benchmark, embora tenha gerado algumas surpresas, representa muito pouco para avaliação de desempenho de implementações de linguagens de programação.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-713330841145307792?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/713330841145307792/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=713330841145307792' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/713330841145307792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/713330841145307792'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/03/lies-damn-lies-and-benchmarks.html' title='Lies, damn lies and benchmarks'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-8212968718072330222</id><published>2010-03-29T16:39:00.000-07:00</published><updated>2010-03-29T16:51:09.985-07:00</updated><title type='text'>Publicação dinâmica de arquivos estáticos com awful</title><content type='html'>Hoje um usuário no canal #chicken (&lt;a href='http://freenode.net/'&gt;freenode.net&lt;/a&gt;) levantou a questão de como servir conteúdo dinâmico a partir de arquivos estáticos, mas sem publicar os arquivos estáticos diretamente. É, parece confuso.  Um exemplo seria ter o diretório de documentos do servidor vazio e gerar conteúdo dinâmico a partir de arquivos estáticos e código executado no servidor.  Isto é exatamente o que awful faz (via &lt;code&gt;define-page&lt;/code&gt;).  Porém, o usuário queria disponibilizar conteúdo dinâmico em vários formatos, não apenas em [X]HTML.  Por exemplo, servir uma imagem através da URL &lt;code&gt;http://servidor/imagem&lt;/code&gt;, onde imagem não é um arquivo no diretório de documentos do servidor.  Além disso, ele queria que &lt;code&gt;http://servidor/imagem&lt;/code&gt; retornasse a própria imagem, não uma página em HTML com &lt;code&gt;&amp;lt;img src=&amp;quot;imagem&amp;quot;&amp;gt;&lt;/code&gt;.&lt;br /&gt; &lt;br /&gt;Confesso que isso não foi algo que cogitei quando implementei &lt;code&gt;define-page&lt;/code&gt;.  Pensei no uso de &lt;code&gt;define-page&lt;/code&gt; para a definição de páginas em [X]HTML ou de texto, não para imagens, vídeos ou formatos arbitrários.&lt;br /&gt; &lt;br /&gt;Para a minha surpresa, a solução é bastante simples com o uso do procedimento &lt;a href='http://chicken.wiki.br/eggref/4/spiffy#procedures-and-macros'&gt;&lt;code&gt;send-static-file&lt;/code&gt;&lt;/a&gt;, de &lt;a href='http://chicken.wiki.br/eggref/4/spiffy'&gt;Spiffy&lt;/a&gt;:&lt;br /&gt; &lt;pre&gt;(define-page &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;img&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;begin&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;       (send-static-file &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;/home/mario/img.png&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;/pre&gt;&lt;br /&gt;O código acima faz com que &lt;code&gt;send-static-file&lt;/code&gt; ajuste os cabeçalhos HTTP para indicar que a resposta é um arquivo de imagem (com base na extensão) e envie o conteúdo do arquivo dado como argumento.&lt;br /&gt; &lt;br /&gt;Porém, &lt;code&gt;send-static-file&lt;/code&gt; considera que o caminho do arquivo passado como argumento está a partir do diretório de documentos do servidor web (i.e., o caminho passado como argumento será concatenado com o diretório de documentos do servidor web).  Tentativas de passar um caminho absoluto, obviamente, não funcionam, pois o caminho absoluto será concatenado ao diretório de documentos do servidor, possivelmente apontando para um arquivo que não existe ou, com certeza, apontando para o arquivo errado.&lt;br /&gt; &lt;br /&gt;A solução para este problema, no entanto, também é fácil: basta temporariamente mudar o valor do parâmetro que indica o diretório de documentos do servidor (&lt;code&gt;root-path&lt;/code&gt;):&lt;br /&gt; &lt;pre&gt;(define-page &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;img&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;begin&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      (parameterize ((root-path &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;/&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;         (send-static-file &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;/home/mario/img.png&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;/pre&gt; &lt;br /&gt;No exemplo acima, configurei o diretório de documentos do servidor web para ser &lt;code&gt;/&lt;/code&gt;, de forma que eu possa referenciar arquivos através do caminho absoluto.  O uso de &lt;a href='http://srfi.schemers.org/srfi-39/srfi-39.html'&gt;&lt;code&gt;parameterize&lt;/code&gt;&lt;/a&gt; garante que a definição temporária será válida apenas durante a execução do seu corpo (&lt;code&gt;send-static-file&lt;/code&gt;, no exemplo).&lt;br /&gt; &lt;br /&gt;Obviamente, a definição de URLs para envio de objetos estáticos de forma dinâmica pode ser simplificada se definirmos um procedimento para isso:&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;define-static-file&lt;/FONT&gt;&lt;/B&gt; url-path abs-path)&lt;br /&gt;  (define-page url-path&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;begin&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;br /&gt;        (parameterize ((root-path &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;/&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;          (send-static-file abs-path))&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;/pre&gt; &lt;br /&gt;Estando &lt;code&gt;define-static-file&lt;/code&gt; definido, publicar um arquivo estático de forma dinâmica, basta:&lt;br /&gt; &lt;pre&gt;(define-static-file &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;img&amp;quot;&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;/home/mario/img.png&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-8212968718072330222?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/8212968718072330222/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=8212968718072330222' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8212968718072330222'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8212968718072330222'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/03/publicacao-dinamica-de-arquivos.html' title='Publicação dinâmica de arquivos estáticos com awful'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-1929830056314671229</id><published>2010-03-24T16:46:00.000-07:00</published><updated>2010-03-24T16:50:17.843-07:00</updated><title type='text'>Awful em 35 segundos</title><content type='html'>Hoje vi na &lt;a href="http://www.python.org.br/wiki/EnvolvaSe"&gt;lista de usuários brasileiros de Python&lt;/a&gt; uma mensagem em que era apontado um &lt;a href="http://www.youtube.com/watch?v=vfzz36Hbetg"&gt;vídeo&lt;/a&gt; sobre o framework &lt;a href="http://bottle.paws.de/"&gt;Bottle&lt;/a&gt;.  O vídeo mostra o desenvolvimento de um "hello world" no framework em 36 segundos.  Resolvi fazer o mesmo com &lt;a href="http://chicken.wiki.br/eggref/4/awful"&gt;awful&lt;/a&gt; e consegui (oh!) em 35 segundos.&lt;br /&gt;&lt;br /&gt;&lt;object width="320" height="266" class="BLOG_video_class" id="BLOG_video-25701ada215b30a3" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="movie" value="http://www.youtube.com/get_player"&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;param name="flashvars" value="flvurl=http://v1.nonxt1.googlevideo.com/videoplayback?id%3D25701ada215b30a3%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1330347884%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D6CA1D896F86BD31B3D64EC5DBA362A4357F72780.24079C277AAE5B8E4984E7212821BC540482293E%26key%3Dck1&amp;amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3D25701ada215b30a3%26offsetms%3D5000%26itag%3Dw160%26sigh%3DSHcVK4G0jM4z_mWJCBSHBE7LTXs&amp;amp;autoplay=0&amp;amp;ps=blogger"&gt;&lt;embed src="http://www.youtube.com/get_player" type="application/x-shockwave-flash"width="320" height="266" bgcolor="#FFFFFF"flashvars="flvurl=http://v1.nonxt1.googlevideo.com/videoplayback?id%3D25701ada215b30a3%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1330347884%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D6CA1D896F86BD31B3D64EC5DBA362A4357F72780.24079C277AAE5B8E4984E7212821BC540482293E%26key%3Dck1&amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3D25701ada215b30a3%26offsetms%3D5000%26itag%3Dw160%26sigh%3DSHcVK4G0jM4z_mWJCBSHBE7LTXs&amp;autoplay=0&amp;ps=blogger"allowFullScreen="true" /&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Típica medição inútil, mas aí está. :-)&lt;br /&gt;&lt;br /&gt;Não sei se é possível visualizar o vídeo em uma resolução maior com esse tocador de vídeos do blogger.  Na dúvida, coloquei umas cópias em &lt;a href="http://parenteses.org/mario/misc/awful.avi"&gt;http://parenteses.org/mario/misc/awful.avi&lt;/a&gt; e &lt;a href="http://parenteses.org/mario/misc/awful.ogv"&gt;http://parenteses.org/mario/misc/awful.ogv&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-1929830056314671229?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/1929830056314671229/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=1929830056314671229' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1929830056314671229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1929830056314671229'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/03/awful-em-35-segundos_24.html' title='Awful em 35 segundos'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-5909700612556207285</id><published>2010-03-08T16:48:00.000-08:00</published><updated>2010-03-09T16:43:01.606-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Scheme sem parênteses</title><content type='html'>Para aqueles que não usam Scheme só por causa dos parênteses: seus problemas acabaram! Basta substituir os parênteses por colchetes.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;[&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; [fatorial n]&lt;br /&gt;  [&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; [&amp;lt; n 2]&lt;br /&gt;      1&lt;br /&gt;      [* n [fatorial [- n 1]]]]]&lt;br /&gt;&lt;br /&gt;[display [fatorial 5]]&lt;br /&gt;[newline]&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Exemplos com algumas implementações:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;$ csi -s fatorial.scm &lt;br /&gt;120&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.iro.umontreal.ca/~gambit/"&gt;Gambit&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;$ gsi fatorial.scm &lt;br /&gt;120&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.plt-scheme.org/"&gt;PLT&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;$ mzscheme -f fatorial.scm &lt;br /&gt;120&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/ypsilon/"&gt;Ypsilon&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;$ ypsilon fatorial.scm &lt;br /&gt;120&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Embora &lt;code&gt;[&lt;/code&gt; e &lt;code&gt;]&lt;/code&gt; sejam &lt;a href="http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-5.html#%_sec_2.3"&gt;caracteres reservados&lt;/a&gt; em &lt;a href="http://schemers.org/Documents/Standards/R5RS/HTML/"&gt;R5RS&lt;/a&gt;, muitas implementações os utilizam como sinônimos para parênteses.  É comum a prática de uso de colchetes para associações entre variáveis e valores em formas &lt;code&gt;let&lt;/code&gt;.  Exemplo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ([a 3]&lt;br /&gt;      [b 4]&lt;br /&gt;      [c 5])&lt;br /&gt;   (+ a b c))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Eu, particularmente, não costumo usar colchetes como sinônimo de parênteses, mas já vi muito código que usa.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-5909700612556207285?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/5909700612556207285/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=5909700612556207285' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5909700612556207285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5909700612556207285'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/03/scheme-sem-parenteses.html' title='Scheme sem parênteses'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-2374603368015275824</id><published>2010-02-26T14:20:00.000-08:00</published><updated>2010-02-26T14:22:23.487-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>try/catch em Scheme</title><content type='html'>Para quem não gosta da sintaxe para tratamento de exceções de &lt;code&gt;handle-exceptions&lt;/code&gt; (&lt;a  href="http://srfi.schemers.org/srfi-12/srfi-12.html"&gt;SRFI-12&lt;/a&gt;), a seguir está uma pequena macro para transformar a sintaxe de &lt;code&gt;handle-exceptions&lt;/code&gt; em uma com try/catch:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(define-syntax try&lt;br /&gt;  (syntax-rules (catch)&lt;br /&gt;    ((_ attempt (catch exn handler ...))&lt;br /&gt;     (handle-exceptions exn&lt;br /&gt;                        (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;begin&lt;/FONT&gt;&lt;/B&gt; handler ...)&lt;br /&gt;                        attempt))))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Exemplos de uso:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;try-car&lt;/FONT&gt;&lt;/B&gt; l #!optional default)&lt;br /&gt;  (try (car l)&lt;br /&gt;       (catch exn default)))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;csi&gt; (try-car '(1 2 3 4))&lt;br /&gt;1&lt;br /&gt;csi&gt; (try-car '())&lt;br /&gt;#f&lt;br /&gt;csi&gt; (try-car '() '())&lt;br /&gt;()&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-2374603368015275824?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/2374603368015275824/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=2374603368015275824' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2374603368015275824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2374603368015275824'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/02/trycatch-em-scheme.html' title='try/catch em Scheme'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-4995170427361566472</id><published>2010-02-23T16:42:00.000-08:00</published><updated>2010-02-23T16:44:25.726-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='awful'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Arc challenge em awful</title><content type='html'>Há dois anos, &lt;a  href="http://www.paulgraham.com/"&gt;Paul Graham&lt;/a&gt; propôs o seguinte desafio (&lt;i&gt;arc challenge&lt;/i&gt;):&lt;br /&gt;&lt;br /&gt; &lt;blockquote&gt;Write a program that causes the url said (e.g. http://localhost:port/said) to produce a page with an input field and a submit button. When the submit button is pressed, that should produce a second page with a single link saying "click here." When that is clicked it should lead to a third page that says "you said: ..." where ... is whatever the user typed in the original input field. The third page must only show what the user actually typed. I.e. the value entered in the input field must not be passed in the url, or it would be possible to change the behavior of the final page by editing the url.&lt;/blockquote&gt;&lt;br /&gt; &lt;br /&gt;Abaixo está uma implementação para o &lt;a  href="http://www.paulgraham.com/arcchallenge.html"&gt;arc challenge&lt;/a&gt; em &lt;a  href="http://chicken.wiki.br/eggref/4/awful"&gt;awful&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(use awful html-utils spiffy-request-vars)&lt;br /&gt;&lt;br /&gt;(define-session-page &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;said&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;    (with-request-vars $ (said)&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;cond&lt;/FONT&gt;&lt;/B&gt; (said&lt;br /&gt;             ($session-set! 'said said)&lt;br /&gt;             (link &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;said&amp;quot;&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;click here&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;            (($session 'said)&lt;br /&gt;             &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;=&amp;gt;&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (said)&lt;br /&gt;                  (++ &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;You said: &amp;quot;&lt;/FONT&gt;&lt;/B&gt; said)))&lt;br /&gt;            (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;else&lt;/FONT&gt;&lt;/B&gt; (form (++ (text-input 'said)&lt;br /&gt;                            (submit-input))&lt;br /&gt;                        action: &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;said&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                        method: 'post))))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Para testar o programa, basta executar:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ awful arc-challenge.scm&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;E acessar &lt;code&gt;http://localhost:8080/said&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-4995170427361566472?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/4995170427361566472/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=4995170427361566472' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4995170427361566472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4995170427361566472'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/02/arc-challenge-em-awful.html' title='Arc challenge em awful'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-3136214727902355139</id><published>2010-02-16T05:48:00.000-08:00</published><updated>2010-02-16T06:32:44.904-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='doctests'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>doctests em Scheme</title><content type='html'>No ano passado, o &lt;a  href="http://blog.ramgarlic.com/"&gt;Luciano Ramalho&lt;/a&gt; criou um &lt;a  href="http://groups.google.com/group/eipc"&gt;grupo&lt;/a&gt; para estudo do livro &lt;a  href="http://mitpress.mit.edu/sicp/full-text/book/book.html"&gt;Structure and Interpretation of Computer Programs&lt;/a&gt;. O grupo ainda existe mas está com as atividades paradas atualmente.  Boa parte dos componentes do grupo são usuários de &lt;a  href="http://www.python.org"&gt;Python&lt;/a&gt;.  O Luciano é um usuário de Python e mencionou a falta, em Scheme, de uma facilidade que existe em Python: a possibilidade de de especificar testes em &lt;i&gt;docstrings&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;A minha argumentação com relação a esta funcionalidade em Scheme é de que não deve ser feita da mesma forma como em Python, pois em Scheme, diferentemente de Python, &lt;i&gt;docstrings&lt;/i&gt; são ambíguas.  O equivalente a &lt;i&gt;docstrings&lt;/i&gt; em Scheme só poderia ser feito através de comentários (&lt;i&gt;doccomments&lt;/i&gt;?).&lt;br /&gt;&lt;br /&gt;Em Python, a ambigüidade não existe porque funções exigem um comando &lt;code&gt;return&lt;/code&gt; para indicar que a função terminará e desviará o fluxo de execução para o ponto imediatamente seguinte ao de onde foi invocada, opcionalmente, devolvendo resultados.  Em Scheme, não há um comando &lt;code&gt;return&lt;/code&gt; explícito (a menos que seja definido um &lt;a  href="http://call-with-hopeless-continuation.blogspot.com/2009/03/definicao-de-procedimentos-e-return.html"&gt;procedimento de escape de uma continuação&lt;/a&gt;, mas este é um caso bem específico e não muito usual). O valor produzido por um procedimento é o valor resultante da última expressão avaliada. No caso de procedimentos em que a única expressão a ser avaliada é uma string, tem-se a ambigüidade.  Exemplo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;proc&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Isso é uma docstring ou uma string legítima?&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A ambigüidade que ocorre com docstrings é a mesma que ocorre com doctests.  Se a única expressão a ser avaliada por um procedimento for uma string, como saber a string deve ser o resultado da avaliação do procedimento ou simplesmente uma docstring?  Em Scheme, é uma ambigüidade. Em Python a ambigüidade é resolvida com o comando &lt;code&gt;return&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Ignorando a ambigüidade que pode ocorrer em algumas definições, implementei em Scheme um esquema semelhante a doctests em Python.  A implementação não é de uso geral, mas serve como " prova de conceito" (ainda que o conceito não esteja totalmente correto :-)).&lt;br /&gt;&lt;br /&gt;A sintaxe das strings de teste é a seguinte:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;a expressão sob teste, que seria digitada no REPL, deve ser precedida por &lt;code&gt;&gt;&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;o resultado esperado deve ser precedido por &lt;code&gt;:&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;O parser das strings de teste é bastante limitado.  Não são admitidas múltiplas linhas para expressões de teste nem de resultado. O parser ignora linhas não iniciadas por &lt;code&gt;&gt;&lt;/code&gt; ou &lt;code&gt;:&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;A única forma sintática para declaração de procedimentos admitida é:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;proc&lt;/FONT&gt;&lt;/B&gt; args)&lt;br /&gt;  body)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Outras formas, como as abaixo, &lt;b&gt;não&lt;/b&gt; são suportadas:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;proc&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (args)&lt;br /&gt;    body))&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;proc&lt;/FONT&gt;&lt;/B&gt; #f)&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; proc (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (args) body))&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;proc&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (args)&lt;br /&gt;      body)))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Teste de procedimentos resultantes da expansão de macros também não é suportado.&lt;br /&gt;&lt;br /&gt;A implementação consiste, basicamente, de um procedimento &lt;code&gt;doctest&lt;/code&gt; que lê todas as formas (forms) do arquivo em que é invocado e procura por definições com o padrão&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;proc&lt;/FONT&gt;&lt;/B&gt; args)&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;doctest&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  body)&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;Então a string com os testes é extraída da definição e é passada para o parser de strings de teste, o qual avalia as expressões e os resultados esperados e imprime o resultado.&lt;br /&gt;&lt;br /&gt;Um aspecto interessante da implementação é a forma como o parsing do código é feito: com manipulação de listas (estrutura de dados usada para representar código em Scheme).&lt;br /&gt;&lt;br /&gt;O código da implementação, em &lt;a href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; Scheme, está abaixo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(use posix (srfi 1 13))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;doctest&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;pick-teststrings&lt;/FONT&gt;&lt;/B&gt; forms)&lt;br /&gt;    &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; Retorna uma alist '((procname1 . test-string1) (proname2 . test-string2) ...)&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;    (filter-map&lt;br /&gt;     (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (form)&lt;br /&gt;       (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; (list? form)&lt;br /&gt;            (eq? (car form) '&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;            (not (null? (cddr form))) &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; (define sym)&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;            (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; (pair? (cadr form))   &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; (define (proc ...))&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;                 (string? (caddr form))&lt;br /&gt;                 (cons (caadr form) &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; procname&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;                       (caddr form))))) &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; test-string&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;     forms))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;check&lt;/FONT&gt;&lt;/B&gt; test result)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((error-test #f)&lt;br /&gt;           (error-result #f)&lt;br /&gt;           (err-msg (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (e)&lt;br /&gt;                      (with-output-to-string (cut print-error-message e))))&lt;br /&gt;           (pass&lt;br /&gt;            (equal? (handle-exceptions e&lt;br /&gt;                                       (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;begin&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                                         (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; error-test (err-msg e))&lt;br /&gt;                                         #f)&lt;br /&gt;                                       (eval test))&lt;br /&gt;                    (handle-exceptions e&lt;br /&gt;                                       (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;begin&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                                         (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; error-result (err-msg e))&lt;br /&gt;                                         #t)&lt;br /&gt;                                       (eval result)))))&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; error-test error-result)&lt;br /&gt;          (display&lt;br /&gt;           (string-append&lt;br /&gt;            &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Erro executando &amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            (-&amp;gt;string (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; error-test test result))&lt;br /&gt;            &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; --&amp;gt; &amp;quot;&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; error-test error-result)))&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; pass&lt;br /&gt;              (print test &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; = &amp;quot;&lt;/FONT&gt;&lt;/B&gt; result &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;  [ok]&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;              (print test &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; != &amp;quot;&lt;/FONT&gt;&lt;/B&gt; result &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;  [fail]&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;              ))))&lt;br /&gt;  &lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;parse-teststring&lt;/FONT&gt;&lt;/B&gt; teststring)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;parse-line&lt;/FONT&gt;&lt;/B&gt; line prefix)&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; (string-prefix? (-&amp;gt;string prefix) line)&lt;br /&gt;           (with-input-from-string&lt;br /&gt;               (string-trim line (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (c) (char=? c prefix)))&lt;br /&gt;             read)))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((tests '())&lt;br /&gt;          (results '()))&lt;br /&gt;      (for-each (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (line)&lt;br /&gt;                  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; line (string-trim-both line))&lt;br /&gt;                  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;cond&lt;/FONT&gt;&lt;/B&gt; ((parse-line line #\&amp;gt;)&lt;br /&gt;                         &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;=&amp;gt;&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (expr)&lt;br /&gt;                              (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; tests (cons expr tests))))&lt;br /&gt;                        ((parse-line line #\:)&lt;br /&gt;                         &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;=&amp;gt;&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (expr)&lt;br /&gt;                              (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; results (cons expr results))))))&lt;br /&gt;                (with-input-from-string teststring read-lines))&lt;br /&gt;      (values tests results)))&lt;br /&gt; &lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((forms (with-input-from-file (program-name) read-file)))&lt;br /&gt;    (for-each (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (procname/teststring)&lt;br /&gt;                (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((procname (car procname/teststring))&lt;br /&gt;                      (teststring (cdr procname/teststring)))&lt;br /&gt;                  (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;===== &amp;quot;&lt;/FONT&gt;&lt;/B&gt; procname &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; =====&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;                  (let-values (((tests results) (parse-teststring teststring)))&lt;br /&gt;                    (for-each (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (test result)&lt;br /&gt;                                (check test result))&lt;br /&gt;                              (reverse tests)&lt;br /&gt;                              (reverse results)))&lt;br /&gt;                  (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;              (pick-teststrings forms))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Abaixo estão exemplos de uso de doctests e, em seguinda, a saída da execução dos testes:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#!/usr/bin/csi -script&lt;br /&gt;&lt;br /&gt;(load &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;doctest.scm&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;plus&lt;/FONT&gt;&lt;/B&gt; a b)&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; Aqui estao os testes&lt;br /&gt;&amp;gt; (plus 3 4)&lt;br /&gt;:  7&lt;br /&gt;&amp;gt; (plus 4 5 0)&lt;br /&gt;: 8&lt;br /&gt;&amp;gt; (plus 4 5)&lt;br /&gt;: 8&lt;br /&gt;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  (+ a b))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;minus&lt;/FONT&gt;&lt;/B&gt; a b)&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&lt;br /&gt;&amp;gt; (minus (plus 3 4) 3)&lt;br /&gt;:  4&lt;br /&gt;&amp;gt; (minus 4 5 0)&lt;br /&gt;:    8&lt;br /&gt;&amp;gt; (minus 4 5)&lt;br /&gt;: 8&lt;br /&gt;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  (- a b))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;sort-list-string&lt;/FONT&gt;&lt;/B&gt; l)&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&lt;br /&gt;&amp;gt; (sort-list-string '(\&amp;quot;b\&amp;quot; \&amp;quot;o\&amp;quot; \&amp;quot;p\&amp;quot; \&amp;quot;h\&amp;quot; \&amp;quot;v\&amp;quot;))&lt;br /&gt;: '(\&amp;quot;b\&amp;quot; \&amp;quot;h\&amp;quot; \&amp;quot;o\&amp;quot; \&amp;quot;p\&amp;quot; \&amp;quot;v\&amp;quot;)&lt;br /&gt;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  (sort l (cut string-ci&amp;lt;? &amp;lt;&amp;gt; &amp;lt;&amp;gt;)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;fatorial&lt;/FONT&gt;&lt;/B&gt; n)&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&lt;br /&gt;&amp;gt; (fatorial 1)&lt;br /&gt;: 1&lt;br /&gt;&amp;gt; (fatorial 2)&lt;br /&gt;: 2&lt;br /&gt;&amp;gt; (fatorial 3)&lt;br /&gt;: 6&lt;br /&gt;&amp;gt; (fatorial 5)&lt;br /&gt;: 120&lt;br /&gt;&amp;gt; (fatorial 10)&lt;br /&gt;: 3&lt;br /&gt;&amp;gt; (plus (fatorial 0) (fatorial 3))&lt;br /&gt;: 7&lt;br /&gt;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (&amp;lt; n 2)&lt;br /&gt;      1&lt;br /&gt;      (* n (fatorial (sub1 n)))))&lt;br /&gt;&lt;br /&gt;(doctest)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A saída da execução dos doctests é mostrada abaixo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;===== plus =====&lt;br /&gt;(plus 3 4) = 7  [ok]&lt;br /&gt;Erro executando (plus 4 5 0) --&gt; Error: bad argument count - received 3 but expected 2: #&lt;procedure (plus a b)&gt;&lt;br /&gt;(plus 4 5) != 8  [fail]&lt;br /&gt;&lt;br /&gt;===== minus =====&lt;br /&gt;(minus (plus 3 4) 3) = 4  [ok]&lt;br /&gt;Erro executando (minus 4 5 0) --&gt; Error: bad argument count - received 3 but expected 2: #&lt;procedure (minus a b)&gt;&lt;br /&gt;(minus 4 5) != 8  [fail]&lt;br /&gt;&lt;br /&gt;===== sort-list-string =====&lt;br /&gt;(sort-list-string (quote (b o p h v))) = (quote (b h o p v))  [ok]&lt;br /&gt;&lt;br /&gt;===== fatorial =====&lt;br /&gt;(fatorial 1) = 1  [ok]&lt;br /&gt;(fatorial 2) = 2  [ok]&lt;br /&gt;(fatorial 3) = 6  [ok]&lt;br /&gt;(fatorial 5) = 120  [ok]&lt;br /&gt;(fatorial 10) != 3  [fail]&lt;br /&gt;(plus (fatorial 0) (fatorial 3)) = 7  [ok]&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-3136214727902355139?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/3136214727902355139/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=3136214727902355139' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/3136214727902355139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/3136214727902355139'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/02/doctests-em-scheme.html' title='doctests em Scheme'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-5395995360968246868</id><published>2010-02-16T05:20:00.000-08:00</published><updated>2010-02-16T05:38:42.441-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><category scheme='http://www.blogger.com/atom/ns#' term='markerpen'/><title type='text'>markerpen.el</title><content type='html'>&lt;a href="http://www.emacswiki.org/cgi-bin/wiki/download/markerpen.el"&gt;markerpen.el&lt;/a&gt; é uma extensão interessante para destacar regiões quaisquer de buffers do &lt;a href="http://www.gnu.org/software/emacs/"&gt;Emacs&lt;/a&gt;. Analogamente, é como destacar o texto de um documento com uma caneta marca-textos (daí o nome &lt;span style="font-style:italic;"&gt;markerpen&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ade5bioRWEE/S3qePxsAzQI/AAAAAAAAAEQ/nJdHwZMpTKo/s1600-h/markerpen.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 333px;" src="http://4.bp.blogspot.com/_ade5bioRWEE/S3qePxsAzQI/AAAAAAAAAEQ/nJdHwZMpTKo/s400/markerpen.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5438833493876460802" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Para destacar uma região, basta selecionar a região desejada e executar &lt;code&gt;M-x markerpen-mark-region&lt;/code&gt;.  Para eliminar o destaque, deve-se selecionar a região e executar &lt;code&gt;M-x markerpen-clear-region&lt;/code&gt;.  Obviamente, é possível definir atalhos de teclas para esses comandos.&lt;br /&gt;&lt;br /&gt;As cores podem ser selecionadas a partir de perfis disponibilizados pela extensão.  A seleção é feita através dos comandos &lt;code&gt;M-x markerpen&lt;/code&gt;&lt;span style="font-style:italic;"&gt;n&lt;/span&gt;, onde &lt;span style="font-style:italic;"&gt;n&lt;/span&gt; é um número de 1 a 10 (há 10 perfis pré-programados).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-5395995360968246868?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/5395995360968246868/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=5395995360968246868' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5395995360968246868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5395995360968246868'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/02/emacs-markerpenel.html' title='markerpen.el'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_ade5bioRWEE/S3qePxsAzQI/AAAAAAAAAEQ/nJdHwZMpTKo/s72-c/markerpen.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-4774925713846837830</id><published>2010-02-08T14:19:00.000-08:00</published><updated>2010-02-08T14:22:32.791-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='awful'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Cálculo de fatorial através de redirecionamentos de páginas</title><content type='html'>Abaixo está uma aplicação absurdamente inútil e sem sentido usando &lt;a  href="http://chicken.wiki.br/eggref/4/awful"&gt;awful&lt;/a&gt;: cálculo de fatorial através de redirecionamentos de páginas.&lt;br /&gt;&lt;br /&gt;Para calcular o fatorial de &lt;code&gt;5&lt;/code&gt;, por exemplo, basta executar o servidor com a aplicação:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ awful awful-fatorial.scm&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;e acessar &lt;code&gt;http://localhost:8080/?n=5&lt;/code&gt; (a entrada de dados é feita através da variável &lt;code&gt;n&lt;/code&gt;).&lt;br /&gt;&lt;br /&gt;O código está a seguir:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(use awful html-tags html-utils)&lt;br /&gt;&lt;br /&gt;(root-path &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;&lt;br /&gt;(define-page (main-page-path)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((n ($ 'n 0 string-&amp;gt;number))&lt;br /&gt;           (current ($ 'current n string-&amp;gt;number))&lt;br /&gt;           (accum ($ 'accum 1 string-&amp;gt;number))&lt;br /&gt;           (finished? (&amp;lt; current 2)))&lt;br /&gt;      (html-page&lt;br /&gt;       (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; finished?&lt;br /&gt;           (&amp;lt;h1&amp;gt; n &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;! = &amp;quot;&lt;/FONT&gt;&lt;/B&gt; accum)&lt;br /&gt;           &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;       headers: (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; finished?&lt;br /&gt;                    &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                    (&amp;lt;meta&amp;gt; http-equiv: &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;refresh&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                            content: (conc &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;0;url=?n=&amp;quot;&lt;/FONT&gt;&lt;/B&gt; n&lt;br /&gt;                                           &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;amp;accum=&amp;quot;&lt;/FONT&gt;&lt;/B&gt; (* current accum)&lt;br /&gt;                                           &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;amp;current=&amp;quot;&lt;/FONT&gt;&lt;/B&gt; (sub1 current)))))))&lt;br /&gt;  no-template: #t)&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-4774925713846837830?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/4774925713846837830/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=4774925713846837830' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4774925713846837830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4774925713846837830'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/02/calculo-de-fatorial-atraves-de.html' title='Cálculo de fatorial através de redirecionamentos de páginas'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-6328242544842691437</id><published>2010-02-06T10:48:00.001-08:00</published><updated>2010-02-06T11:24:38.155-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='awful'/><category scheme='http://www.blogger.com/atom/ns#' term='sqlite'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><title type='text'>Suporte a múltiplos bancos de dados para Awful</title><content type='html'>A partir da versão 0.10, &lt;a href="http://chicken.wiki.br/eggref/4/awful"&gt;awful&lt;/a&gt; passa a oferecer suporte a múltiplos bancos de dados.  Atualmente há suporte para &lt;a href="http://www.postgresql.org"&gt;PostgreSQL&lt;/a&gt; (através da extensão &lt;a href="http://chicken.wiki.br/eggref/4/postgresql"&gt;postgresql&lt;/a&gt;) e &lt;a href="http://www.sqlite.org"&gt;SQLite3&lt;/a&gt; (através da extensão &lt;a href="http://chicken.wiki.br/eggref/4/sqlite3"&gt;sqlite3&lt;/a&gt; ou &lt;a href="http://chicken.wiki.br/eggref/4/sql-de-lite"&gt;sql-de-lite&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Há uma extensão para cada tipo de base de dados: &lt;a href="http://chicken.wiki.br/eggref/4/awful-postgresql"&gt;awful-postgresql&lt;/a&gt;, &lt;a href="http://chicken.wiki.br/eggref/4/awful-sqlite3"&gt;awful-sqlite3&lt;/a&gt; e &lt;a href="http://chicken.wiki.br/eggref/4/awful-sql-de-lite"&gt;awful-sql-de-lite&lt;/a&gt;.  No caso de SQLite3, pode-se optar por usar tanto a extensão &lt;a href="http://chicken.wiki.br/eggref/4/sqlite3"&gt;sqlite3&lt;/a&gt; ou &lt;a href="http://chicken.wiki.br/eggref/4/sql-de-lite"&gt;sql-de-lite&lt;/a&gt; (duas extensões diferentes para acesso a bases SQLite3).&lt;br /&gt;&lt;br /&gt;A forma de acesso a bases de dados continua praticamente a mesma: através do procedimento &lt;code&gt;$db&lt;/code&gt;, o qual faz uso das facilidades oferecidas por awful (conexão transparente, fechamento automático).  A única diferença é que agora é necessário carregar a extensão relativa ao tipo de base de dados que pretende-se acessar (e.g., &lt;code&gt;(use awful awful-postgresql)&lt;/code&gt;) e usar &lt;code&gt;enable-db&lt;/code&gt; como um procedimento sem argumentos, não um parâmetro com argumento booleano, como antes.&lt;br /&gt;&lt;br /&gt;Abaixo está um exemplo completo de uma aplicação que gera uma página HTML com uma tabela contendo dados de nome e endereço da tabela &lt;code&gt;users&lt;/code&gt; de uma base de dados PostgreSQL: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(use awful awful-sql-de-lite html-utils)&lt;br /&gt;&lt;br /&gt;(enable-db)&lt;br /&gt;&lt;br /&gt;(db-credentials &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;db.db&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;&lt;br /&gt;(define-page (main-page-path)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;    (tabularize ($db &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;select name, address from users&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Para publicar esta página, basta executar (supondo que o código acima está no arquivo &lt;code&gt;users.scm&lt;/code&gt;):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ awful users.scm&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(ficará disponível em &lt;code&gt;http://localhost:8080&lt;/code&gt;).&lt;br /&gt;&lt;br /&gt;Se um dia for necessário migrar essa base de dados para PostgreSQL, basta usar &lt;code&gt;(use awful-postgresl)&lt;/code&gt; em vez de &lt;code&gt;(use awful-sql-de-lite)&lt;/code&gt; e ajustar a configuração de credenciais para acesso ao banco (no caso de SQLite3, a credencial é o caminho para o arquivo com a base de dados).  Se a estrutura da base de dados não for modificada, e se forem usadas consultas SQL portáveis, o código Scheme não precisará ser alterado.&lt;br /&gt;&lt;br /&gt;Opcionalmente, a página pode ser compilada:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ csc -s users.scm&lt;br /&gt;$ awful users.so&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Simples assim. :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-6328242544842691437?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/6328242544842691437/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=6328242544842691437' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6328242544842691437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6328242544842691437'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/02/suporte-multiplos-bancos-de-dados-para.html' title='Suporte a múltiplos bancos de dados para Awful'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-944827328518112581</id><published>2010-01-26T10:15:00.000-08:00</published><updated>2010-01-26T10:27:35.584-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='woof'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='spiffy'/><title type='text'>Woof em Chicken</title><content type='html'>Há uns dias li sobre o &lt;a  href="http://www.home.unix-ag.org/simon/woof.html"&gt;woof&lt;/a&gt;, um programa para compartilhar arquivos via HTTP.  A descrição do site é mais detalhada:&lt;br /&gt;&lt;br /&gt;&lt;cite&gt;&lt;br /&gt;I guess everybody with a laptop has experienced this problem at some&lt;br /&gt;point: You plug into a network and just want to exchange files with&lt;br /&gt;other participants. It &lt;em&gt;always&lt;/em&gt; is a pain until you can exchange&lt;br /&gt;files with the person vis-a-vis.&lt;br /&gt;&lt;br /&gt;Of course there are a lot of tools to tackle this problem. For large&lt;br /&gt;scale communities there are dozens of filesharing networks. However,&lt;br /&gt;they don't work for small local networks. Of course you could put your&lt;br /&gt;stuff to exchange on a local web server, but who really wants to&lt;br /&gt;maintain this? Tools like the ingenious&lt;br /&gt;&lt;tt&gt;&lt;a href="http://www.fefe.de/ncp/"&gt;npush/npoll&lt;/a&gt;&lt;/tt&gt; are&lt;br /&gt;extremely helpful, provided that both parties have it installed,&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;&lt;a href="http://www.belwue.de/projekte/saft/"&gt;SAFT/sendfile&lt;/a&gt;&lt;/tt&gt;&lt;br /&gt;also aims to solve this problem, but needs a permanently running daemon...&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;Woof&lt;/tt&gt; (Web Offer One File) tries a different approach. It&lt;br /&gt;assumes that everybody has a web-browser or a commandline web-client&lt;br /&gt;installed. &lt;tt&gt;Woof&lt;/tt&gt; is a small simple stupid webserver that can&lt;br /&gt;easily be invoked on a single file. Your partner can access the file&lt;br /&gt;with tools he trusts (e.g. &lt;tt&gt;wget&lt;/tt&gt;). No need to enter&lt;br /&gt;passwords on keyboards where you don't know about keyboard sniffers, no&lt;br /&gt;need to start a huge lot of infrastructure, just do a&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;$ woof filename&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;and tell the recipient the URL &lt;tt&gt;woof&lt;/tt&gt; spits out. When he got that&lt;br /&gt;file, &lt;tt&gt;woof&lt;/tt&gt; will quit and everything is done.&lt;br /&gt;&lt;/cite&gt; &lt;br /&gt;&lt;br /&gt;Abaixo está uma implementação em setenta e poucas linhas de código em &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; Scheme, usando o servidor web &lt;a  href="http://chicken.wiki.br/eggref/4/spiffy"&gt;Spiffy&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#! /usr/bin/csi -s&lt;br /&gt;(use posix srfi-13 spiffy)&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;woof&lt;/FONT&gt;&lt;/B&gt; file count ip-addr port)&lt;br /&gt;  (when port (server-port port))&lt;br /&gt;  (root-path (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; (pathname-directory file) (current-directory)))&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((current-count 0)&lt;br /&gt;        (ip-addresses (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; ip-addr (string-split ip-addr &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;,&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;        (file (pathname-strip-directory file)))&lt;br /&gt;    (handle-file&lt;br /&gt;     (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (path)&lt;br /&gt;       (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (equal? (pathname-strip-directory path) file)&lt;br /&gt;           (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; (not ip-addr) (member (remote-address) ip-addresses))&lt;br /&gt;               (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((ext (pathname-extension path))&lt;br /&gt;                      (handler (alist-ref ext (file-extension-handlers)&lt;br /&gt;                                          string-ci=? send-static-file)))&lt;br /&gt;                 (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; current-count (add1 current-count))&lt;br /&gt;                 (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Serving file &amp;quot;&lt;/FONT&gt;&lt;/B&gt; file&lt;br /&gt;                        &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; to &amp;quot;&lt;/FONT&gt;&lt;/B&gt; (remote-address)&lt;br /&gt;                        &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; (count=&amp;quot;&lt;/FONT&gt;&lt;/B&gt; current-count &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;).&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;                 (handler path)&lt;br /&gt;                 (when (&amp;gt;= current-count count)&lt;br /&gt;                   (exit 0)))&lt;br /&gt;               (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;begin&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;br /&gt;                 (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Denying access to host &amp;quot;&lt;/FONT&gt;&lt;/B&gt; (remote-address) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;                 (send-status 403 &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Forbidden&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;           (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;begin&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;             (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Denying access to file &amp;quot;&lt;/FONT&gt;&lt;/B&gt; path &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;             (send-status 403 &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Forbidden&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))))&lt;br /&gt;    (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Sharing '&amp;quot;&lt;/FONT&gt;&lt;/B&gt; file &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;' with &amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;br /&gt;           (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; ip-addresses&lt;br /&gt;               (string-intersperse ip-addresses &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;, &amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;               &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;anybody&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;           &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;    (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;URL: http://&amp;quot;&lt;/FONT&gt;&lt;/B&gt; (get-host-name) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;:&amp;quot;&lt;/FONT&gt;&lt;/B&gt; port &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;/&amp;quot;&lt;/FONT&gt;&lt;/B&gt; file)&lt;br /&gt;    (start-server)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;usage&lt;/FONT&gt;&lt;/B&gt; #!optional exit-code)&lt;br /&gt;  (display&lt;br /&gt;   (string-append&lt;br /&gt;    (pathname-strip-directory (program-name))&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; [ --port=&amp;lt;port&amp;gt; ] [ --ip-addr=&amp;lt;ip address&amp;gt; ] [ --count=&amp;lt;count&amp;gt; ] file\n&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;   (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; exit-code (current-error-port) (current-output-port)))&lt;br /&gt;  (when exit-code (exit exit-code)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;cl-option-value&lt;/FONT&gt;&lt;/B&gt; option args #!optional (converter identity))&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; loop ((args args))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; (not (null? args))&lt;br /&gt;         (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((arg (car args)))&lt;br /&gt;           (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (string-prefix? option arg)&lt;br /&gt;               (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;cond&lt;/FONT&gt;&lt;/B&gt; ((string-match (string-append option &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;=(.*)&amp;quot;&lt;/FONT&gt;&lt;/B&gt;) arg)&lt;br /&gt;                      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;=&amp;gt;&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (m)&lt;br /&gt;                           (converter (cadr m))))&lt;br /&gt;                     (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;else&lt;/FONT&gt;&lt;/B&gt; (loop (cdr args))))&lt;br /&gt;               (loop (cdr args)))))))&lt;br /&gt;         &lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((args (command-line-arguments)))&lt;br /&gt;  (when (null? args)&lt;br /&gt;    (usage 1))&lt;br /&gt;  (when (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; (member &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;-h&amp;quot;&lt;/FONT&gt;&lt;/B&gt; args) (member &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;--help&amp;quot;&lt;/FONT&gt;&lt;/B&gt; args))&lt;br /&gt;    (usage 0))&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((count (cl-option-value &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;--count&amp;quot;&lt;/FONT&gt;&lt;/B&gt; args string-&amp;gt;number))&lt;br /&gt;        (ip-addr (cl-option-value &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;--ip-addr&amp;quot;&lt;/FONT&gt;&lt;/B&gt; args))&lt;br /&gt;        (port (cl-option-value &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;--port&amp;quot;&lt;/FONT&gt;&lt;/B&gt; args string-&amp;gt;number))&lt;br /&gt;        (file (car (reverse args))))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (file-exists? file)&lt;br /&gt;        (woof file (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; count 1) ip-addr port)&lt;br /&gt;        (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;begin&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;br /&gt;          (display (string-append file &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; does not exist.\n&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;                   (current-error-port))&lt;br /&gt;          (exit 1)))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Nem todas as funcionalidades do woof original estão presentes, mas é possível especificar:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;o arquivo a ser compartilhado&lt;/li&gt;&lt;br /&gt;&lt;li&gt;a porta a ser usada pelo servidor&lt;/li&gt;&lt;br /&gt;&lt;li&gt;o número IP da máquina que poderá pegar o arquivo (pode-se liberar o acesso para mais de uma máquina separando os números IP por vírgula)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;o número de vezes que o arquivo pode ser acessado&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Abaixo está a sintaxe para utilização do woof em Chicken na linha de comando:&lt;br /&gt;&lt;pre&gt;$ woof --help                                  &lt;br /&gt;woof [ --port=&amp;lt;port&amp;gt; ] [ --ip-addr=&amp;lt;ip address&amp;gt; ] [ --count=&amp;lt;count&amp;gt; ] file&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-944827328518112581?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/944827328518112581/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=944827328518112581' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/944827328518112581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/944827328518112581'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/01/woof-em-chicken.html' title='Woof em Chicken'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-4148044287153531321</id><published>2010-01-23T16:21:00.000-08:00</published><updated>2010-01-23T16:28:58.503-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>jsmin para Chicken Scheme</title><content type='html'>Há pouco fiz o &lt;span style="font-style:italic;"&gt;commit&lt;/span&gt; no repositório de extensões do sistema &lt;a href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; de uma tradução para Scheme do código C do &lt;a href="http://www.crockford.com/javascript/jsmin.html"&gt;jsmin&lt;/a&gt;, de Douglas Crockford.&lt;br /&gt;&lt;br /&gt;A &lt;a href="http://chicken.wiki.br/eggref/4/jsmin"&gt;extensão&lt;/a&gt; fornece apenas dois procedimentos: &lt;code&gt;jsmin-string&lt;/code&gt; e &lt;code&gt;jsmin-file&lt;/code&gt;, as quais compactam o código javascript considerando como entrada, respectivamente, uma string e um arquivo.&lt;br /&gt;&lt;br /&gt;O código Scheme traduzido de código C (sem uso da &lt;a href="http://chicken.wiki.br/man/4/Interface%20to%20external%20functions%20and%20variables"&gt;FFI&lt;/a&gt;) não é dos mais bonitos :-), pois a tradução foi feita praticamente linha-a-linha (inclusive mantendo os &lt;code&gt;return&lt;/code&gt;s, implementados através de &lt;code&gt;call/cc&lt;/code&gt;).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-4148044287153531321?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/4148044287153531321/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=4148044287153531321' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4148044287153531321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4148044287153531321'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/01/jsmin-para-chicken-scheme.html' title='jsmin para Chicken Scheme'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-374629810210312334</id><published>2010-01-23T03:03:00.000-08:00</published><updated>2010-01-23T03:05:59.586-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='awful'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Programação para a Web com Awful</title><content type='html'>Há uns dias comecei a desenvolver mais uma tentativa de tornar a programação para a Web mais "fácil".  O resultado é uma extensão para o sistema &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; (versão 4) que fornece as seguintes funcionalidades:&lt;br /&gt;&lt;br /&gt; &lt;ul&gt;&lt;li&gt;Interfaces simples para o uso de bases de dados &lt;a  href="http://www.postgresql.org"&gt;Postgresql&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Suporte a Ajax através da biblioteca &lt;a  href="http://jquery.com"&gt;JQuery&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Acesso fácil às variáveis de requisições HTTP (tanto da &lt;i&gt;query string&lt;/i&gt; (método GET) quando do corpo da requisição (e.g., método POST)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Flexibilidade: há vários parâmetros de configuração&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A compilação de páginas para código nativo para a plataforma alvo é fácil&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Disponibilidade de um visualizador de sessão&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Disponibilidade de um REPL que pode ser acessado através do navegador (via HTTP) para a depuração de aplicações para a web&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Tentei fazer uma documentação razoável, que cobrisse boa parte da implementação.  Ela está em &lt;a  href="http://chicken.wiki.br/eggref/4/awful"&gt;http://chicken.wiki.br/eggref/4/awful&lt;/a&gt;.  Na documentação podem ser vistos exemplos de aplicações simples que demonstram algumas das funcionalidades.&lt;br /&gt;&lt;br /&gt;Sobre o nome: é só um nome. :-)  Em &lt;a  href="http://chicken.wiki.br/eggref/4/awful#the-name"&gt;http://chicken.wiki.br/eggref/4/awful#the-name&lt;/a&gt; há algumas possíveis interpretações caso AWFUL fosse uma sigla.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-374629810210312334?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/374629810210312334/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=374629810210312334' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/374629810210312334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/374629810210312334'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2010/01/programacao-para-web-com-awful.html' title='Programação para a Web com Awful'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-7807788902121486753</id><published>2009-12-10T14:15:00.000-08:00</published><updated>2009-12-10T14:18:12.885-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Introspecção de módulos em Chicken Scheme</title><content type='html'>Abaixo está um pequeno procedimento para inspecionar símbolos de módulos importados no sistema &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; (para a versão 4).  É semelhante à função &lt;code&gt;dir&lt;/code&gt; de &lt;a  href="http://www.python.org"&gt;Python&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;introspect&lt;/FONT&gt;&lt;/B&gt; #!optional symbol)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; symbol&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((module-data (alist-ref symbol ##sys#module-table)))&lt;br /&gt;        (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; module-data&lt;br /&gt;            (let-values (((_ module-symbols _) (##sys#module-exports module-data)))&lt;br /&gt;              (map car module-symbols))&lt;br /&gt;            (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; loop ((syms (##sys#current-environment)))&lt;br /&gt;              (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? syms)&lt;br /&gt;                  '()&lt;br /&gt;                  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((sym/sym+prefix (car syms))&lt;br /&gt;                         (sym+prefix (symbol-&amp;gt;string (cdr sym/sym+prefix)))&lt;br /&gt;                         (tokens (string-split sym+prefix &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;#&amp;quot;&lt;/FONT&gt;&lt;/B&gt; #t))&lt;br /&gt;                         (prefix (car tokens)))&lt;br /&gt;                    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (equal? (-&amp;gt;string symbol) prefix)&lt;br /&gt;                        (cons (string-&amp;gt;symbol (string-intersperse (cdr tokens) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;                              (loop (cdr syms)))&lt;br /&gt;                        (loop (cdr syms))))))))&lt;br /&gt;      (map car (##sys#current-environment))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Exemplos de uso&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ csi -n&lt;br /&gt;&lt;br /&gt;CHICKEN&lt;br /&gt;(c)2008-2009 The Chicken Team&lt;br /&gt;(c)2000-2007 Felix L. Winkelmann&lt;br /&gt;Version 4.2.0 - SVN rev. 16023&lt;br /&gt;linux-unix-gnu-x86 [ manyargs dload ptables applyhook ]&lt;br /&gt;compiled 2009-10-20 on dellito (Linux)&lt;br /&gt;&lt;br /&gt;#;1&gt; ,l introspection.scm&lt;br /&gt;; loading introspection.scm ...&lt;br /&gt;#;1&gt; (introspect)&lt;br /&gt;()&lt;br /&gt;#;2&gt; (import html-utils)&lt;br /&gt;; loading /usr/local/chicken-4.2.0/lib/chicken/4/html-utils.import.so ...&lt;br /&gt;; loading /usr/local/chicken-4.2.0/lib/chicken/4/chicken.import.so ...&lt;br /&gt;; loading /usr/local/chicken-4.2.0/lib/chicken/4/scheme.import.so ...&lt;br /&gt;; loading /usr/local/chicken-4.2.0/lib/chicken/4/files.import.so ...&lt;br /&gt;; loading /usr/local/chicken-4.2.0/lib/chicken/4/data-structures.import.so ...&lt;br /&gt;; loading /usr/local/chicken-4.2.0/lib/chicken/4/srfi-13.import.so ...&lt;br /&gt;; loading /usr/local/chicken-4.2.0/lib/chicken/4/posix.import.so ...&lt;br /&gt;; loading /usr/local/chicken-4.2.0/lib/chicken/4/utils.import.so ...&lt;br /&gt;; loading /usr/local/chicken-4.2.0/lib/chicken/4/html-tags.import.so ...&lt;br /&gt;; loading /usr/local/chicken-4.2.0/lib/chicken/4/srfi-1.import.so ...&lt;br /&gt;#;3&gt; (introspect 'html-utils)&lt;br /&gt;(tabularize itemize enumerate html-page combo-box hidden-input)&lt;br /&gt;#;4&gt; (introspect 'srfi-1)&lt;br /&gt;(alist-cons alist-copy alist-delete alist-delete! any append! append-map append-map!&lt;br /&gt;append-reverse append-reverse! assoc break break! car+cdr circular-list circular-list? &lt;br /&gt;concatenate concatenate! cons* count delete delete! delete-duplicates delete-duplicates! &lt;br /&gt;dotted-list? drop drop-right drop-right! drop-while eighth every fifth filter filter! filter-map &lt;br /&gt;find find-tail first fold fold-right fourth iota last last-pair length+ list-copy list-index &lt;br /&gt;list-tabulate list= lset-adjoin lset-diff+intersection lset-diff+intersection! lset-difference &lt;br /&gt;lset-difference! lset-intersection lset-intersection! lset-union lset-union! lset-xor lset-xor! &lt;br /&gt;lset&lt;= lset= make-list map map! map-in-order member ninth not-pair? null-list? pair-fold &lt;br /&gt;pair-fold-right pair-for-each partition partition! proper-list? reduce reduce-right remove &lt;br /&gt;remove! reverse! second seventh sixth span span! split-at split-at! take take! take-right &lt;br /&gt;take-while take-while! tenth third unfold unfold-right unzip1 unzip2 unzip3 unzip4 unzip5 xcons &lt;br /&gt;zip)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-7807788902121486753?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/7807788902121486753/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=7807788902121486753' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7807788902121486753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7807788902121486753'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/12/introspeccao-de-modulos-em-chicken.html' title='Introspecção de módulos em Chicken Scheme'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-481517227748275617</id><published>2009-12-01T16:00:00.000-08:00</published><updated>2009-12-01T16:07:37.017-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gcc'/><title type='text'>Opções utilizadas nos diferentes níveis de otimização do GCC</title><content type='html'>Hoje surgiu uma &lt;a href="http://gcc.gnu.org/ml/gcc-help/2009-12/msg00015.html"&gt;dica interessante&lt;/a&gt; na &lt;a href="http://gcc.gnu.org/ml/gcc-help/"&gt;lista de discussão&lt;/a&gt; do &lt;a href='http://gcc.gnu.org/'&gt;GCC&lt;/a&gt;.  Está reproduzida abaixo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;From: "John (Eljay) Love-Jensen"&lt;br /&gt;Subject: Re: How can I find out which optimizing techniques were used for  each function?&lt;br /&gt;To: Byoungyoung Lee, GCC-help &lt;gcc-help@gcc.gnu.org&gt;&lt;br /&gt;Date: Tue, 1 Dec 2009 04:51:11 -0800&lt;br /&gt;&lt;br /&gt;Hi Byoungyoung Lee,&lt;br /&gt;&lt;br /&gt;&gt; Is there anyway in gcc to log the information about which compiler&lt;br /&gt;&gt; options were actually used to optimize each function?&lt;br /&gt;&gt; For example, if I compile a program with option -O3, how could I&lt;br /&gt;&gt; figure out which specific options (such as -funroll-loops or something&lt;br /&gt;&gt; like that) were used to optimize function X ?&lt;br /&gt;&lt;br /&gt;I use this technique:&lt;br /&gt;&lt;br /&gt;echo '' | gcc -O3 -fverbose-asm -S -xc - -o O3.s&lt;br /&gt;cat O3.s&lt;br /&gt;&lt;br /&gt;In the created O3.s assembly source comment, it mentions which flags were&lt;br /&gt;enabled by the -O3 switch.&lt;br /&gt;&lt;br /&gt;If you want a detailed assembly line-by-line diagnostic of which particular&lt;br /&gt;optimization was used for a given algorithm, you'll have to do some more&lt;br /&gt;sleuthing.&lt;br /&gt;&lt;br /&gt;Such as using -fno-&amp;lt;flag&amp;gt; to disable all the flags, and enable them&lt;br /&gt;one-by-one.&lt;br /&gt;&lt;br /&gt;Or perhaps by dumping the compiler state after each optimization pass (which&lt;br /&gt;I think is usually only used as a diagnostic aid for making changes to GCC&lt;br /&gt;itself).&lt;br /&gt;&lt;br /&gt;Also, the majority of optimizations do not have a toggle-able flag to&lt;br /&gt;enable/disable them.  As I understand it...  -O1 enables a whole lot of&lt;br /&gt;optimizations that do not have toggle-able flags.  -O2 enables a few more.&lt;br /&gt;-O3 enables one-or-two more.&lt;br /&gt;&lt;br /&gt;HTH,&lt;br /&gt;--Eljay&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-481517227748275617?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/481517227748275617/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=481517227748275617' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/481517227748275617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/481517227748275617'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/12/opcoes-utilizadas-nos-diferentes-niveis.html' title='Opções utilizadas nos diferentes níveis de otimização do GCC'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-2123940718238465456</id><published>2009-12-01T15:49:00.000-08:00</published><updated>2009-12-01T15:57:13.355-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Indentação de and-let* no Emacs</title><content type='html'>A indentação padrão do &lt;a href="http://www.gnu.org/software/emacs"&gt;Emacs&lt;/a&gt; para a expressão &lt;a href="http://srfi.schemers.org/srfi-2/srfi-2.html"&gt;&lt;code&gt;and-let*&lt;/code&gt;&lt;/a&gt; não é das melhores.  Abaixo está a expressão a ser avaliada no &lt;a href="http://www.gnu.org/software/emacs"&gt;Emacs&lt;/a&gt; para fazer com que a indentação padrão de &lt;code&gt;and-let*&lt;/code&gt; (Figura 1) fique como a da Figura 2:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(put 'and-let* 'scheme-indent-function 1)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ade5bioRWEE/SxWsmrNHs7I/AAAAAAAAAD8/LhClmqwV1V0/s1600/and-let-fig.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 399px; height: 123px;" src="http://1.bp.blogspot.com/_ade5bioRWEE/SxWsmrNHs7I/AAAAAAAAAD8/LhClmqwV1V0/s400/and-let-fig.png" alt="" id="BLOGGER_PHOTO_ID_5410420307788280754" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-2123940718238465456?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/2123940718238465456/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=2123940718238465456' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2123940718238465456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2123940718238465456'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/12/indentacao-de-and-let-no-emacs.html' title='Indentação de and-let* no Emacs'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_ade5bioRWEE/SxWsmrNHs7I/AAAAAAAAAD8/LhClmqwV1V0/s72-c/and-let-fig.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-8508399053545043804</id><published>2009-11-24T09:19:00.000-08:00</published><updated>2009-11-24T09:20:40.267-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Suporte a versionamento de bibliotecas de carga dinâmica para Chicken 4.2.0</title><content type='html'>Coloquei em &lt;a href='http://parenteses.org/mario/misc/chicken-4.2.0-soname.patch'&gt;http://parenteses.org/mario/misc/chicken-4.2.0-soname.patch&lt;/a&gt; um &lt;i&gt;patch&lt;/i&gt; para a versão estável mais recente do sistema &lt;a href='http://www.call-with-current-continuation.org'&gt;Chicken&lt;/a&gt; (4.2.0).  Este &lt;i&gt;patch&lt;/i&gt; recoloca o suporte a versionamento das bibliotecas de carga dinâmica usadas pelo &lt;i&gt;runtime&lt;/i&gt;.  Isso permite que várias versões do sistema Chicken convivam pacificamente quando instaladas no mesmo sistema operacional (i.e., o compilador de uma versão não tentará usar bibliotecas de carga dinâmica do compilador de outra versão).&lt;br /&gt;&lt;br /&gt;O &lt;i&gt;patch&lt;/i&gt; é, na verdade, um &lt;i&gt;backport&lt;/i&gt; do suporte que existe na versão de desenvolvimento do sistema Chicken para a versão estável mais recente.  A versão 4.3.0 deverá sair com esta correção.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-8508399053545043804?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/8508399053545043804/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=8508399053545043804' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8508399053545043804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8508399053545043804'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/11/suporte-versionamento-de-bibliotecas-de.html' title='Suporte a versionamento de bibliotecas de carga dinâmica para Chicken 4.2.0'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-5926729750837662064</id><published>2009-11-18T13:54:00.000-08:00</published><updated>2009-11-18T14:13:18.800-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sawfish'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Corrigindo o Sawfish no Ubuntu 9.10</title><content type='html'>Lamentavelmente, a versão do &lt;a href="http://sawfish.wikia.com/"&gt;Sawfish&lt;/a&gt; fornecida pelo &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt; 9.10 contém um &lt;a href="https://bugs.launchpad.net/ubuntu/+source/sawfish/+bug/433358"&gt;bug&lt;/a&gt;.  Felizmente, há uma forma fácil de corrigi-lo.  Abaixo está uma receita de bolo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;1. $ sudo apt-get source sawfish&lt;br /&gt;2. $ sudo apt-get build-dep sawfish&lt;br /&gt;3. $ cd sawfish-1.3.5.2&lt;br /&gt;4. $ wget http://parenteses.org/mario/misc/sawfish-patch.diff&lt;br /&gt;5. $ patch -p1 --ignore-whitespace &amp;lt; sawfish-patch.diff&lt;br /&gt;6. $ dpkg-buildpackage -rfakeroot -uc -b&lt;br /&gt;7. $ sudo dpkg -i ../sawfish_1.3.5.2-1_i386.deb&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;O passo 1 instala os fontes do pacote do sawfish.&lt;br /&gt;&lt;br /&gt;O passo 2 instala os pacotes necessários para a compilação do sawfish.&lt;br /&gt;&lt;br /&gt;O passo 3 é óbvio.&lt;br /&gt;&lt;br /&gt;O passo 4 baixa o patch a ser aplicado para que o sawfish passe a funcionar (é o patch disponível em &lt;a href="http://sawfish.wikia.com/wiki/Fix_sawfish_server_connection"&gt;http://sawfish.wikia.com/wiki/Fix_sawfish_server_connection&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;O passo 5 aplica o patch nos fontes do sawfish.&lt;br /&gt;&lt;br /&gt;O passo 6 compila o código corrigido e gera os pacotes (.deb).&lt;br /&gt;&lt;br /&gt;O passo 7 instala o pacote com o sawfish corrigido. &lt;br /&gt;&lt;br /&gt;Com isso, os programas &lt;code&gt;sawfish-client&lt;/code&gt; e &lt;code&gt;sawfish-ui&lt;/code&gt; passam a funcionar normalmente.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ sawfish-client &lt;br /&gt;sawfish 1.3.5.2, Copyright (C) 1999-2000 John Harper&lt;br /&gt;sawfish comes with ABSOLUTELY NO WARRANTY; for details see the file COPYING&lt;br /&gt;&lt;br /&gt;Enter `,help' to list commands.&lt;br /&gt;user&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-5926729750837662064?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/5926729750837662064/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=5926729750837662064' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5926729750837662064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5926729750837662064'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/11/corrigindo-o-sawfish-no-ubuntu-910.html' title='Corrigindo o Sawfish no Ubuntu 9.10'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-2854803103851817095</id><published>2009-11-07T09:22:00.000-08:00</published><updated>2009-11-07T09:36:16.033-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='música'/><title type='text'>Don't cross my way</title><content type='html'>Na semana passada o &lt;a href="http://www.myspace.com/eduardodutra"&gt;Eduardo&lt;/a&gt; me enviou a versão final da música que gravou mais recentemente (Don't Cross My Way). A composição e as gravações de guitarra e vocal foram feitas por ele. A bateria foi gravada pelo Fábio Cruz (Tela), a gaita pelo Mateus Brod e o baixo por mim.&lt;br /&gt;&lt;br /&gt;A música está disponível na &lt;a href="http://www.myspace.com/eduardodutra"&gt;página do Eduardo no MySpace&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-2854803103851817095?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/2854803103851817095/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=2854803103851817095' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2854803103851817095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2854803103851817095'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/11/dont-cross-my-way.html' title='Don&apos;t cross my way'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-1260996947578908733</id><published>2009-10-24T12:15:00.000-07:00</published><updated>2009-10-24T12:31:53.786-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Jogo para iPhone em Scheme</title><content type='html'>O &lt;a href="https://mercure.iro.umontreal.ca/pipermail/gambit-list/2009-October/004135.html"&gt;Scheme hacker&lt;/a&gt; &lt;a href="http://www.ventonegro.org"&gt;Alex Queiroz&lt;/a&gt; implementou o jogo &lt;a href="http://www.dunasystems.com.br/reverso/"&gt;Reverso&lt;/a&gt; para iPhone.  Os comentários de Alex sobre a implementação do jogo estão em &lt;a href="http://www.ventonegro.org/2009/10/scheme-hits-the-app-store/"&gt;http://www.ventonegro.org/2009/10/scheme-hits-the-app-store/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Certamente uma aplicação muito interessante da linguagem.  Alex utilizou a implementação &lt;a href="http://www.iro.umontreal.ca/~gambit/"&gt;Gambit&lt;/a&gt; (assim como &lt;a href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt;, compila Scheme para C) e diz que o código resultante é 90% Scheme e 10% Objective-C.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-1260996947578908733?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/1260996947578908733/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=1260996947578908733' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1260996947578908733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1260996947578908733'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/10/jogo-para-iphone-em-scheme.html' title='Jogo para iPhone em Scheme'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-8619726137250850676</id><published>2009-09-03T15:56:00.000-07:00</published><updated>2009-09-23T15:44:48.530-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web-scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>web-scheme para Chicken 4</title><content type='html'>Vou aproveitar a transição de versões do sistema &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; (versão 3 -&gt; versão 4, com algumas incompatibilidades) para lançar uma versão nova de &lt;a  href="http://chicken.wiki.br/eggref/3/web-scheme"&gt;web-scheme&lt;/a&gt;, totalmente incompatível com a versão anterior (para Chicken 3).  Eu mesmo provavelmente serei o maior prejudicado pelas incompatibilidades.  Sem exagero, devo ter algumas dezenas de milhares de linhas de código usando web-scheme e Chicken 3.  Mas o momento é esse.&lt;br /&gt;&lt;br /&gt;Se bem me lembro, a extensão &lt;a  href="http://chicken.wiki.br/eggref/3/web-scheme"&gt;web-scheme&lt;/a&gt; foi lançada em 2005 e, desde então, venho pensando em algumas melhorias que só podem ser implementadas quebrando a compatibilidade com versões anteriores. Como Chicken 4 de certa forma faz isso, vou aproveitar a onda. :-)&lt;br /&gt;&lt;br /&gt;As duas maiores modificações são sintáticas.&lt;br /&gt;&lt;br /&gt;Uma das coisas que me incomodam em web-scheme para Chicken 3 é o mapeamento direto de nomes de tags para procedimentos.  Inicialmente me pareceu uma boa idéia, e na maioria dos casos é, mas há situações que tornam esse aspecto inconveniente.  Por exemplo, o procedimento equivalente à tag &lt;code&gt;map&lt;/code&gt;, deveria, a rigor, ser &lt;code&gt;map&lt;/code&gt;.  Obviamente isso causa problemas em Scheme.&lt;br /&gt;&lt;br /&gt;Casos semelhantes ocorrem com tags com nomes muito usuais como &lt;code&gt;select&lt;/code&gt; (Chicken define uma macro com esse nome), &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;i&lt;/code&gt; ou &lt;code&gt;object&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Em Chicken 4 há a possibilidade de se importar um módulo prefixando símbolos do módulo importado.  Então, por exemplo, seria possível importar o módulo web-scheme prefixando os procedimentos por &lt;code&gt;ws:&lt;/code&gt;.  Nos casos como o do procedimento &lt;code&gt;map&lt;/code&gt;, &lt;b&gt;não&lt;/b&gt; usar um prefixo seria suicídio.  É difícil algum código em Scheme não fazer uso de &lt;code&gt;map&lt;/code&gt;. web-scheme para Chicken 3 coloca "de fábrica" o prefixo &lt;code&gt;ws:&lt;/code&gt; nos procedimentos &lt;code&gt;map&lt;/code&gt; e &lt;code&gt;select&lt;/code&gt;, para evitar conflito de nomes com os respectivos procedimento e macro correspondentes.  Isso já é meio feio em Chicken 3, em que não há uma forma direta para se importar uma biblioteca de extensão com um prefixo -- em Chicken 4 seria muito feio, pois se o usuário decide prefixar os símbolos do módulo, ficarão dois prefixos para &lt;code&gt;map&lt;/code&gt; e &lt;code&gt;select&lt;/code&gt;!&lt;br /&gt;&lt;br /&gt;Decidi, então, modificar o nome de todos os procedimentos correspondentes a tags HTML e usar uma notação semelhante à usada por &lt;a  href="http://hop.inria.fr/"&gt;Hop&lt;/a&gt;.  Assim, em vez de &lt;code&gt;(pre "texto")&lt;/code&gt;, tem-se &lt;code&gt;(&amp;lt;pre&amp;gt; "texto")&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Não estou totalmente satisfeito com esta notação, pois é conflitante com a convenção de nomes de classes quando se usa um sistema de objetos.  Em Scheme não chega a ser um grande problema, pois o uso de classes não é muito usual.  Em Common Lisp essa decisão seria mais problemática, pois &lt;a  href="http://en.wikipedia.org/wiki/Common_Lisp_Object_System"&gt;CLOS&lt;/a&gt; é bastante usado.  Optei por essa sitaxe porque claramente lembra a sintaxe de tags HTML e provavelmente desenvolvedores para a Web associarão &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; à tag &lt;code&gt;pre&lt;/code&gt; de HTML e não à classe &lt;code&gt;pre&lt;/code&gt; de algum código parte de um sistema de objetos.&lt;br /&gt;&lt;br /&gt;A outra modificação é com relação à sintaxe para atributos e valores de atributos de tags.  Em web-scheme para Chicken 3 usa-se da seguinte forma:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(a 'href "http://minha-url.com" "Minha URL")&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;Em web-scheme para Chicken 4 decidi usar parâmetros por palavra-chave para representar atributos.  Fica, então, assim:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(&amp;lt;a&amp;gt; href: "http://minha-url.com" "Minha URL")&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As razões para esta mudaça são puramente técnicas.  No esquema usado em web-scheme para Chicken 3, precisei implementar um parser para extrair atributos e seus respectivos valores.  Usando parâmetros por palavra-chave, ganho o parser "de brinde" de Chicken, melhor e mais rápido.&lt;br /&gt;&lt;br /&gt;O esquema de atributos usado por web-scheme para Chicken 3 tem uma limitação chata quando espera-se poder usar ou não atributos em função do fluxo de execução do código.  Exemplo: no caso de um procedimento &lt;code&gt;text-input&lt;/code&gt; como um &lt;i&gt;wrapper&lt;/i&gt; para o elemento &lt;code&gt;input&lt;/code&gt; de tipo texto:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;text-input&lt;/FONT&gt;&lt;/B&gt; text #!key maxlength)&lt;br /&gt;     (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; maxlength&lt;br /&gt;       (input 'type &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;text&amp;quot;&lt;/FONT&gt;&lt;/B&gt; 'maxlength maxlength 'value text)&lt;br /&gt;       (input 'type &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;text&amp;quot;&lt;/FONT&gt;&lt;/B&gt; 'value text)))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Em web-scheme para Chicken 3 não há uma forma "fácil" (i.e., sem &lt;code&gt;eval&lt;/code&gt; ou macros) de fazer isso sem duplicar código. Em web-scheme para Chicken 4 bastará:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;text-input&lt;/FONT&gt;&lt;/B&gt; text #!key maxlength)&lt;br /&gt;    (&amp;lt;input&amp;gt; type: &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;text&amp;quot;&lt;/FONT&gt;&lt;/B&gt; maxlength: maxlength value: text)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;O uso de parâmetros por palavra-chave dá essa flexibilidade, o que é tratado internamente pelo código que gera o HTML.  Se o valor de um parâmetro for &lt;code&gt;#f&lt;/code&gt; o par atributo/valor não é gerado.  Em web-scheme para Chicken 3 geraria uma certa complicação nos casos de atributos que não requerem valor, como &lt;code&gt;selected&lt;/code&gt; em elementos &lt;code&gt;select&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Essas serão as modificações mais radicais.  Haverá também modificações nos procedimentos extras de web-scheme, os quais não estão diretamente relacionados ao mapeamento tags-&gt;procedimentos.  Mas essa parte ainda está em estudo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-8619726137250850676?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/8619726137250850676/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=8619726137250850676' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8619726137250850676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8619726137250850676'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/09/web-scheme-para-chicken-4.html' title='web-scheme para Chicken 4'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-6633304015411074352</id><published>2009-07-29T17:53:00.000-07:00</published><updated>2009-07-29T18:03:51.184-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Fatiamento de seqüências em Scheme</title><content type='html'>&lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt; oferece uma funcionalidade interessante para ser usadas com seqüências (string, listas e qualquer objeto com o método &lt;code&gt;__getslice__&lt;/code&gt;, suponho).  O fatiamento de &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt; admite índices negativos, omissão de índices e índices maiores que o tamanho da seqüência.&lt;br /&gt;&lt;br /&gt;Exemplos:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&gt;&gt;&gt; "abcdef"[3:6]&lt;br /&gt;'def'&lt;br /&gt;&gt;&gt;&gt; [1, 2, 3, 4, 5][:3]&lt;br /&gt;[1, 2, 3]&lt;br /&gt;&gt;&gt;&gt; [1,2,3,4,5][:-3]&lt;br /&gt;[1, 2]&lt;br /&gt;&gt;&gt;&gt; [1,2,3,4,5][-3:]&lt;br /&gt;[3, 4, 5]&lt;br /&gt;&gt;&gt;&gt; [1,2,3,4,5][-10:]&lt;br /&gt;[1, 2, 3, 4, 5]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A seguir está uma implementação de algo parecido para &lt;a href="http://www.call-with-current-continuation.org/"&gt;Chicken&lt;/a&gt;, que funciona com listas, vetores, strings e permite a adição de fatiadores personalizados para o procedimento &lt;code&gt;slice&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#!/usr/bin/csi -script&lt;br /&gt;&lt;br /&gt;(use (srfi 1 13))&lt;br /&gt;&lt;br /&gt;(&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;slice&lt;/span&gt;&lt;/b&gt;&lt;br /&gt; (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;let&lt;/span&gt;&lt;/b&gt; ()&lt;br /&gt;   (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; (&lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;positive?&lt;/span&gt;&lt;/b&gt; n) (&amp;gt; n 0))&lt;br /&gt;   (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; (&lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;negative?&lt;/span&gt;&lt;/b&gt; n) (&amp;lt; n 0))&lt;br /&gt;   (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; (&lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;both-positive?&lt;/span&gt;&lt;/b&gt; n m) (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; n m (&amp;gt;= n 0) (&amp;gt;= m 0)))&lt;br /&gt; &lt;br /&gt;   (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; (&lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;from/to&lt;/span&gt;&lt;/b&gt; from to len)&lt;br /&gt;     (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;cond&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;      ((&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; from (&amp;gt; from len))         &lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;; [XXX:2]&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;        #f)&lt;br /&gt;      ((&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; (both-positive? from to)   &lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;; [1:2]&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;             from to&lt;br /&gt;            (&amp;gt; to from)&lt;br /&gt;            (&amp;lt; to len))&lt;br /&gt;       (cons from to))&lt;br /&gt;      ((&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; (both-positive? from to)   &lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;; [1:XXX]&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;             from to&lt;br /&gt;            (&amp;gt; to from)&lt;br /&gt;            (&amp;gt;= to len))&lt;br /&gt;       (cons from len))&lt;br /&gt;      ((&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; (both-positive? from to)   &lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;; [2:1]&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;             from to&lt;br /&gt;            (&amp;gt; from to))&lt;br /&gt;       #f)&lt;br /&gt;      ((&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; from                       &lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;; [-1:]&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;             (&amp;lt; from 0)&lt;br /&gt;            (not to))&lt;br /&gt;       (cons (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;if&lt;/span&gt;&lt;/b&gt; (&amp;gt;= (abs from) len)&lt;br /&gt;                 0&lt;br /&gt;                 (+ len from))&lt;br /&gt;             len))&lt;br /&gt;      ((&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; (not from)                 &lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;; [:-1]&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;             to&lt;br /&gt;            (&amp;lt; to 0))&lt;br /&gt;       (cons 0&lt;br /&gt;             (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;if&lt;/span&gt;&lt;/b&gt; (&amp;gt;= (abs to) len)&lt;br /&gt;                 len&lt;br /&gt;                 (+ len to))))&lt;br /&gt;      ((&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; from                       &lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;; [1:]&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;             (&amp;gt;= from 0)&lt;br /&gt;            (not to))&lt;br /&gt;       (cons from len))&lt;br /&gt;      ((&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; from to                    &lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;; [-2:-1]&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;             (&amp;lt; from 0)&lt;br /&gt;            (&amp;lt; to 0)&lt;br /&gt;            (&amp;lt; to from))&lt;br /&gt;       #f)&lt;br /&gt;      ((&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; from to                    &lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;; [-1:-2]&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;             (&amp;lt; from 0)&lt;br /&gt;            (&amp;lt; to 0))&lt;br /&gt;       (cons (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;if&lt;/span&gt;&lt;/b&gt; (&amp;gt;= (abs from) len)&lt;br /&gt;                 0&lt;br /&gt;                 (+ len from))&lt;br /&gt;             (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;if&lt;/span&gt;&lt;/b&gt; (&amp;gt;= (abs to) len)&lt;br /&gt;                 len&lt;br /&gt;                 (+ len to))))      &lt;br /&gt;      (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;else&lt;/span&gt;&lt;/b&gt; #f)))&lt;br /&gt;&lt;br /&gt;   (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; (&lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;generic-slicer&lt;/span&gt;&lt;/b&gt; obj from to ruler empty obj-slicer)&lt;br /&gt;     (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;let*&lt;/span&gt;&lt;/b&gt; ((len (ruler obj))&lt;br /&gt;            (from&amp;amp;to (from/to from to len))&lt;br /&gt;            (from (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; from&amp;amp;to (car from&amp;amp;to)))&lt;br /&gt;            (to (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; from&amp;amp;to (cdr from&amp;amp;to))))&lt;br /&gt;       (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;if&lt;/span&gt;&lt;/b&gt; (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; from to)&lt;br /&gt;           (obj-slicer obj from to)&lt;br /&gt;           empty)))&lt;br /&gt;&lt;br /&gt;   (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; (&lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string-slice&lt;/span&gt;&lt;/b&gt; s from to)&lt;br /&gt;     (generic-slicer s from to string-length &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;""&lt;/span&gt;&lt;/b&gt; substring))&lt;br /&gt;&lt;br /&gt;   (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; (&lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;list-slice&lt;/span&gt;&lt;/b&gt; l from to)&lt;br /&gt;     (generic-slicer l from to length '()&lt;br /&gt;                     (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;lambda&lt;/span&gt;&lt;/b&gt; (l from to)&lt;br /&gt;                       (take (drop l from) (- to from)))))&lt;br /&gt;&lt;br /&gt;   (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; (&lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;vector-slice&lt;/span&gt;&lt;/b&gt; v from to)&lt;br /&gt;     (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; (&lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;subvector&lt;/span&gt;&lt;/b&gt; vector start end)&lt;br /&gt;       (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;let&lt;/span&gt;&lt;/b&gt; ((sub (make-vector (- end start))))&lt;br /&gt;         (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;let&lt;/span&gt;&lt;/b&gt; loop ((i 0))&lt;br /&gt;           (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;if&lt;/span&gt;&lt;/b&gt; (&amp;lt; i (- end start))&lt;br /&gt;               (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;begin&lt;/span&gt;&lt;/b&gt; (vector-set! sub i (vector-ref vector (+ i start)))&lt;br /&gt;                      (loop (+ i 1)))))&lt;br /&gt;         sub))&lt;br /&gt;     (generic-slicer v from to vector-length '#() subvector))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;let&lt;/span&gt;&lt;/b&gt; ((slicers&lt;br /&gt;          (list (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;lambda&lt;/span&gt;&lt;/b&gt; (obj)&lt;br /&gt;                  (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; (string? obj)&lt;br /&gt;                       string-slice))&lt;br /&gt;                (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;lambda&lt;/span&gt;&lt;/b&gt; (obj)&lt;br /&gt;                  (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; (vector? obj)&lt;br /&gt;                       vector-slice))&lt;br /&gt;                (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;lambda&lt;/span&gt;&lt;/b&gt; (obj)&lt;br /&gt;                  (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; (list? obj)&lt;br /&gt;                       list-slice)))))&lt;br /&gt;     (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;lambda&lt;/span&gt;&lt;/b&gt; (obj #!optional from to)&lt;br /&gt;       (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;if&lt;/span&gt;&lt;/b&gt; (procedure? obj)&lt;br /&gt;           (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;set!&lt;/span&gt;&lt;/b&gt; slicers (cons obj slicers))&lt;br /&gt;           (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;let&lt;/span&gt;&lt;/b&gt; loop ((slicers slicers))&lt;br /&gt;             (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;if&lt;/span&gt;&lt;/b&gt; (null? slicers)&lt;br /&gt;                 (error &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"No slicer for the given object."&lt;/span&gt;&lt;/b&gt;)&lt;br /&gt;                 (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;let*&lt;/span&gt;&lt;/b&gt; ((slicer (car slicers))&lt;br /&gt;                        (slice (slicer obj)))&lt;br /&gt;                   (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;if&lt;/span&gt;&lt;/b&gt; slice&lt;br /&gt;                       (slice obj from to)&lt;br /&gt;                       (loop (cdr slicers)))))))))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Abaixo está o arquivo de teste do código de fatiamento (usando a extensão &lt;a href="http://chicken.wiki.br/eggref/3/test"&gt;test&lt;/a&gt;), o qual também serve como exemplo de uso.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#!/usr/bin/csi -script&lt;br /&gt;&lt;br /&gt;(use test)&lt;br /&gt;&lt;br /&gt;(load &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"slice.scm"&lt;/span&gt;&lt;/b&gt;)&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;;;;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;;;; Strings&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;;;;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;(&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;s&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"1234567"&lt;/span&gt;&lt;/b&gt;)&lt;br /&gt;&lt;br /&gt;(display &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"s = "&lt;/span&gt;&lt;/b&gt;)&lt;br /&gt;(pp s)&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;""&lt;/span&gt;&lt;/b&gt; (slice s 0 0))&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;""&lt;/span&gt;&lt;/b&gt; (slice s 1 0))&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"1"&lt;/span&gt;&lt;/b&gt; (slice s 0 1))&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;""&lt;/span&gt;&lt;/b&gt; (slice s 10 10))&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"1234567"&lt;/span&gt;&lt;/b&gt; (slice s 0 10))&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;""&lt;/span&gt;&lt;/b&gt; (slice s 10 0))&lt;br /&gt;&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"1234567"&lt;/span&gt;&lt;/b&gt; (slice s 0))&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"7"&lt;/span&gt;&lt;/b&gt; (slice s -1))&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;""&lt;/span&gt;&lt;/b&gt; (slice s 10))&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"1234567"&lt;/span&gt;&lt;/b&gt; (slice s -10))&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"4567"&lt;/span&gt;&lt;/b&gt; (slice s -4))&lt;br /&gt;&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;""&lt;/span&gt;&lt;/b&gt; (slice s -4 -4))&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"45"&lt;/span&gt;&lt;/b&gt; (slice s -4 -2))&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;""&lt;/span&gt;&lt;/b&gt; (slice s -4 -10))&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"123"&lt;/span&gt;&lt;/b&gt; (slice s -10 -4))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;;;;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;;;; Lists&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;;;;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;(&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;l&lt;/span&gt;&lt;/b&gt; '(1 2 3 4 5 6 7))&lt;br /&gt;&lt;br /&gt;(newline)&lt;br /&gt;(display &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"l = "&lt;/span&gt;&lt;/b&gt;)&lt;br /&gt;(pp l)&lt;br /&gt;&lt;br /&gt;(test '() (slice l 0 0))&lt;br /&gt;(test '() (slice l 1 0))&lt;br /&gt;(test '(1) (slice l 0 1))&lt;br /&gt;(test '(2 3) (slice l 1 3))&lt;br /&gt;(test '() (slice l 10 10))&lt;br /&gt;(test '(1 2 3 4 5 6 7) (slice l 0 10))&lt;br /&gt;(test '() (slice l 10 0))&lt;br /&gt;&lt;br /&gt;(test '(1 2 3 4 5 6 7) (slice l 0))&lt;br /&gt;(test '(7) (slice l -1))&lt;br /&gt;(test '() (slice l 10))&lt;br /&gt;(test '(1 2 3 4 5 6 7) (slice l -10))&lt;br /&gt;(test '(4 5 6 7) (slice l -4))&lt;br /&gt;&lt;br /&gt;(test '() (slice l -4 -4))&lt;br /&gt;(test '(4 5) (slice l -4 -2))&lt;br /&gt;(test '() (slice l -4 -10))&lt;br /&gt;(test '(1 2 3) (slice l -10 -4))&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;;;;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;;;; Vectors&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;;;;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;(&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;v&lt;/span&gt;&lt;/b&gt; '#(1 2 3 4 5 6 7))&lt;br /&gt;&lt;br /&gt;(newline)&lt;br /&gt;(display &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"v = "&lt;/span&gt;&lt;/b&gt;)&lt;br /&gt;(pp v)&lt;br /&gt;&lt;br /&gt;(test '#() (slice v 0 0))&lt;br /&gt;(test '#() (slice v 1 0))&lt;br /&gt;(test '#(1) (slice v 0 1))&lt;br /&gt;(test '#(2 3) (slice v 1 3))&lt;br /&gt;(test '#() (slice v 10 10))&lt;br /&gt;(test '#(1 2 3 4 5 6 7) (slice v 0 10))&lt;br /&gt;(test '#() (slice v 10 0))&lt;br /&gt;&lt;br /&gt;(test '#(1 2 3 4 5 6 7) (slice v 0))&lt;br /&gt;(test '#(7) (slice v -1))&lt;br /&gt;(test '#() (slice v 10))&lt;br /&gt;(test '#(1 2 3 4 5 6 7) (slice v -10))&lt;br /&gt;(test '#(4 5 6 7) (slice v -4))&lt;br /&gt;&lt;br /&gt;(test '#() (slice v -4 -4))&lt;br /&gt;(test '#(4 5) (slice v -4 -2))&lt;br /&gt;(test '#() (slice v -4 -10))&lt;br /&gt;(test '#(1 2 3) (slice v -10 -4))&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;;;;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;;;; Custom object&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span style="color: rgb(178, 34, 34);"&gt;;;;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;(define-record custom-string text)&lt;br /&gt;&lt;br /&gt;(&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;define&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;s&lt;/span&gt;&lt;/b&gt; (make-custom-string &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"custom string"&lt;/span&gt;&lt;/b&gt;))&lt;br /&gt;(slice (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;lambda&lt;/span&gt;&lt;/b&gt; (obj)&lt;br /&gt;        (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;and&lt;/span&gt;&lt;/b&gt; (custom-string? obj)&lt;br /&gt;             (&lt;b&gt;&lt;span style="color: rgb(160, 32, 240);"&gt;lambda&lt;/span&gt;&lt;/b&gt; (obj from to)&lt;br /&gt;               (handle-exceptions&lt;br /&gt;                exn&lt;br /&gt;                &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;""&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;                (substring (custom-string-text obj) from to))))))&lt;br /&gt;&lt;br /&gt;(newline)&lt;br /&gt;(display &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"s = "&lt;/span&gt;&lt;/b&gt;)&lt;br /&gt;(pp s)&lt;br /&gt;&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;""&lt;/span&gt;&lt;/b&gt; (slice s 0 0))&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;""&lt;/span&gt;&lt;/b&gt; (slice s 1 0))&lt;br /&gt;(test &lt;b&gt;&lt;span style="color: rgb(188, 143, 143);"&gt;"c"&lt;/span&gt;&lt;/b&gt; (slice s 0 1))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A seguir está a saída da execução do programa de teste:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;s = "1234567"&lt;br /&gt;(slice s 0 0) .................................. [ PASS]&lt;br /&gt;(slice s 1 0) .................................. [ PASS]&lt;br /&gt;(slice s 0 1) .................................. [ PASS]&lt;br /&gt;(slice s 10 10) ................................ [ PASS]&lt;br /&gt;(slice s 0 10) ................................. [ PASS]&lt;br /&gt;(slice s 10 0) ................................. [ PASS]&lt;br /&gt;(slice s 0) .................................... [ PASS]&lt;br /&gt;(slice s -1) ................................... [ PASS]&lt;br /&gt;(slice s 10) ................................... [ PASS]&lt;br /&gt;(slice s -10) .................................. [ PASS]&lt;br /&gt;(slice s -4) ................................... [ PASS]&lt;br /&gt;(slice s -4 -4) ................................ [ PASS]&lt;br /&gt;(slice s -4 -2) ................................ [ PASS]&lt;br /&gt;(slice s -4 -10) ............................... [ PASS]&lt;br /&gt;(slice s -10 -4) ............................... [ PASS]&lt;br /&gt;&lt;br /&gt;l = (1 2 3 4 5 6 7)&lt;br /&gt;(slice l 0 0) .................................. [ PASS]&lt;br /&gt;(slice l 1 0) .................................. [ PASS]&lt;br /&gt;(slice l 0 1) .................................. [ PASS]&lt;br /&gt;(slice l 1 3) .................................. [ PASS]&lt;br /&gt;(slice l 10 10) ................................ [ PASS]&lt;br /&gt;(slice l 0 10) ................................. [ PASS]&lt;br /&gt;(slice l 10 0) ................................. [ PASS]&lt;br /&gt;(slice l 0) .................................... [ PASS]&lt;br /&gt;(slice l -1) ................................... [ PASS]&lt;br /&gt;(slice l 10) ................................... [ PASS]&lt;br /&gt;(slice l -10) .................................. [ PASS]&lt;br /&gt;(slice l -4) ................................... [ PASS]&lt;br /&gt;(slice l -4 -4) ................................ [ PASS]&lt;br /&gt;(slice l -4 -2) ................................ [ PASS]&lt;br /&gt;(slice l -4 -10) ............................... [ PASS]&lt;br /&gt;(slice l -10 -4) ............................... [ PASS]&lt;br /&gt;&lt;br /&gt;v = #(1 2 3 4 5 6 7)&lt;br /&gt;(slice v 0 0) .................................. [ PASS]&lt;br /&gt;(slice v 1 0) .................................. [ PASS]&lt;br /&gt;(slice v 0 1) .................................. [ PASS]&lt;br /&gt;(slice v 1 3) .................................. [ PASS]&lt;br /&gt;(slice v 10 10) ................................ [ PASS]&lt;br /&gt;(slice v 0 10) ................................. [ PASS]&lt;br /&gt;(slice v 10 0) ................................. [ PASS]&lt;br /&gt;(slice v 0) .................................... [ PASS]&lt;br /&gt;(slice v -1) ................................... [ PASS]&lt;br /&gt;(slice v 10) ................................... [ PASS]&lt;br /&gt;(slice v -10) .................................. [ PASS]&lt;br /&gt;(slice v -4) ................................... [ PASS]&lt;br /&gt;(slice v -4 -4) ................................ [ PASS]&lt;br /&gt;(slice v -4 -2) ................................ [ PASS]&lt;br /&gt;(slice v -4 -10) ............................... [ PASS]&lt;br /&gt;(slice v -10 -4) ............................... [ PASS]&lt;br /&gt;&lt;br /&gt;s = #&amp;lt;custom-string&amp;gt;&lt;br /&gt;(slice s 0 0) .................................. [ PASS]&lt;br /&gt;(slice s 1 0) .................................. [ PASS]&lt;br /&gt;(slice s 0 1) .................................. [ PASS]&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-6633304015411074352?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/6633304015411074352/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=6633304015411074352' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6633304015411074352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6633304015411074352'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/07/fatiamento-de-sequencias-em-scheme.html' title='Fatiamento de seqüências em Scheme'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-8324880822516002906</id><published>2009-07-29T17:11:00.000-07:00</published><updated>2009-07-29T17:29:23.537-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sacanagem'/><title type='text'>Spam via telefone</title><content type='html'>Como se não bastasse a praga de spams que assola o mundo dos e-mails, há algum tempo venho recebendo propagandas não solicitadas da &lt;span style="font-weight: bold;"&gt;própria companhia telefônica&lt;/span&gt; (TIM) -- tanto através de SMS como, ultimamente, por ligações e mensagens de voz.&lt;br /&gt;&lt;br /&gt;Hoje decidi ligar para a TIM para ver se conseguia me livrar desse transtorno. O atendente me disse que não é possível desativar esse "serviço" e sugeriu que eu mandasse um e-mail para a ouvidoria TIM, cujo endereço estaria disponível no site da empresa. Quando eu disse que não faria por medo de começar a receber spam da TIM por e-mail &lt;span style="font-weight: bold;"&gt;também&lt;/span&gt;, ele mesmo deu uma risada discreta, como se estivesse pensando "&lt;span style="font-style: italic;"&gt;ele tem razão, é muita burrice fazer isso&lt;/span&gt;".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-8324880822516002906?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/8324880822516002906/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=8324880822516002906' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8324880822516002906'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8324880822516002906'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/07/spam-via-telefone.html' title='Spam via telefone'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-5915908557626950138</id><published>2009-05-21T17:02:00.001-07:00</published><updated>2009-05-21T17:10:06.052-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FURG'/><category scheme='http://www.blogger.com/atom/ns#' term='Engenharia de Computação'/><title type='text'>Do fundo do baú</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ade5bioRWEE/ShXr0wefo_I/AAAAAAAAADk/40z1_kzyPYs/s1600-h/camisa.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_ade5bioRWEE/ShXr0wefo_I/AAAAAAAAADk/40z1_kzyPYs/s320/camisa.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5338432224916120562" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ade5bioRWEE/ShXr6BjrAdI/AAAAAAAAADs/ZQjXtgfEKFw/s1600-h/sessao-coruja.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 240px; height: 320px;" src="http://3.bp.blogspot.com/_ade5bioRWEE/ShXr6BjrAdI/AAAAAAAAADs/ZQjXtgfEKFw/s320/sessao-coruja.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5338432315400585682" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Em algum outro baú, mais fundo, devo ter as apostilas dos cursos. &lt;code&gt;:-)&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-5915908557626950138?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/5915908557626950138/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=5915908557626950138' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5915908557626950138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5915908557626950138'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/05/do-fundo-do-bau.html' title='Do fundo do baú'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ade5bioRWEE/ShXr0wefo_I/AAAAAAAAADk/40z1_kzyPYs/s72-c/camisa.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-1751108953256468876</id><published>2009-05-07T19:10:00.000-07:00</published><updated>2009-05-07T19:32:39.390-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sawfish'/><title type='text'>Disparador de programas para Sawfish</title><content type='html'>Havia tempos que eu queria um disparador de aplicações para usar com o &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt;. Nunca tinha encontrado um que tivesse me agradado.  Basicamente, gostaria de um que fosse simples, permitisse completar o nome de programas com TAB, que fosse &lt;b&gt;rápido&lt;/b&gt; e &lt;b&gt;que não ocupasse muita memória&lt;/b&gt;.  Com uma rápida pesquisa na Internet, achei o código em &lt;a  href="http://www.skamphausen.de/cgi-bin/ska/download/runner.jl"&gt;http://www.skamphausen.de/cgi-bin/ska/download/runner.jl&lt;/a&gt;, o qual faz exatamente o que eu queria e satisfaz todos os meus requisitos: como é implementado em &lt;a  href="http://librep.sf.net"&gt;rep&lt;/a&gt;, não é preciso nem criar um novo processo; e a implementação é minúscula.&lt;br /&gt;&lt;br /&gt;Depois de uma leve refatorada no código, estou usando o seguinte:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(require 'prompt)&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;uniq&lt;/FONT&gt;&lt;/B&gt; l #!optional in)&lt;br /&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; Elimina replicas na lista L usando o procedimento IN para&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; verificar se um dado elemento se encontra na lista.&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((unique '()))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; loop ((l l))&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null l)&lt;br /&gt;          unique&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((head (car l)))&lt;br /&gt;            (unless ((&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; in member) head unique)&lt;br /&gt;              (setq unique (cons head unique)))&lt;br /&gt;            (loop (cdr l)))))&lt;br /&gt;    (reverse unique)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;runner&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((paths (uniq (delete-if-not file-directory-p&lt;br /&gt;         (string-split &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;:&amp;quot;&lt;/FONT&gt;&lt;/B&gt; (getenv &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;PATH&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))))&lt;br /&gt;  (completions (uniq (apply append (mapcar directory-files paths)))))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;      (interactive)&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((cmd (prompt-from-list completions &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Run: &amp;quot;&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt; t)))&lt;br /&gt; (system (concat cmd &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; &amp;amp;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))))&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;Adicionei o procedimento &lt;code&gt;uniq&lt;/code&gt; para eliminar eventuais réplicas na lista de comandos.  Ela é mais flexível que &lt;code&gt;uniquify-list&lt;/code&gt;, do &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt; (a comparação é feita exclusivamente usando &lt;code&gt;eq&lt;/code&gt;). &lt;code&gt;uniq&lt;/code&gt; aceita um argumento opcional que é o procedimento de comparação (em caso de omissão, usa &lt;code&gt;member&lt;/code&gt;).&lt;br /&gt;&lt;br /&gt;O procedimento &lt;code&gt;runner&lt;/code&gt; monta uma lista de elementos para serem usados como possíveis alternativas para completar palavras digitadas pelo usuário (&lt;i&gt;tab completion&lt;/i&gt;), a qual é usada por &lt;code&gt;prompt-from-list&lt;/code&gt;, do módulo &lt;code&gt;prompt&lt;/code&gt;. As alternativas são os arquivos nos diretórios apontados pela variável de ambiente &lt;code&gt;PATH&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Associei o procedimento &lt;code&gt;runner&lt;/code&gt; à combinação de teclas &lt;code&gt;H-RET&lt;/code&gt; (Hyper-Enter):&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(bind-keys global-keymap&lt;br /&gt;...&lt;br /&gt;   "H-RET"  (lambda () (runner))&lt;br /&gt;...)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A seguir está um &lt;i&gt;screenshot&lt;/i&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ade5bioRWEE/SgOZm2AZuII/AAAAAAAAADc/ngxzszDyS0U/s1600-h/sawfish-runner.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_ade5bioRWEE/SgOZm2AZuII/AAAAAAAAADc/ngxzszDyS0U/s320/sawfish-runner.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5333275276348078210" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;O prompt criado pelo procedimento &lt;code&gt;prompt-from-list&lt;/code&gt; define um mapa de teclas.  Assim, quando em uso, o prompt aceita as seguintes combinações de teclas associadas a procedimentos (de &lt;code&gt;prompt.jl&lt;/code&gt;, so &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(bind-keys prompt-keymap&lt;br /&gt;     "ESC" prompt-exit&lt;br /&gt;     "C-g" prompt-exit&lt;br /&gt;     "C-u" prompt-clear&lt;br /&gt;     "BS" prompt-backspace&lt;br /&gt;     "C-k" prompt-kill-line&lt;br /&gt;     "Left" prompt-backward-character&lt;br /&gt;     "C-b" prompt-backward-character&lt;br /&gt;     "Right" prompt-forward-character&lt;br /&gt;     "C-f" prompt-forward-character&lt;br /&gt;     "C-Left" prompt-backward-word&lt;br /&gt;     "M-b" prompt-backward-word&lt;br /&gt;     "A-b" prompt-backward-word&lt;br /&gt;     "C-Right" prompt-forward-word&lt;br /&gt;     "M-f" prompt-forward-word&lt;br /&gt;     "A-f" prompt-forward-word&lt;br /&gt;     "C-a" prompt-beginning-of-line&lt;br /&gt;     "C-e" prompt-end-of-line&lt;br /&gt;     "TAB" prompt-complete&lt;br /&gt;     "RET" prompt-accept&lt;br /&gt;     "Up" prompt-previous&lt;br /&gt;     "Down" prompt-next&lt;br /&gt;     "M-n" prompt-next&lt;br /&gt;     "M-p" prompt-previous&lt;br /&gt;     "A-n" prompt-next&lt;br /&gt;     "A-p" prompt-previous))&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-1751108953256468876?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/1751108953256468876/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=1751108953256468876' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1751108953256468876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1751108953256468876'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/05/disparador-de-programas-para-sawfish.html' title='Disparador de programas para Sawfish'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ade5bioRWEE/SgOZm2AZuII/AAAAAAAAADc/ngxzszDyS0U/s72-c/sawfish-runner.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-4322188799116711278</id><published>2009-04-26T08:24:00.000-07:00</published><updated>2009-04-26T09:43:44.287-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='sawfish'/><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><title type='text'>Sawfish</title><content type='html'>O &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt; é um dos softwares da lista dos que eu não gostaria de parar de usar.  Assim como o &lt;a  href="http://www.gnu.org/software/emacs"&gt;Emacs&lt;/a&gt;, é o tipo de software que, depois que se entende e aprende a usar, é difícil de largar.&lt;br /&gt;&lt;br /&gt;O &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt; durante algum tempo foi o gerenciador de janelas do ambiente de desktop &lt;a  href="http://www.gnome.org"&gt;Gnome&lt;/a&gt;. Por razões ainda não muito claras para mim, foi substituído pelo Metacity.&lt;br /&gt;&lt;br /&gt;Assim como o &lt;a  href="http://www.gnu.org/software/emacs"&gt;Emacs&lt;/a&gt;, um dos grandes diferenciais do &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt; é o fato de ser programável em uma linguagem de alto nível da família Lisp. &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt; usa a linguagem &lt;a  href="http://librep.sf.net"&gt;rep&lt;/a&gt; (&lt;b&gt;R&lt;/b&gt;ead, &lt;b&gt;E&lt;/b&gt;val, &lt;b&gt;P&lt;/b&gt;rint), a qual inicialmente foi inspirada por &lt;a  href="http://www.gnu.org/software/emacs/elisp-manual/"&gt;Elisp&lt;/a&gt; (Emacs Lisp).  A concepção do &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt; segue a mesma linha do &lt;a  href="http://www.gnu.org/software/emacs"&gt;Emacs&lt;/a&gt;: prover uma API em uma linguagem de alto nível para desenvolvimento voltado às aplicações a que se destina (&lt;b&gt;abstração&lt;/b&gt;).  Manipulação de texto no caso do &lt;a  href="http://www.gnu.org/software/emacs"&gt;Emacs&lt;/a&gt; e gerenciamento de janelas no caso do &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt;.  Com base na API de alto nível, os aplicativos são desenvolvidos.  Assim são desenvolvidos o &lt;a  href="http://www.gnu.org/software/emacs"&gt;Emacs&lt;/a&gt; e o &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt;.  A maior parte do código do &lt;a  href="http://www.gnu.org/software/emacs"&gt;Emacs&lt;/a&gt; é em &lt;a  href="http://www.gnu.org/software/emacs/elisp-manual/"&gt;Elisp&lt;/a&gt; e a maior parte do código do &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt; é em &lt;a  href="http://librep.sf.net"&gt;rep&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;O fato de prover uma API para desenvolvimento em uma linguagem de alto nível faz com que o &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt; seja altamente (e facilmente!) personalizável e extensível.  Além das possibilidades de configuração e extensão através de código em &lt;a  href="http://librep.sf.net"&gt;rep&lt;/a&gt;, &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt; também dispõe de um configurador gráfico, o qual, por baixo dos panos, apenas gera e executa código &lt;a  href="http://librep.sf.net"&gt;rep&lt;/a&gt; para configurar o gerenciador de janelas (similar à &lt;a  href="http://www.gnu.org/software/emacs/manual/html_node/emacs/Easy-Customization.html"&gt;interface para personalização do Emacs&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ade5bioRWEE/SfSPGVQQbmI/AAAAAAAAADM/xbjThDXjHTQ/s1600-h/sawfish-ui-2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 138px;" src="http://4.bp.blogspot.com/_ade5bioRWEE/SfSPGVQQbmI/AAAAAAAAADM/xbjThDXjHTQ/s320/sawfish-ui-2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5329041598033456738" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Seguindo a tradição de linguagens Lisp e de aplicativos que usam Lisp como linguagem de extensão/implementacao, &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt; também oferece um REPL para avaliação de expressões &lt;a  href="http://librep.sf.net"&gt;rep&lt;/a&gt;.  Abaixo está um exemplo de sessão com o REPL do &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ sawfish-client&lt;br /&gt;sawfish 1.3.3, Copyright (C) 1999-2000 John Harper&lt;br /&gt;sawfish comes with ABSOLUTELY NO WARRANTY; for details see the file COPYING&lt;br /&gt;&lt;br /&gt;Enter `,help' to list commands.&lt;br /&gt;user&gt; (define emacs (get-window-by-name-re "emacs.*"))&lt;br /&gt;user&gt; emacs&lt;br /&gt;#&amp;lt;window 1e00011&amp;gt;&lt;br /&gt;user&gt; (window-name emacs)&lt;br /&gt;"emacs@mandolate"&lt;br /&gt;user&gt; (window-visible-p emacs)&lt;br /&gt;t&lt;br /&gt;user&gt; (window-iconified-p emacs)&lt;br /&gt;()&lt;br /&gt;user&gt; (window-dimensions emacs)&lt;br /&gt;(798 . 742)&lt;br /&gt;user&gt; (window-border-width emacs)&lt;br /&gt;0&lt;br /&gt;user&gt; (window-framed-p emacs)&lt;br /&gt;t&lt;br /&gt;user&gt; (window-depth emacs)&lt;br /&gt;0&lt;br /&gt;user&gt; (window-absolute-position emacs)&lt;br /&gt;(68 . 0)&lt;br /&gt;user&gt; (window-sticky-p emacs)&lt;br /&gt;()&lt;br /&gt;user&gt; (move-window-to emacs 200 100)&lt;br /&gt;#&amp;lt;window 1e00011&amp;gt;&lt;br /&gt;user&gt; (window-absolute-position emacs)&lt;br /&gt;(200 . 100)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;O &lt;a  href="http://home.blarg.net/~sand/sawfish/v0.12/sawfish/"&gt;Manual de Programação do Sawfish&lt;/a&gt; documenta a API para programação e extensão do gerenciador de janelas.&lt;br /&gt;&lt;br /&gt;Abaixo está um &lt;i&gt;screenshot&lt;/i&gt; com temas pouco usuais do sawfish (cada janela pode ser decorada com um tema diferente).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ade5bioRWEE/SfR-C_bDFPI/AAAAAAAAADE/-_fKk1fr7-U/s1600-h/themes.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 256px;" src="http://1.bp.blogspot.com/_ade5bioRWEE/SfR-C_bDFPI/AAAAAAAAADE/-_fKk1fr7-U/s320/themes.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5329022848935859442" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A seguir está um exemplo de aplicação feita na linguagem de extensão do &lt;a  href="http://sawfish.wikia.com"&gt;Sawfish&lt;/a&gt;. Os aplicativos no canto superior esquerdo da tela são &lt;a  href="http://en.wikipedia.org/wiki/Dockapps"&gt;dockapps&lt;/a&gt; (&lt;a  href="http://dockapps.org/"&gt;aqui&lt;/a&gt; há vários deles).  Quando um dockapp é  executado em um gerenciador de janelas sem suporte a dock, o aplicativo é mostrado como uma janela normal, com bordas, decorações e respondendo a eventos como qualquer outra janela.  Quando o gerenciador de janelas oferece suporte a dockapps, ou quando se usa um programa externo para gerenciar dockapps, eles são mostrados como no &lt;i&gt;screenshot&lt;/i&gt; e têm comportamento diferenciado (são exibidos em todas as áreas de trabalho, não são cobertos por outras janelas quando elas são maximizadas etc).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ade5bioRWEE/SfR9gdNu4nI/AAAAAAAAAC8/corUCsRsUr4/s1600-h/sawdock.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_ade5bioRWEE/SfR9gdNu4nI/AAAAAAAAAC8/corUCsRsUr4/s320/sawdock.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5329022255637652082" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A extensão para gerenciamento de dockapps pode ser obtida em &lt;a  href="http://paginas.ucpel.tche.br/~mario/english/utils/sawdock/"&gt;http://paginas.ucpel.tche.br/~mario/english/utils/sawdock/&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-4322188799116711278?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/4322188799116711278/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=4322188799116711278' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4322188799116711278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4322188799116711278'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/04/sawfish.html' title='Sawfish'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_ade5bioRWEE/SfSPGVQQbmI/AAAAAAAAADM/xbjThDXjHTQ/s72-c/sawfish-ui-2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-495460531466369224</id><published>2009-04-24T18:54:00.000-07:00</published><updated>2009-04-24T19:04:49.962-07:00</updated><title type='text'>Criptografia simples (ingênua)</title><content type='html'>A seguir está um esquema simples de criptografia para autenticação em páginas web.  Não é um esquema seguro e não envolve chaves públicas (criptografia de chaves assimétricas).&lt;br /&gt;&lt;br /&gt;O esquema consiste em apresentar para o usuário uma matriz de números aleatórios (&lt;i&gt;puzzle&lt;/i&gt;) para que ele possa dali extrair o texto a ser enviado para ser validado. A cada acesso à pagina uma matriz aleatória nova é exibida. Somente o usuário e o software para valição de senha sabem o segredo (chave) para determinar se a senha está ou não correta.&lt;br /&gt;&lt;br /&gt;Na implementação mostrada a seguir (em &lt;a href='http://www.call-with-current-continuation.org'&gt;Chicken Scheme&lt;/a&gt;), o código para valição de senha verifica se:&lt;br /&gt;&lt;br /&gt; &lt;ul&gt;&lt;li&gt;a senha possui quatro caracteres&lt;/li&gt;&lt;br /&gt;&lt;li&gt;o primeiro caractere da senha é igual ao caractere do canto superior esquerdo da matriz de números&lt;/li&gt;&lt;br /&gt;&lt;li&gt;o segundo caractere da senha é igual ao caractere do canto superior direito da matriz de números&lt;/li&gt;&lt;br /&gt;&lt;li&gt;o terceiro caractere da senha é igual ao caractere do canto inferior esquerdo da matriz de números&lt;/li&gt;&lt;br /&gt;&lt;li&gt;o quarto caractere da senha é igual ao caractere do canto inferior direito da matriz de números&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ade5bioRWEE/SfJtruLosdI/AAAAAAAAAC0/MeMNy3Cq1cA/s1600-h/puzzle.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 225px;" src="http://3.bp.blogspot.com/_ade5bioRWEE/SfJtruLosdI/AAAAAAAAAC0/MeMNy3Cq1cA/s400/puzzle.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5328441907031355858" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ou seja, o validador verifica se a senha corresponde aos números dos quatro cantos da matriz números concatenados no sentido horário, começando pelo canto superior esquerdo.&lt;br /&gt;&lt;br /&gt;Obviamente o validador de senha é dos mais simples, mas poderia usar técnicas mais elaboradas como, por exemplo, o &lt;a href='http://en.wikipedia.org/wiki/Beale_ciphers'&gt;código de Beale&lt;/a&gt;.  Neste caso, o validador teria um texto padrão, o qual seria de conhecimento do usuário, e os números da matriz indicariam a posição das letras no texto.  Assim, o usuário digitaria as letras correspondentes às posições do texto indicadas em lugares pré-determinados da matriz (o uso da matriz é uma otimização sobre o código de Beale -- originalmente seriam apresentados apenas os números indicando a posição das letras no texto).&lt;br /&gt;&lt;br /&gt;O código de servidor web (extensão &lt;a href='http://chicken.wiki.br/eggref/3/spiffy'&gt;spiffy&lt;/a&gt; de &lt;a href='http://www.call-with-current-continuation.org'&gt;Chicken&lt;/a&gt;) está abaixo (&lt;code&gt;web-server.scm&lt;/code&gt;):&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;#!/usr/bin/csi -script&lt;br /&gt;&lt;br /&gt;(use spiffy spiffy-utils web-scheme web-scheme-handler (srfi 1 13))&lt;br /&gt;&lt;br /&gt;(spiffy-file-ext-handlers `((&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;ws&amp;quot;&lt;/FONT&gt;&lt;/B&gt; . ,web-scheme-handler)))&lt;br /&gt;(spiffy-tcp-port 8080)&lt;br /&gt;(spiffy-root-path &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;./&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;&lt;br /&gt;(start-server)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A implementação do esquema de autenticação está a seguir (&lt;code&gt;index.ws&lt;/code&gt;):&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;make-puzzle&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; Retorna uma lista de listas de numeros aleatorios entre 0 e 9&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; (inclusive 0 e 9).&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((line-length 40)&lt;br /&gt;         (num-columns 10)&lt;br /&gt;         (random-line&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;            (map (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (_) (random 10))&lt;br /&gt;                 (iota line-length)))))&lt;br /&gt;    (map (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (_)&lt;br /&gt;           (random-line))&lt;br /&gt;         (iota num-columns))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;valid-passwd?&lt;/FONT&gt;&lt;/B&gt; passwd puzzle)&lt;br /&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; Chave (ingenua): a senha corresponde aos numeros dos cantos da&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; tabela de numeros concatenados no sentido horario, comecando pelo&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; canto superior esquerdo.&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;$&lt;/FONT&gt;&lt;/B&gt; pos)&lt;br /&gt;    &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; Retorna o caractere da posicao POS em PASSWD, ou #f se POS nao&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;    &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; existir em PASSWD.&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;    (handle-exceptions exn #f (-&amp;gt;string (string-ref passwd pos))))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;check&lt;/FONT&gt;&lt;/B&gt; pw-pos key-pos)&lt;br /&gt;    (equal? ($ pw-pos) (number-&amp;gt;string key-pos)))&lt;br /&gt;    &lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; passwd&lt;br /&gt;       (= (string-length passwd) 4)&lt;br /&gt;       (check 0 (caar puzzle))&lt;br /&gt;       (check 1 (last (car puzzle)))&lt;br /&gt;       (check 2 (car (last puzzle)))&lt;br /&gt;       (check 3 (last (last puzzle)))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;auth-page&lt;/FONT&gt;&lt;/B&gt; #!optional preamble)&lt;br /&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; Pagina de autenticacao.&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  (ws:page&lt;br /&gt;   (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((puzzle (make-puzzle)))&lt;br /&gt;     (center&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; preamble (p preamble) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;      (ws:make-table puzzle)&lt;br /&gt;      (form 'method &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;post&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            (input 'type &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;hidden&amp;quot;&lt;/FONT&gt;&lt;/B&gt; 'name &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;puzzle&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                   'value (with-output-to-string (cut pp puzzle)))&lt;br /&gt;            (input 'type &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;password&amp;quot;&lt;/FONT&gt;&lt;/B&gt; 'name &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;passwd&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;            (input 'type &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;submit&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((passwd (post-var &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;passwd&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;      (puzzle (post-var &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;puzzle&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; puzzle passwd)&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (valid-passwd? passwd (with-input-from-string puzzle read))&lt;br /&gt;          (ws:page &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Senha correta&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;          (auth-page &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Senha errada!&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;      (auth-page)))&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-495460531466369224?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/495460531466369224/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=495460531466369224' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/495460531466369224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/495460531466369224'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/04/criptografia-simples-ingenua.html' title='Criptografia simples (ingênua)'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_ade5bioRWEE/SfJtruLosdI/AAAAAAAAAC0/MeMNy3Cq1cA/s72-c/puzzle.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-2178779336934276535</id><published>2009-04-24T15:47:00.000-07:00</published><updated>2009-04-24T16:05:14.259-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><title type='text'>Camiseta do projeto Chicken!</title><content type='html'>Há umas semanas, &lt;a href="http://chicken.wiki.br/users/felix-winkelmann"&gt;Felix Winkelmann&lt;/a&gt;, autor e principal desenvolvedor do projeto &lt;a href="http://www.call-with-current-continuation.org"&gt;Chicken Scheme&lt;/a&gt;, gentilmente me enviou um e-mail informando que me mandaria uma camiseta do projeto Chicken.  Hoje, para a minha felicidade, recebi a camiseta.  Muito bonita. :-)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ade5bioRWEE/SfJCkbH-JmI/AAAAAAAAACs/1uQhyPZnIQU/s1600-h/chicken-tshirt.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://4.bp.blogspot.com/_ade5bioRWEE/SfJCkbH-JmI/AAAAAAAAACs/1uQhyPZnIQU/s400/chicken-tshirt.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5328394502656632418" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Um tempo atrás tentei fazer uma camiseta dessas no site http://www.camisaonline.com.br/ mas fui roubado. Efetuei o pagamento e nunca recebi a camiseta nem resposta para os vários e-mails que enviei para o endereço de contato. Não comprem desse site.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-2178779336934276535?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/2178779336934276535/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=2178779336934276535' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2178779336934276535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2178779336934276535'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/04/camiseta-do-projeto-chicken.html' title='Camiseta do projeto Chicken!'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_ade5bioRWEE/SfJCkbH-JmI/AAAAAAAAACs/1uQhyPZnIQU/s72-c/chicken-tshirt.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-1474587348012639975</id><published>2009-03-30T19:14:00.000-07:00</published><updated>2009-03-30T19:30:21.202-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='macros'/><title type='text'>Definição de procedimentos e return explícito</title><content type='html'>A seguir está um pequeno &lt;i&gt;hack&lt;/i&gt; em &lt;a href="http://www.call-with-current-continuation.org"&gt;Chicken Scheme&lt;/a&gt; usando procedimento de escape (via &lt;code&gt;call/cc&lt;/code&gt;) e definição de macros ao estilo de Common Lisp.  No final das contas, tem-se definições de função como em &lt;a  href="http://www.python.org"&gt;Python&lt;/a&gt; ou &lt;a  href="http://www.ruby-lang.org/"&gt;Ruby&lt;/a&gt;, incluindo &lt;code&gt;return&lt;/code&gt; explícito (para os masoquistas).&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(define-macro (def procname args . body)&lt;br /&gt;  `(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (,procname ,@args)&lt;br /&gt;     (call/cc (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (return)&lt;br /&gt;                ,@body))))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Exemplo de uso (considerando programadores de linguagens cujo &lt;code&gt;if&lt;/code&gt; não passa seu resultado para a sua continuação):&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(def fatorial(n)&lt;br /&gt;     (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (&amp;lt; n 2)&lt;br /&gt;         (return 1)&lt;br /&gt;         (return (* n (fatorial (sub1 n))))))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Exemplo de uso (considerando um schemer sendo obrigado a usar &lt;code&gt;return&lt;/code&gt;):&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(def fatorial(n)&lt;br /&gt;     (return (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (&amp;lt; n 2)&lt;br /&gt;                 1&lt;br /&gt;                 (* n (fatorial (sub1 n))))))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Código equivalente em Scheme puro:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;fatorial&lt;/FONT&gt;&lt;/B&gt; n)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (&amp;lt; n 2)&lt;br /&gt;      1&lt;br /&gt;      (* n (fatorial (sub1 n)))))&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-1474587348012639975?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/1474587348012639975/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=1474587348012639975' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1474587348012639975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1474587348012639975'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2009/03/definicao-de-procedimentos-e-return.html' title='Definição de procedimentos e return explícito'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-4093919153245304662</id><published>2008-12-09T06:26:00.001-08:00</published><updated>2008-12-09T06:50:40.356-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sacanagem'/><category scheme='http://www.blogger.com/atom/ns#' term='americanas'/><title type='text'>Americanas: "inconsistências"</title><content type='html'>Há umas semanas tentei comprar um notebook das &lt;a href="http://www.americanas.com.br"&gt;Americanas&lt;/a&gt;.  Um dia após eu ter feito o pedido, recebo um e-mail pedindo para enviar dados a serem avaliados pela instituição financeira responsável pelo meu cartão de crédito. No mesmo dia respondi o e-mail com as informações solicitadas (com as mesmas informações que usei em compras feitas nas Americanas anteriormente).&lt;br /&gt;&lt;br /&gt;Dois dias depois recebo um e-mail indicando que as informações haviam sido recebidas e que a análise demoraria até 36h.  Depois de mais dois dias recebo um e-mail informando que o pedido havia sido suspenso devido a &lt;i&gt;inconsistência de informações na sua compra e também à ausência de contato nossa Central de Atendimento&lt;/i&gt;. Ressalto que respondi todas as requisições de contato e pedidos de informações que a mim chegaram.&lt;br /&gt;&lt;br /&gt;Via e-mail, tentei obter informações sobre a razão da suspensão do pedido, mas não obtive resposta.&lt;br /&gt;&lt;br /&gt;Hoje fui ver a fatura do meu cartão de crédito e percebi que o valor da parcela da compra havia sido debitado. É claro, ficou a dúvida: se as informações eram inconsistentes para efetuar a compra, &lt;b&gt;por que não eram inconsistentes para fazer a cobrança&lt;/b&gt;?&lt;br /&gt;&lt;br /&gt;Tentei fazer esta pergunta para o atendimento online das Americanas, via chat.  A conversa está abaixo (fui fazendo a captura das telas conforme a conversa se desenvolvia, pois temia que o texto fosse desaparecer quando o atentente desejasse -- o que de fato aconteceu).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ade5bioRWEE/ST6CkQnnqzI/AAAAAAAAABs/fnPWc1hrZIA/s1600-h/1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 312px; height: 400px;" src="http://1.bp.blogspot.com/_ade5bioRWEE/ST6CkQnnqzI/AAAAAAAAABs/fnPWc1hrZIA/s400/1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5277799372772846386" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ade5bioRWEE/ST6FFkdv6AI/AAAAAAAAACk/QEePDU0O47w/s1600-h/2.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 312px; height: 400px;" src="http://2.bp.blogspot.com/_ade5bioRWEE/ST6FFkdv6AI/AAAAAAAAACk/QEePDU0O47w/s400/2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5277802144059090946" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ade5bioRWEE/ST6C7XsV4HI/AAAAAAAAAB8/CYHeR0oGkig/s1600-h/3.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 312px; height: 400px;" src="http://3.bp.blogspot.com/_ade5bioRWEE/ST6C7XsV4HI/AAAAAAAAAB8/CYHeR0oGkig/s400/3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5277799769808691314" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ade5bioRWEE/ST6DCd6Zi_I/AAAAAAAAACE/X7uHt7E3LgI/s1600-h/4.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 312px; height: 400px;" src="http://3.bp.blogspot.com/_ade5bioRWEE/ST6DCd6Zi_I/AAAAAAAAACE/X7uHt7E3LgI/s400/4.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5277799891737349106" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ade5bioRWEE/ST6DJJBNWLI/AAAAAAAAACM/JtufAJgBpzo/s1600-h/5.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 312px; height: 400px;" src="http://2.bp.blogspot.com/_ade5bioRWEE/ST6DJJBNWLI/AAAAAAAAACM/JtufAJgBpzo/s400/5.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5277800006387849394" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ade5bioRWEE/ST6DPwzAcfI/AAAAAAAAACU/Fou8P7H4rZQ/s1600-h/6.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 312px; height: 400px;" src="http://4.bp.blogspot.com/_ade5bioRWEE/ST6DPwzAcfI/AAAAAAAAACU/Fou8P7H4rZQ/s400/6.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5277800120144916978" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ade5bioRWEE/ST6DWQNkodI/AAAAAAAAACc/Im8VIlDshrQ/s1600-h/7.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 312px; height: 400px;" src="http://2.bp.blogspot.com/_ade5bioRWEE/ST6DWQNkodI/AAAAAAAAACc/Im8VIlDshrQ/s400/7.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5277800231657054674" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Não consegui capturar a última tela, pois o atendente "desligou".&lt;br /&gt;&lt;br /&gt;Fica o conselho: &lt;b&gt;cautela ao comprar das Americanas&lt;/b&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-4093919153245304662?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/4093919153245304662/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=4093919153245304662' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4093919153245304662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4093919153245304662'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/12/americanas-inconsistncias.html' title='Americanas: &quot;inconsistências&quot;'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_ade5bioRWEE/ST6CkQnnqzI/AAAAAAAAABs/fnPWc1hrZIA/s72-c/1.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-4827006919143302945</id><published>2008-12-05T05:34:00.000-08:00</published><updated>2008-12-05T05:53:09.442-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cow'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Interpretador de COW em Chicken Scheme</title><content type='html'>Dando seqüência à série &lt;i&gt;implementações de interpretadores de linguagens que não servem para nada&lt;/i&gt; (iniciada com um &lt;a  href="http://call-with-hopeless-continuation.blogspot.com/2008/07/interpretador-de-assembly-em-scheme.html"&gt;interpretador de assembly&lt;/a&gt;), a seguir está a implementação de um interpretador para a &lt;a  href="http://www.bigzaphod.org/cow/"&gt;linguagem COW&lt;/a&gt; em &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; Scheme.&lt;br /&gt;&lt;br /&gt;Da página da linguagem:&lt;br /&gt;&lt;br /&gt; &lt;cite&gt;The COW programming language was designed with the bovine in mind. Given that cows have somewhat limited vocabulary skills, it seemed natural to incorporate only the words they know into the language. As a result, all instructions are some variation on "moo" which just so happens to be the only word they really understand.&lt;/cite&gt;&lt;br /&gt;&lt;br /&gt;Abaixo estão o código da implementação e um programa exemplo:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(use srfi-1)&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;*memory*&lt;/FONT&gt;&lt;/B&gt; (make-vector 1 0))&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;*program*&lt;/FONT&gt;&lt;/B&gt; #f)&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;*ip*&lt;/FONT&gt;&lt;/B&gt; 0) &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; instruction pointer&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;*mp*&lt;/FONT&gt;&lt;/B&gt; 0) &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; memory pointer&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;*register*&lt;/FONT&gt;&lt;/B&gt; #f)&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;instructions&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  '((&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;moo&amp;quot;&lt;/FONT&gt;&lt;/B&gt; . 0) (&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;mOo&amp;quot;&lt;/FONT&gt;&lt;/B&gt; . 1) (&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;moO&amp;quot;&lt;/FONT&gt;&lt;/B&gt; . 2) (&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;mOO&amp;quot;&lt;/FONT&gt;&lt;/B&gt; . 3) (&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Moo&amp;quot;&lt;/FONT&gt;&lt;/B&gt; . 4)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;MOo&amp;quot;&lt;/FONT&gt;&lt;/B&gt; . 5) (&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;MoO&amp;quot;&lt;/FONT&gt;&lt;/B&gt; . 6) (&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;MOO&amp;quot;&lt;/FONT&gt;&lt;/B&gt; . 7) (&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;OOO&amp;quot;&lt;/FONT&gt;&lt;/B&gt; . 8) (&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;MMM&amp;quot;&lt;/FONT&gt;&lt;/B&gt; . 9)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;OOM&amp;quot;&lt;/FONT&gt;&lt;/B&gt; . 10) (&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;oom&amp;quot;&lt;/FONT&gt;&lt;/B&gt; . 11)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;sanitize-code&lt;/FONT&gt;&lt;/B&gt; code)&lt;br /&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; removes non-cow instructions and returns a list containing valid cow code&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  (map string-&amp;gt;symbol&lt;br /&gt;       (filter (cut alist-ref &amp;lt;&amp;gt; instructions equal?)&lt;br /&gt;               (flatten (map string-split code)))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;get-address&lt;/FONT&gt;&lt;/B&gt; snippet from to)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((scope 0)&lt;br /&gt;        (address #f))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; loop ((code snippet))&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; (null? code) (not address))&lt;br /&gt;          (terminate)&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((current-instr (car code))&lt;br /&gt;                 (instr (cdr current-instr))&lt;br /&gt;                 (pos (car current-instr)))&lt;br /&gt;            (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;cond&lt;/FONT&gt;&lt;/B&gt; ((eq? instr from)&lt;br /&gt;                   (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; scope (add1 scope))&lt;br /&gt;                   (loop (cdr code)))&lt;br /&gt;                  ((&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; (not (zero? scope)) (eq? instr to))&lt;br /&gt;                   (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; scope (sub1 scope))&lt;br /&gt;                   (loop (cdr code)))&lt;br /&gt;                  ((&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; (zero? scope) (eq? instr to)) pos)&lt;br /&gt;                  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;else&lt;/FONT&gt;&lt;/B&gt; (loop (cdr code)))))))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;MOO-address&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (get-address (reverse (take *program* (sub1 *ip*))) 'moo 'MOO))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;moo-address&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (get-address (drop *program* (+ 2 *ip*)) 'MOO 'moo))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;mem-get&lt;/FONT&gt;&lt;/B&gt;) (vector-ref *memory* *mp*))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;maybe-resize-mem!&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((vlen (vector-length *memory*)))&lt;br /&gt;    (when (&amp;gt;= (add1 *mp*) vlen)&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; *memory* (vector-resize *memory* (add1 vlen) 0)))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;mem-set!&lt;/FONT&gt;&lt;/B&gt; val)&lt;br /&gt;  (maybe-resize-mem!)&lt;br /&gt;  (vector-set! *memory* *mp* val))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;terminate&lt;/FONT&gt;&lt;/B&gt; #!optional (exit-code 0))&lt;br /&gt;  (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Terminating.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (exit exit-code))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;moo-interpreter&lt;/FONT&gt;&lt;/B&gt; file)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((sane-code (sanitize-code (read-lines file)))&lt;br /&gt;         (program-len (length sane-code))&lt;br /&gt;         (debug? (getenv &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;COWDEBUG&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; *program* (map cons (iota program-len) sane-code))&lt;br /&gt;    (when debug? (display &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;prog&amp;gt; &amp;quot;&lt;/FONT&gt;&lt;/B&gt;) (pp *program*))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; loop ()&lt;br /&gt;      (when debug?&lt;br /&gt;        (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;-----------------------------------&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;        (print *program*)&lt;br /&gt;        (display &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;mem&amp;gt; &amp;quot;&lt;/FONT&gt;&lt;/B&gt;) (pp *memory*)&lt;br /&gt;        (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;*mp*&amp;gt; &amp;quot;&lt;/FONT&gt;&lt;/B&gt; *mp*)&lt;br /&gt;        (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;*ip*&amp;gt; &amp;quot;&lt;/FONT&gt;&lt;/B&gt; *ip*)&lt;br /&gt;        (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;*register*&amp;gt;  &amp;quot;&lt;/FONT&gt;&lt;/B&gt; *register*))&lt;br /&gt;      (when (&amp;gt; *ip* program-len) (terminate))&lt;br /&gt;        (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? *program*)&lt;br /&gt;            (terminate)&lt;br /&gt;            (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((current-instr (alist-ref *ip* *program*))&lt;br /&gt;                   &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; special-instr =&amp;gt; instructions that modify *ip*&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;                   (special-instrs '(MOO mOO moo))&lt;br /&gt;                   (special-instr? (memq current-instr special-instrs)))&lt;br /&gt;              (when (eq? current-instr 'mOO)&lt;br /&gt;                (unless (memq (mem-get) (map cdr instructions))&lt;br /&gt;                  (terminate))&lt;br /&gt;                (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; current-instr (alist-ref (mem-get) *program*))&lt;br /&gt;                (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; special-instr? (memq current-instr special-instrs)))&lt;br /&gt;              (when debug?&lt;br /&gt;                (display &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;current-instr&amp;gt; &amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;                (display (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; special-instr? &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;(*) &amp;quot;&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;                (pp  current-instr))&lt;br /&gt;              (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;case&lt;/FONT&gt;&lt;/B&gt; current-instr&lt;br /&gt;                ((moo) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; *ip* (MOO-address)))&lt;br /&gt;                ((mOo) (maybe-resize-mem!) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; *mp* (sub1 *mp*)))&lt;br /&gt;                ((moO) (maybe-resize-mem!) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; *mp* (add1 *mp*)))&lt;br /&gt;                ((Moo) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (zero? (mem-get))&lt;br /&gt;                           (mem-set! (string-&amp;gt;number (-&amp;gt;string (read-line))))&lt;br /&gt;                           (print (integer-&amp;gt;char (mem-get)))))&lt;br /&gt;                ((MOo) (mem-set! (sub1 (mem-get))))&lt;br /&gt;                ((MoO) (mem-set! (add1 (mem-get))))&lt;br /&gt;                ((MOO) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (zero? (mem-get))&lt;br /&gt;                           (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; *ip* (add1 (moo-address)))&lt;br /&gt;                           (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; *ip* (add1 *ip*))))&lt;br /&gt;                ((OOO) (mem-set! 0))&lt;br /&gt;                ((MMM) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; *register*&lt;br /&gt;                           (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;begin&lt;/FONT&gt;&lt;/B&gt; (mem-set! *register*)&lt;br /&gt;                                  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; *register* #f))&lt;br /&gt;                           (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; *register* (mem-get))))&lt;br /&gt;                ((OOM) (print (mem-get)))&lt;br /&gt;                ((oom) (mem-set! (string-&amp;gt;number (read-line)))))&lt;br /&gt;              (unless special-instr? (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; *ip* (add1 *ip*)))))&lt;br /&gt;        (loop))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;usage&lt;/FONT&gt;&lt;/B&gt; #!optional (exit-code 0))&lt;br /&gt;  (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Usage: &amp;quot;&lt;/FONT&gt;&lt;/B&gt; (program-name) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; &amp;lt;input file&amp;gt;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (exit exit-code))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((args (command-line-arguments)))&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? args)&lt;br /&gt;      (usage 1)&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((file (car args)))&lt;br /&gt;        (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (file-exists? (car args))&lt;br /&gt;            (moo-interpreter file)&lt;br /&gt;            (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;begin&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;              (print file &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;: not found.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;              (exit 1))))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Obs.: se a variável &lt;code&gt;COWDEBUG&lt;/code&gt; estiver definida no ambiente, o interpretador exibe informações para depuração.&lt;br /&gt;&lt;br /&gt;Aqui está a implementação de um gerador da &lt;a  href="http://en.wikipedia.org/wiki/Fibonacci_number"&gt;série de Fibonacci&lt;/a&gt; em COW (um dos exemplos disponibilizados no site da linguagem):&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;MoO&lt;br /&gt;moO&lt;br /&gt;MoO&lt;br /&gt;mOo&lt;br /&gt;[[ main loop ]]&lt;br /&gt;MOO&lt;br /&gt;[[ print first number ]]&lt;br /&gt;OOM&lt;br /&gt;[[ temp copy of first number ]]&lt;br /&gt;MMM&lt;br /&gt;moO&lt;br /&gt;moO&lt;br /&gt;MMM&lt;br /&gt;mOo&lt;br /&gt;mOo&lt;br /&gt;[[ store second number off in the first position now ]]&lt;br /&gt;moO&lt;br /&gt;MMM&lt;br /&gt;mOo&lt;br /&gt;MMM&lt;br /&gt;[[ move back to temp number ]]&lt;br /&gt;moO&lt;br /&gt;moO&lt;br /&gt;[[ use temp to add to first and store in second in loop ]]&lt;br /&gt;MOO&lt;br /&gt;MOo&lt;br /&gt;mOo&lt;br /&gt;MoO&lt;br /&gt;moO&lt;br /&gt;moo&lt;br /&gt;mOo&lt;br /&gt;mOo&lt;br /&gt;moo&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Executando este exemplo com o interpretador, temos:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ csi -s cow.scm fib.cow&lt;br /&gt;1&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;5&lt;br /&gt;8&lt;br /&gt;13&lt;br /&gt;21&lt;br /&gt;34&lt;br /&gt;55&lt;br /&gt;89&lt;br /&gt;144&lt;br /&gt;233&lt;br /&gt;377&lt;br /&gt;610&lt;br /&gt;987&lt;br /&gt;1597&lt;br /&gt;2584&lt;br /&gt;4181&lt;br /&gt;6765&lt;br /&gt;10946&lt;br /&gt;17711&lt;br /&gt;28657&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Algum voluntário para implementar as &lt;a  href="http://www.bigzaphod.org/cow/ddx/ddx.txt"&gt;Distributed Digestion eXtentions&lt;/a&gt;? &lt;code&gt;:-)&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-4827006919143302945?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/4827006919143302945/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=4827006919143302945' title='3 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4827006919143302945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4827006919143302945'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/12/interpretador-de-cow-em-chicken-scheme.html' title='Interpretador de COW em Chicken Scheme'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-7032765682159394632</id><published>2008-11-19T06:04:00.000-08:00</published><updated>2008-11-19T06:18:19.002-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Scheme na Apple?</title><content type='html'>Estava dando uma olhada em uma &lt;a href="http://www.usenix.org/events/lisa08/tech/hubbard_talk.pdf"&gt;apresentação sobre o MacOSX&lt;/a&gt; que o &lt;a href="http://japao.drebes.org/"&gt;Drebes&lt;/a&gt; divulgou em uma lista de discussão e me deparei com a seguinte tela:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ade5bioRWEE/SSQfk5MTqfI/AAAAAAAAABk/fgDPm5mMbGM/s1600-h/hubbard.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 315px;" src="http://1.bp.blogspot.com/_ade5bioRWEE/SSQfk5MTqfI/AAAAAAAAABk/fgDPm5mMbGM/s400/hubbard.png" alt="" id="BLOGGER_PHOTO_ID_5270372182618515954" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Com uma rápida pesquisada, encontrei o seguinte &lt;a href="http://www.usefulsecurity.com/2007/11/apple-sandboxes-part-1/"&gt;texto&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;cite&gt;&lt;br /&gt;While there is no documentation of the format of the policy file, there are several examples available in /usr/share/sandbox which give clues to what a policy can do. These policies seem to use a &lt;b&gt;Scheme-like syntax&lt;/b&gt; and provide abilities to restrict file access (based on pathname), restrict interprocess communication (IPC) such as shared memory, restrict network access, restrict signals, restrict many process-related actions, restrict sysctls, and more.&lt;br /&gt;&lt;/cite&gt;&lt;br /&gt;&lt;br /&gt;Interessante.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-7032765682159394632?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/7032765682159394632/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=7032765682159394632' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7032765682159394632'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7032765682159394632'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/11/scheme-na-apple.html' title='Scheme na Apple?'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_ade5bioRWEE/SSQfk5MTqfI/AAAAAAAAABk/fgDPm5mMbGM/s72-c/hubbard.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-161131117797411493</id><published>2008-10-28T11:30:00.000-07:00</published><updated>2008-10-28T11:34:49.704-07:00</updated><title type='text'>Chicken LiveCD na LatinoWare 2008</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ade5bioRWEE/SQdbD_beW4I/AAAAAAAAABU/xsarsIi8S3k/s1600-h/livecd.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_ade5bioRWEE/SQdbD_beW4I/AAAAAAAAABU/xsarsIi8S3k/s320/livecd.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5262274813730118530" /&gt;&lt;/a&gt;&lt;br /&gt;Como não será possível levar a &lt;a href="http://qdp.ucpel.tche.br"&gt;torradeira&lt;/a&gt; para a Latinoware 2008, levarei alguns &lt;a href="http://chicken.wiki.br/livecd"&gt;LiveCDs&lt;/a&gt; de &lt;a href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; para os interessados.  Serão poucas unidades (~20). Faça sua reserva na seção de comentários. :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-161131117797411493?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/161131117797411493/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=161131117797411493' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/161131117797411493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/161131117797411493'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/10/chicken-livecd-na-latinoware-2008.html' title='Chicken LiveCD na LatinoWare 2008'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_ade5bioRWEE/SQdbD_beW4I/AAAAAAAAABU/xsarsIi8S3k/s72-c/livecd.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-6552662593556379437</id><published>2008-10-22T04:39:00.000-07:00</published><updated>2008-10-22T04:59:11.186-07:00</updated><title type='text'>Chicken LiveCD 0.4</title><content type='html'>A versão 0.4 do &lt;a href="http://chicken.wiki.br/livecd"&gt;Chicken LiveCD&lt;/a&gt; está disponível em &lt;a href="http://g3pd.ufpel.tche.br/chicken/livecd/"&gt;http://g3pd.ufpel.tche.br/chicken/livecd/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Esta versão contém:&lt;br /&gt;&lt;br /&gt;&lt;ul style="margin-top: 0px; margin-bottom=0px; padding-top=0; padding-bottom=0;"&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://chicken.wiki.br/releases"&gt;Chicken 3.4.0&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;mais de 300 &lt;a href="http://chicken.wiki.br/eggs"&gt;eggs&lt;/a&gt; instalados&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.gnu.org/software/emacs"&gt;Emacs&lt;/a&gt; + &lt;a href="http://www.neilvandyke.org/quack/"&gt;Quack&lt;/a&gt; + &lt;a href="http://synthcode.com/emacs/"&gt;scheme-complete&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://chicken.wiki.br/releases"&gt;Manual em PDF&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;várias ferramentas e bibliotecas para desenvolvimento com Chicken&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Esta versão do LiveCD é baseada no &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt;.  Usei o &lt;a href="http://reconstructor.aperantis.com/"&gt;Reconstructor&lt;/a&gt; para remasterizar o CD.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ade5bioRWEE/SP8TRqROU-I/AAAAAAAAABM/fYfxcp6IRDQ/s1600-h/3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_ade5bioRWEE/SP8TRqROU-I/AAAAAAAAABM/fYfxcp6IRDQ/s320/3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5259944083917263842" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-6552662593556379437?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/6552662593556379437/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=6552662593556379437' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6552662593556379437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6552662593556379437'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/10/chicken-livecd-04.html' title='Chicken LiveCD 0.4'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ade5bioRWEE/SP8TRqROU-I/AAAAAAAAABM/fYfxcp6IRDQ/s72-c/3.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-146956148375471343</id><published>2008-10-20T12:06:00.000-07:00</published><updated>2008-10-20T12:17:38.875-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Correctly answer a simple skill testing question</title><content type='html'>Ainda não decidi se devo chorar ou dar risada:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ade5bioRWEE/SPzXmRdaxqI/AAAAAAAAABE/JzHOccU05zY/s1600-h/scheme-workshop.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_ade5bioRWEE/SPzXmRdaxqI/AAAAAAAAABE/JzHOccU05zY/s400/scheme-workshop.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5259315517383689890" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Há uma &lt;a href="http://groups.google.com/group/plt-scheme/browse_thread/thread/efe7a75333c6328/f64a0fd4f117ff14?pli=1"&gt;thread na lista de discussão da implementação PLT&lt;/a&gt; com a discussão gerada por uma &lt;a href="http://www.google.com/search?hl=en&amp;q=%22scheme+is+simple%22+programming"&gt;&lt;b&gt;simples questão&lt;/b&gt;&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-146956148375471343?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/146956148375471343/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=146956148375471343' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/146956148375471343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/146956148375471343'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/10/correctly-answer-simple-skill-testing.html' title='Correctly answer a simple skill testing question'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ade5bioRWEE/SPzXmRdaxqI/AAAAAAAAABE/JzHOccU05zY/s72-c/scheme-workshop.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-4334806054595402741</id><published>2008-10-17T13:50:00.000-07:00</published><updated>2008-10-17T14:09:49.379-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='latinoware'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Lisp na LatinoWare 2008!</title><content type='html'>A &lt;a href="http://2008.latinoware.org"&gt;LatinoWare 2008&lt;/a&gt;, V Conferência Latino-Americana de Software Livre, que ocorrerá de 30 de outubro a 1&lt;sup&gt;o&lt;/sup&gt;. de novembro em Foz do Iguaçu, PR, contará com três apresentações especificamente sobre Lisp!  Serão 3 horas consecutivas sobre parênteses no dia 31/10/2008:&lt;br /&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;15h-16h&lt;/td&gt;&lt;td&gt;Usando Common Lisp no Dia-a-dia&lt;/td&gt;&lt;td&gt;&lt;a href="http://kroger.lisp-br.org/index-en.html"&gt;Pedro Ribeiro Kroger Junior&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;16h-17h&lt;/td&gt;&lt;td&gt;Chicken - Uma Implementação de Scheme para Aplicações Práticas&lt;/td&gt;&lt;td&gt;&lt;a href="http://paginas.ucpel.tche.br/~mario"&gt;Mario Domenech Goulart&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;17h-18h&lt;/td&gt;&lt;td&gt;CL-Weblocks - Programando Aplicações Web com Blocos&lt;/td&gt;&lt;td&gt;&lt;a href="http://vilson.void.cc"&gt;Vilson Vieira da Silva Junior&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;A programação completa do evento está em &lt;a href="http://lapsi.latinoware.org/index.php?page=grade.GradeEvento&amp;id=1"&gt;http://lapsi.latinoware.org/index.php?page=grade.GradeEvento&amp;id=1&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-4334806054595402741?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/4334806054595402741/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=4334806054595402741' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4334806054595402741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4334806054595402741'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/10/lisp-na-latinoware-2008.html' title='Lisp na LatinoWare 2008!'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-6826503713664660458</id><published>2008-09-04T06:15:00.000-07:00</published><updated>2008-09-04T06:32:34.863-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ldap'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Interface para manipulação de grupos no LDAP</title><content type='html'>A seguir está uma simples, rápida e não muito elegante interface para manipulação de grupos de usuários no &lt;a  href="http://tools.ietf.org/html/rfc4510"&gt;LDAP&lt;/a&gt; (&lt;i&gt;Lightweight Directory Access Protocol&lt;/i&gt;) que usa o programa &lt;a  href="http://cpu.sourceforge.net/"&gt;cpu&lt;/a&gt; por baixo dos panos. A implementação é em &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; Scheme.&lt;br /&gt;&lt;br /&gt; Com esta ferramenta são possíveis as seguintes operações:&lt;br /&gt;&lt;br /&gt; &lt;ul&gt;&lt;li&gt;Listar grupos aos quais um dado usuário pertence&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Listar usuários que fazem parte de um dado grupo&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Adicionar usuário a grupo&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt; Exemplos:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;$ ldap-groups.scm -h&lt;br /&gt;Uso: ldap-groups.scm -h | -a &amp;lt;user&amp;gt; &amp;lt;group&amp;gt; | -l &amp;lt;group&amp;gt; | -g &amp;lt;user&amp;gt;&lt;br /&gt;&lt;br /&gt;-a : adiciona &amp;lt;user&amp;gt; ao grupo &amp;lt;group&amp;gt; (cria &amp;lt;group&amp;gt; se nao existir)&lt;br /&gt;-l : lista os usuarios do grupo &amp;lt;group&amp;gt;&lt;br /&gt;-g : lista os grupos a que pertence o usuario &amp;lt;user&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Listando os usuários do grupo &lt;code&gt;admin&lt;/code&gt;:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;$ ldap-groups.scm -l admin&lt;br /&gt;mario&lt;br /&gt;joao&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Listando os grupos a que pertenço:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;$ ldap-groups.scm -g mario&lt;br /&gt;sgpc&lt;br /&gt;admin&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Adicionando o meu usuário ao grupo &lt;code&gt;printer&lt;/code&gt;:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;$ ldap-groups.scm -a mario printer&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; O código está abaixo:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(use posix srfi-13)&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;system-output&lt;/FONT&gt;&lt;/B&gt; . command)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((cmd (string-intersperse (map -&amp;gt;string command))))&lt;br /&gt;    (read-all (open-input-pipe (sprintf &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;~A 2&amp;gt;&amp;amp;1&amp;quot;&lt;/FONT&gt;&lt;/B&gt; cmd)))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;*groups-data*&lt;/FONT&gt;&lt;/B&gt; #f)&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;set-groups-data!&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; *groups-data*&lt;br /&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; lista de listas ((&amp;quot;grupo&amp;quot; &amp;quot;user1&amp;quot; &amp;quot;user2&amp;quot; ... &amp;quot;usern&amp;quot;))&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;        (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((data (with-input-from-string&lt;br /&gt;                        (cadr (string-split-fields&lt;br /&gt;                               &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Group Entries\n&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                               (system-output &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;cpu cat&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;                               infix:))&lt;br /&gt;                      read-lines)))&lt;br /&gt;          (map (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (line)&lt;br /&gt;                 (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((ldata (string-split line &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;:&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;                   (cons (car ldata) &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; nome do grupo&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;                         (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((users (cdddr ldata))) &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; usuarios&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;                           (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? users)&lt;br /&gt;                               '()&lt;br /&gt;                               (map&lt;br /&gt;                                string-trim-both&lt;br /&gt;                                (string-split (car users) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;,&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))))))&lt;br /&gt;               data))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;get-groups&lt;/FONT&gt;&lt;/B&gt; user)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((user-groups '()))&lt;br /&gt;    (for-each (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (group/users)&lt;br /&gt;                (when (member user (cdr group/users))&lt;br /&gt;                  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; user-groups&lt;br /&gt;                        (cons (car group/users) user-groups))))&lt;br /&gt;              *groups-data*)&lt;br /&gt;    user-groups))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;group-exists?&lt;/FONT&gt;&lt;/B&gt; group)&lt;br /&gt;  (not (not (alist-ref group *groups-data* equal?))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;get-users&lt;/FONT&gt;&lt;/B&gt; group)&lt;br /&gt;  (alist-ref group *groups-data* equal?))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;add-user-to-group!&lt;/FONT&gt;&lt;/B&gt; user group)&lt;br /&gt;  (unless (group-exists? group)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((cmd (conc &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;cpu groupadd &amp;quot;&lt;/FONT&gt;&lt;/B&gt; group)))&lt;br /&gt;      (print cmd)&lt;br /&gt;      (system-output cmd)))&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((cmd (conc &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;cpu usermod &amp;quot;&lt;/FONT&gt;&lt;/B&gt; user &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; -G &amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                   (string-intersperse&lt;br /&gt;                    (cons group (get-groups user)) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;,&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;br /&gt;    (print cmd)&lt;br /&gt;    (system-output cmd)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;usage&lt;/FONT&gt;&lt;/B&gt; #!optional exit-code)&lt;br /&gt;  (print #&amp;lt;#EOF&lt;br /&gt;Uso: #(program-name) -h | -a &amp;lt;user&amp;gt; &amp;lt;group&amp;gt; | -l &amp;lt;group&amp;gt; | -g &amp;lt;user&amp;gt;&lt;br /&gt;&lt;br /&gt;-a &lt;B&gt;&lt;FONT COLOR="#5F9EA0"&gt;:&lt;/FONT&gt;&lt;/B&gt; adiciona &amp;lt;user&amp;gt; ao grupo &amp;lt;group&amp;gt; (cria &amp;lt;group&amp;gt; se nao existir)&lt;br /&gt;-l &lt;B&gt;&lt;FONT COLOR="#5F9EA0"&gt;:&lt;/FONT&gt;&lt;/B&gt; lista os usuarios &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;do&lt;/FONT&gt;&lt;/B&gt; grupo &amp;lt;group&amp;gt;&lt;br /&gt;-g &lt;B&gt;&lt;FONT COLOR="#5F9EA0"&gt;:&lt;/FONT&gt;&lt;/B&gt; lista os grupos a que pertence o usuario &amp;lt;user&amp;gt;&lt;br /&gt;EOF&lt;br /&gt;)&lt;br /&gt;  (when exit-code&lt;br /&gt;    (exit exit-code)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((args (command-line-arguments)))&lt;br /&gt;  (when (null? args)&lt;br /&gt;    (usage 1))&lt;br /&gt;  (set-groups-data!)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;cond&lt;/FONT&gt;&lt;/B&gt; ((member (car args) '(&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;-h&amp;quot;&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;--help&amp;quot;&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;-help&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;         (usage))&lt;br /&gt;        ((member &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;-a&amp;quot;&lt;/FONT&gt;&lt;/B&gt; args)&lt;br /&gt;         (add-user-to-group! (cadr args) (caddr args)))&lt;br /&gt;        ((member &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;-l&amp;quot;&lt;/FONT&gt;&lt;/B&gt; args)&lt;br /&gt;         (map print (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; (get-users (cadr args)) '())))&lt;br /&gt;        ((member &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;-g&amp;quot;&lt;/FONT&gt;&lt;/B&gt; args)&lt;br /&gt;         (map print (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; (get-groups (cadr args)) '())))&lt;br /&gt;        (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;else&lt;/FONT&gt;&lt;/B&gt; (usage 1))))&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-6826503713664660458?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/6826503713664660458/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=6826503713664660458' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6826503713664660458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6826503713664660458'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/09/interface-para-manipulao-de-grupos-no.html' title='Interface para manipulação de grupos no LDAP'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-1951392417746440187</id><published>2008-08-11T14:13:00.000-07:00</published><updated>2008-08-12T05:18:01.922-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Configurando o tamanho do stack trace</title><content type='html'>&lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; dispõe de uma opção para configurar o tamanho do relatório de chamadas de procedimentos (&lt;i&gt;stack trace&lt;/i&gt;) a ser exibido em caso de erro.  Se a configuração for omitida, o valor 8 é usado, o que significa que serão exibidas as últimas 8 chamadas de procedimento.&lt;br /&gt;&lt;br /&gt; Para algumas aplicações, esse número pode ser muito pequeno, mas pode ser aumentado com o parâmetro &lt;code&gt;-:aNUMBER&lt;/code&gt;, onde &lt;code&gt;NUMBER&lt;/code&gt; é o número de chamadas a ser mostrado (&lt;a  href="http://chicken.wiki.br/Using%20the%20compiler#runtime-options"&gt;http://chicken.wiki.br/Using%20the%20compiler#runtime-options&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt; Abaixo está um exemplo de uma situação onde o aumento do &lt;i&gt;stack trace&lt;/i&gt; pode ser útil:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;l&lt;/FONT&gt;&lt;/B&gt;) (error 'oops))&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;k&lt;/FONT&gt;&lt;/B&gt;) (l))&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;j&lt;/FONT&gt;&lt;/B&gt;) (k))&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;i&lt;/FONT&gt;&lt;/B&gt;) (j))&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;h&lt;/FONT&gt;&lt;/B&gt;) (i))&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;g&lt;/FONT&gt;&lt;/B&gt;) (h))&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;f&lt;/FONT&gt;&lt;/B&gt;) (g))&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;e&lt;/FONT&gt;&lt;/B&gt;) (f))&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;d&lt;/FONT&gt;&lt;/B&gt;) (e))&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;c&lt;/FONT&gt;&lt;/B&gt;) (d))&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;b&lt;/FONT&gt;&lt;/B&gt;) (c))&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;a&lt;/FONT&gt;&lt;/B&gt;) (b))&lt;br /&gt;&lt;br /&gt;(a)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Executando este código com o interpretador, temos:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;$ csi -s oops.scm&lt;br /&gt;Error: oops&lt;br /&gt;&lt;br /&gt;        Call history:&lt;br /&gt;&lt;br /&gt;        &lt;eval&gt;          [e] (f)&lt;br /&gt;        &lt;eval&gt;          [f] (g)&lt;br /&gt;        &lt;eval&gt;          [g] (h)&lt;br /&gt;        &lt;eval&gt;          [h] (i)&lt;br /&gt;        &lt;eval&gt;          [i] (j)&lt;br /&gt;        &lt;eval&gt;          [j] (k)&lt;br /&gt;        &lt;eval&gt;          [k] (l)&lt;br /&gt;        &lt;eval&gt;          [l] (error (quote oops))        &lt;--&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Com esse relatório, não fica claro que quem originou a chamada de &lt;code&gt;l&lt;/code&gt; foi &lt;code&gt;a&lt;/code&gt;. Mas, se aumentarmos o tamanho do relatório:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;$ csi -:a14 -s oops.scm&lt;br /&gt;Error: oops&lt;br /&gt;&lt;br /&gt;        Call history:&lt;br /&gt;&lt;br /&gt;        &lt;syntax&gt;                (a)&lt;br /&gt;        &lt;eval&gt;          (a)&lt;br /&gt;        &lt;eval&gt;          [a] (b)&lt;br /&gt;        &lt;eval&gt;          [b] (c)&lt;br /&gt;        &lt;eval&gt;          [c] (d)&lt;br /&gt;        &lt;eval&gt;          [d] (e)&lt;br /&gt;        &lt;eval&gt;          [e] (f)&lt;br /&gt;        &lt;eval&gt;          [f] (g)&lt;br /&gt;        &lt;eval&gt;          [g] (h)&lt;br /&gt;        &lt;eval&gt;          [h] (i)&lt;br /&gt;        &lt;eval&gt;          [i] (j)&lt;br /&gt;        &lt;eval&gt;          [j] (k)&lt;br /&gt;        &lt;eval&gt;          [k] (l)&lt;br /&gt;        &lt;eval&gt;          [l] (error (quote oops))        &lt;--&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; O parâmetro &lt;code&gt;-:aNUMBER&lt;/code&gt; também é válido para programas compilados com o compilador de Chicken (&lt;a  href="http://chicken.wiki.br/Using%20the%20compiler"&gt;&lt;code&gt;csc&lt;/code&gt;&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;$ csc oops.scm&lt;br /&gt;$ ./oops&lt;br /&gt;Error: oops&lt;br /&gt;&lt;br /&gt;        Call history:&lt;br /&gt;&lt;br /&gt;        oops.scm: 8    f&lt;br /&gt;        oops.scm: 7    g&lt;br /&gt;        oops.scm: 6    h&lt;br /&gt;        oops.scm: 5    i&lt;br /&gt;        oops.scm: 4    j&lt;br /&gt;        oops.scm: 3    k&lt;br /&gt;        oops.scm: 2    l&lt;br /&gt;        oops.scm: 1    error                    &lt;--&lt;br /&gt;&lt;br /&gt;$ ./oops -:a14&lt;br /&gt;Error: oops&lt;br /&gt;&lt;br /&gt;        Call history:&lt;br /&gt;&lt;br /&gt;        oops.scm: 14   a&lt;br /&gt;        oops.scm: 12   b&lt;br /&gt;        oops.scm: 11   c&lt;br /&gt;        oops.scm: 10   d&lt;br /&gt;        oops.scm: 9    e&lt;br /&gt;        oops.scm: 8    f&lt;br /&gt;        oops.scm: 7    g&lt;br /&gt;        oops.scm: 6    h&lt;br /&gt;        oops.scm: 5    i&lt;br /&gt;        oops.scm: 4    j&lt;br /&gt;        oops.scm: 3    k&lt;br /&gt;        oops.scm: 2    l&lt;br /&gt;        oops.scm: 1    error                    &lt;--&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-1951392417746440187?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/1951392417746440187/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=1951392417746440187' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1951392417746440187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1951392417746440187'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/08/configurando-o-tamanho-do-stack-trace.html' title='Configurando o tamanho do stack trace'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-7731380279223882853</id><published>2008-08-06T08:54:00.001-07:00</published><updated>2008-08-06T09:17:15.269-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='repl'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Chicken Web REPL</title><content type='html'>Há algum tempo eu e o &lt;a  href="http://vilson.void.cc/"&gt;Vilson&lt;/a&gt; estávamos discutindo sobre REPLs na Web (não lembro o que desencadeou esse tópico -- também é possível que o tópico não tenha sido esse -- tá feio o caso da minha memória). Bem, o fato é que desta conversa surgiu a idéia de fazer um REPL via Web para &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt;. Lembrei do egg &lt;a  href="http://www.call-with-current-continuation.org/eggs/3/sandbox.html"&gt;sandbox&lt;/a&gt;, do &lt;a  href="http://chicken.wiki.br/playground"&gt;Chicken Playground&lt;/a&gt; (um ambiente chroot com uma instalação de &lt;a  href="http://www.debian.org"&gt;Debian&lt;/a&gt;, &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; e um monte de &lt;a  href="http://chicken.wiki.br/eggs"&gt;eggs&lt;/a&gt;) e fiz um Web REPL simples para Chicken.&lt;br /&gt;&lt;br /&gt; Em seguida, o Vilson descobriu o &lt;a  href="http://www.cdolivet.net/editarea/"&gt;EditArea&lt;/a&gt; (um editor de código em Javascript) e modificou para adicionar um suporte básico a Common Lisp.  Enviou o código para mim e eu, com base nele, adicionei suporte básico a Scheme.&lt;br /&gt;&lt;br /&gt; O resultado está em &lt;a  href="http://repl.ucpel.tche.br:8080"&gt;http://repl.ucpel.tche.br:8080&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ade5bioRWEE/SJnKWrc6VDI/AAAAAAAAAAU/t5Sa0yv7Ytc/s1600-h/web-repl.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_ade5bioRWEE/SJnKWrc6VDI/AAAAAAAAAAU/t5Sa0yv7Ytc/s320/web-repl.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5231434933137462322" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt; Uma das funcionalidades interessantes do Web REPL é o uso de sessões HTTP para manter coisas como histórico de trechos de código submetidos ao avaliador e definições feitas na sessão.  A implementação de sessões é feita com o egg &lt;a  href="http://chicken.wiki.br/http-session"&gt;http-session&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;O Web REPL também usa os eggs &lt;a  href="http://chicken.wiki.br/web-scheme"&gt;web-scheme&lt;/a&gt;, &lt;a  href="http://www.call-with-current-continuation.org/eggs/3/ajax.html"&gt;ajax&lt;/a&gt;, &lt;a  href="http://www.call-with-current-continuation.org/eggs/3/spiffy-utils.html"&gt;spiffy-utils&lt;/a&gt; e &lt;a  href="http://chicken.wiki.br/spiffy"&gt;spiffy&lt;/a&gt; (servidor web).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-7731380279223882853?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/7731380279223882853/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=7731380279223882853' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7731380279223882853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7731380279223882853'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/08/chicken-web-repl.html' title='Chicken Web REPL'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_ade5bioRWEE/SJnKWrc6VDI/AAAAAAAAAAU/t5Sa0yv7Ytc/s72-c/web-repl.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-901579252181802714</id><published>2008-08-06T08:15:00.000-07:00</published><updated>2008-08-06T08:26:48.675-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><title type='text'>REPL de Chicken para acesso a bases de dados do Postgres</title><content type='html'>A seguir está uma forma de usar o REPL de &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; (&lt;a  href="http://chicken.wiki.br/Using%20the%20interpreter"&gt;csi&lt;/a&gt;) como um REPL para bases de dados do &lt;a  href="http://www.postgresql.org/"&gt;Postgres&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt; Com isso, tem-se um REPL que possibilita a execução de consultas SQL e código Scheme.  A implementação usa o próprio REPL do sistema &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; e alguns &lt;a  href="http://chicken.wiki.br/eggs"&gt;eggs&lt;/a&gt; como: &lt;a  href="http://chicken.wiki.br/postgresql"&gt;postgresql&lt;/a&gt; (para acesso so Postgres), &lt;a  href="http://chicken.wiki.br/readline"&gt;readline&lt;/a&gt; (para edição de linhas de comando, histórico) e &lt;a  href="http://chicken.wiki.br/stty"&gt;stty&lt;/a&gt; (para configuração do terminal na leitura de senhas).&lt;br /&gt;&lt;br /&gt; O programa &lt;code&gt;db-repl.scm&lt;/code&gt; usa como argumentos não interativos (opcionais) o usuário do banco de dados, o nome do host e a base de dados, os quais devem ser fornecidos no seguinte formato:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&amp;lt;usuario&amp;gt;@&amp;lt;host&amp;gt;/&amp;lt;base de dados&amp;gt;&lt;/pre&gt;&lt;br /&gt; Quando executado, o programa pede para o usuário digitar a senha.&lt;br /&gt;&lt;br /&gt; A associação do REPL de &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; com a base de dados é feita através da definição de comandos do REPL (&lt;a  href="http://chicken.wiki.br/Using%20the%20interpreter#toplevel-command"&gt;&lt;code&gt;toplevel-command&lt;/code&gt;&lt;/a&gt;). Na implementação mostrada abaixo, são definidos três comandos:&lt;br /&gt;&lt;br /&gt; &lt;ul&gt;&lt;li&gt;&lt;code&gt;tables&lt;/code&gt;: mostras as tabelas da base de dados.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;table&lt;/code&gt;: mostra estrutura da tabela dada como argumento (nome e tipo das colunas e se podem ou não ser nulas).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;-&lt;/code&gt;: executa a consulta SQL dada como argumento.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt; Exemplos:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;csi -s db-repl.scm mario@localhost/sgpc&lt;br /&gt;Senha: *****&lt;br /&gt;&lt;br /&gt;#;1&gt; ,tables&lt;br /&gt;perms&lt;br /&gt;news&lt;br /&gt;users_sites&lt;br /&gt;ticket_comments&lt;br /&gt;ticket_attachments&lt;br /&gt;obj_type&lt;br /&gt;acervos&lt;br /&gt;autores&lt;br /&gt;videos&lt;br /&gt;audios&lt;br /&gt;images&lt;br /&gt;objects&lt;br /&gt;texts&lt;br /&gt;scanners&lt;br /&gt;users&lt;br /&gt;wiki&lt;br /&gt;sites&lt;br /&gt;tickets&lt;br /&gt;&lt;br /&gt;#;1&gt; ,table news&lt;br /&gt;news_id                       integer                       NO&lt;br /&gt;user_id                       integer                       NO&lt;br /&gt;site_id                       integer                       NO&lt;br /&gt;timestamp                     timestamp without time zone   YES&lt;br /&gt;title                         character varying(100)        NO&lt;br /&gt;news                          text                          YES&lt;br /&gt;&lt;br /&gt;#;1&gt; ,- select * from news&lt;br /&gt;(#(2&lt;br /&gt;   1&lt;br /&gt;   1&lt;br /&gt;   #(2008 7 30 19 37 54 271625)&lt;br /&gt;   "Teste."&lt;br /&gt;   "teste&lt;br /&gt;&lt;br /&gt;   === titulo")&lt;br /&gt; #(3&lt;br /&gt;   1&lt;br /&gt;   1&lt;br /&gt;   #(2008 7 30 19 40 27 180765)&lt;br /&gt;   "Outra notícia!"&lt;br /&gt;   "Aqui vai o texto da notícia.&lt;br /&gt;&lt;br /&gt;[[image:http://subversion.tigris.org/branding/images/logo.gif|Logo]]"))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Obviamente, os comandos para acesso ao banco de dados disponibilizados através do REPL podem ser estendidos.  O texto &lt;a  href="http://www.alberton.info/postgresql_meta_info.html"&gt;PostgreSQL INFORMATION_SCHEMA&lt;/a&gt; fornece várias dicas de como extrair informações de bases de dados do Postgres.&lt;br /&gt;&lt;br /&gt; Nesta implementação, o parâmetro &lt;code&gt;pg-repl:conn&lt;/code&gt; armazena o objeto que representa a conexão com o banco de dados, de forma que ele pode ser usado pelos procedimentos do egg &lt;a  href="http://chicken.wiki.br/postgresql"&gt;postgresql&lt;/a&gt; para a execução de consultas:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;#;1&gt; (define query  "select * from news")&lt;br /&gt;#;2&gt; (vector-ref (car (pg:query-tuples query (pg-repl:conn))) 3)&lt;br /&gt;#(2008 7 30 19 37 54 271625)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; O código do programa (&lt;code&gt;db-repl.scm&lt;/code&gt;) está a seguir:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(use utils postgresql readline stty regex (srfi 13))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;pg-repl:conn&lt;/FONT&gt;&lt;/B&gt; (make-parameter #f))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;pg-repl:query&lt;/FONT&gt;&lt;/B&gt; . query)&lt;br /&gt;  (pg:query-tuples&lt;br /&gt;   (string-intersperse (map -&amp;gt;string query) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;   (pg-repl:conn)))&lt;br /&gt;&lt;br /&gt;(toplevel-command&lt;br /&gt; '-&lt;br /&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;   (pp (pg-repl:query&lt;br /&gt;        (with-output-to-string&lt;br /&gt;          (cut print (read-line)))))))&lt;br /&gt;&lt;br /&gt;(toplevel-command&lt;br /&gt; 'table&lt;br /&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;   (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((table (string-trim-both (read-line)))&lt;br /&gt;          (cols&lt;br /&gt;           (pg-repl:query&lt;br /&gt;            &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;select column_name,data_type,&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;character_maximum_length,is_nullable &amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;from information_schema.columns &amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;where table_name = '&amp;quot;&lt;/FONT&gt;&lt;/B&gt; table &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;'&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;     (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? cols)&lt;br /&gt;         (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Tabela \&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt; table &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;\&amp;quot; nao existe.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;         (for-each&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (f)&lt;br /&gt;            (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((colname (vector-ref f 0))&lt;br /&gt;                  (type (vector-ref f 1))&lt;br /&gt;                  (size (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((size (vector-ref f 2)))&lt;br /&gt;                          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (pg:sql-null-object? size)&lt;br /&gt;                              &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                              (conc &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;(&amp;quot;&lt;/FONT&gt;&lt;/B&gt; size &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;)&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;br /&gt;                  (nullable (vector-ref f 3)))&lt;br /&gt;              (print&lt;br /&gt;               colname&lt;br /&gt;               (make-string&lt;br /&gt;                (- 30 (string-length colname)))&lt;br /&gt;               type size&lt;br /&gt;               (make-string&lt;br /&gt;                (- 30 (string-length (conc type size))))&lt;br /&gt;               nullable)))&lt;br /&gt;          cols)))))&lt;br /&gt;&lt;br /&gt;(toplevel-command&lt;br /&gt; 'tables&lt;br /&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;   (for-each&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (item)&lt;br /&gt;      (print (vector-ref item 0)))&lt;br /&gt;    (pg-repl:query&lt;br /&gt;     &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;select table_name from information_schema.tables &amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;     &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;where table_type = 'BASE TABLE' &amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;     &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;and table_schema not in &amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;     &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;('pg_catalog', 'information_schema')&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;pg-repl:usage&lt;/FONT&gt;&lt;/B&gt; #!optional exit-code)&lt;br /&gt;  (print (program-name) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; [&amp;lt;user&amp;gt;@&amp;lt;server&amp;gt;/&amp;lt;database&amp;gt;]&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (when exit-code (exit exit-code)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((args (command-line-arguments))&lt;br /&gt;      (user &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;postgres&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;      (host &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;localhost&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;      (db &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;template&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;      (passwd #f))&lt;br /&gt;&lt;br /&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; Restaura o terminal em caso de termino via C-c&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  (set-signal-handler! signal/int&lt;br /&gt;                       (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (_) (stty '(echo))))&lt;br /&gt;&lt;br /&gt;  (unless (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; (null? args) (equal? &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;\&amp;quot;\&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt; (car args)))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((cred (string-trim-both&lt;br /&gt;                  (car args)&lt;br /&gt;                  (cut memq &amp;lt;&amp;gt; '(#\space #\newline #\&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;)))) ;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;           (@tokens (string-split cred &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;@&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;           (/tokens (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? @tokens)&lt;br /&gt;                        '()&lt;br /&gt;                        (string-split (cadr @tokens) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;/&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; (null? @tokens) (null? /tokens))&lt;br /&gt;          (pg-repl:usage 1)&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;begin&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            (unless (null? @tokens)&lt;br /&gt;              (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; user (car @tokens)))&lt;br /&gt;            (unless (null? /tokens)&lt;br /&gt;              (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; host (car /tokens))&lt;br /&gt;              (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; db (cadr /tokens)))))))&lt;br /&gt;  (display &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Senha: &amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (pg-repl:conn&lt;br /&gt;   (pg:connect&lt;br /&gt;    `((user . ,user)&lt;br /&gt;      (dbname . ,db)&lt;br /&gt;      (host . ,host)&lt;br /&gt;      (password . ,(with-stty '(not echo) read-line)))))&lt;br /&gt;  (current-input-port (make-gnu-readline-port))&lt;br /&gt;  (gnu-history-install-file-manager&lt;br /&gt;   (string-append (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; (getenv &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;HOME&amp;quot;&lt;/FONT&gt;&lt;/B&gt;) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;                  &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;/.csi.history&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;  (newline)&lt;br /&gt;  (repl))&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-901579252181802714?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/901579252181802714/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=901579252181802714' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/901579252181802714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/901579252181802714'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/08/repl-de-chicken-para-acesso-bases-de.html' title='REPL de Chicken para acesso a bases de dados do Postgres'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-3744481839981502092</id><published>2008-07-31T19:18:00.000-07:00</published><updated>2008-07-31T19:21:20.686-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='elisp'/><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><title type='text'>Copy &amp; comment</title><content type='html'>Para quem seguidamente, como eu:&lt;br /&gt;&lt;br /&gt; 1. tem preguiça de criar uma revisão no VCS para alterar algo pequeno no código (só para ver se dá certo -- se não der, volta atrás rapidinho);&lt;br /&gt;&lt;br /&gt; 2. acha muito trabalhoso usar o editor de texto para duplicar um trecho de código (i.e., copiar &amp; colar) e comentar uma das partes.&lt;br /&gt;&lt;br /&gt; A função a seguir (em &lt;a  href="http://www.gnu.org/software/emacs/manual/elisp.html"&gt;Elisp&lt;/a&gt;, para &lt;a  href="http://www.gnu.org/software/emacs/"&gt;Emacs&lt;/a&gt;) faz as tarefas do item 2 para quem se enquadra no perfil do item 1:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;defun&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;copy&amp;amp;comment&lt;/FONT&gt;&lt;/B&gt; (begin end)&lt;br /&gt;  (interactive &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;r&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;save-excursion&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    (copy-region-as-kill begin end)&lt;br /&gt;    (goto-char end)&lt;br /&gt;    (yank)&lt;br /&gt;    (comment-region begin end)))&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-3744481839981502092?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/3744481839981502092/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=3744481839981502092' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/3744481839981502092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/3744481839981502092'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/07/copy-comment.html' title='Copy &amp; comment'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-1170738698149619783</id><published>2008-07-08T05:53:00.000-07:00</published><updated>2008-07-08T06:12:58.983-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Interpretador de assembly em Scheme</title><content type='html'>Dando continuidade à série de programas inúteis que só servem para alimentar a procrastinação, a seguir estão a descrição e implementação (em &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; Scheme) de um pequeno interpretador de uma linguagem assembly bem simples.&lt;br /&gt;&lt;br /&gt; A linguagem possui apenas seis instruções e opera somente com números:&lt;br /&gt;&lt;br /&gt; &lt;ul&gt;&lt;li&gt;&lt;code&gt;add &amp;lt;reg&amp;gt; &amp;lt;number | reg&amp;gt;&lt;/code&gt;: Soma um número ou o conteúdo do registrador usado como segundo argumento com o conteúdo do registrador usado como primeiro argumento.  O resultado é armazenado no registrador usado como primeiro argumento.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;mov &amp;lt;reg&amp;gt; &amp;lt;number | reg&amp;gt;&lt;/code&gt;: Armazena o número ou o conteúdo do registrador usado como segundo argumento no registrador usado como primeiro argumento.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;lbl &amp;lt;label&amp;gt;&lt;/code&gt;: Associa um endereço de memória a um rótulo, o qual pode ser referenciado no programa pelas instruções &lt;code&gt;jmp&lt;/code&gt; e &lt;code&gt;jnz&lt;/code&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;jmp &amp;lt;label&amp;gt;&lt;/code&gt;: Desvia o fluxo de execução para &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; (uma marca determinada através da instrução &lt;code&gt;lbl&lt;/code&gt;).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;jnz &amp;lt;reg&amp;gt; &amp;lt;label&amp;gt;&lt;/code&gt;: Desvia o fluxo de execução para &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; se o conteúdo do registrador usado como primeiro argumento for diferente de zero.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;out &amp;lt;number | reg&amp;gt;&lt;/code&gt;: Imprime o número ou conteúdo do registrador usado como argumento.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt; A arquitetura hipotética considerada possui 8 registradores para leitura e escrita (&lt;code&gt;r1&lt;/code&gt; a &lt;code&gt;r8&lt;/code&gt;), nenhum deles com função específica.  Há também um registrador somente para leitura (&lt;code&gt;ip&lt;/code&gt;) que armazena o endereço de memória da última instrução executada.&lt;br /&gt;&lt;br /&gt; Por simplicidade, a sintaxe das instruções é semelhante à sintaxe de Scheme, ou seja, usa parênteses.  Por exemplo:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(mov r1 3)&lt;/pre&gt;&lt;br /&gt; O código do interpretador está a seguir (&lt;code&gt;tiny-assembly.scm&lt;/code&gt;):&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; Instrucoes:&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;;     add &amp;lt;reg&amp;gt; &amp;lt;number | reg&amp;gt;&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;;     mov &amp;lt;reg&amp;gt; &amp;lt;number | reg&amp;gt;&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;;     jmp &amp;lt;label&amp;gt;&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;;     jnz &amp;lt;reg&amp;gt; &amp;lt;label&amp;gt;&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;;     lbl &amp;lt;label&amp;gt;&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;;     out &amp;lt;number | reg&amp;gt;&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;;&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; Registradores: r1..r8&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; Registrador &amp;quot;read-only&amp;quot;: ip&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;br /&gt;(use srfi-1)&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;run&lt;/FONT&gt;&lt;/B&gt; code)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;memory&lt;/FONT&gt;&lt;/B&gt; (map cons (iota (length code)) code))&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;labels&lt;/FONT&gt;&lt;/B&gt; '())&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;registers&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    '((r1 . 0) (r2 . 0) (r3 . 0) (r4 . 0)&lt;br /&gt;      (r5 . 0) (r6 . 0) (r7 . 0) (r8 . 0)))&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;ip&lt;/FONT&gt;&lt;/B&gt; 0)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;code-len&lt;/FONT&gt;&lt;/B&gt; (length code))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;die&lt;/FONT&gt;&lt;/B&gt; . msg)&lt;br /&gt;    (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Error: &amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;           (string-intersperse (map -&amp;gt;string msg) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;    (exit 1))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;next-ip&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; ip (add1 ip)))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;reg-get&lt;/FONT&gt;&lt;/B&gt; register)&lt;br /&gt;    (alist-ref register registers))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;val-get&lt;/FONT&gt;&lt;/B&gt; thing)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (eq? thing 'ip)&lt;br /&gt;        ip&lt;br /&gt;        (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (number? thing)&lt;br /&gt;            thing&lt;br /&gt;            (reg-get thing))))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;reg-set!&lt;/FONT&gt;&lt;/B&gt; reg val)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; registers&lt;br /&gt;          (alist-update! reg (val-get val) registers)))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;label-address&lt;/FONT&gt;&lt;/B&gt; label)&lt;br /&gt;    (alist-ref label labels))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;add&lt;/FONT&gt;&lt;/B&gt; reg val)&lt;br /&gt;    (reg-set! reg (+ (reg-get reg) (val-get val))))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;mov&lt;/FONT&gt;&lt;/B&gt; reg val)&lt;br /&gt;    (reg-set! reg (val-get val)))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;jmp&lt;/FONT&gt;&lt;/B&gt; label)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((address (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; (reg-get label)&lt;br /&gt;                       (label-address label))))&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; address&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; ip address)&lt;br /&gt;          (die &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;label &amp;quot;&lt;/FONT&gt;&lt;/B&gt; label &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; not found.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;jnz&lt;/FONT&gt;&lt;/B&gt; reg label)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (zero? (reg-get reg))&lt;br /&gt;        (next-ip)&lt;br /&gt;        (jmp label)))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;lbl&lt;/FONT&gt;&lt;/B&gt; label)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; labels (alist-update! label ip labels)))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;finished?&lt;/FONT&gt;&lt;/B&gt; ip) (&amp;gt;= ip code-len))&lt;br /&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; labels&lt;br /&gt;        (map (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (label)&lt;br /&gt;               (cons (caddr label) (car label)))&lt;br /&gt;             (filter (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (expr)&lt;br /&gt;                       (eq? (cadr expr) 'lbl))&lt;br /&gt;                     memory)))&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; loop ()&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (finished? ip)&lt;br /&gt;        (exit)&lt;br /&gt;        (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;begin&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((expr (alist-ref ip memory))&lt;br /&gt;                 (op (car expr))&lt;br /&gt;                 (arg1 (cadr expr))&lt;br /&gt;                 (arg2 (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; (not (null? (cddr expr)))&lt;br /&gt;                            (caddr expr))))&lt;br /&gt;            (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;case&lt;/FONT&gt;&lt;/B&gt; op&lt;br /&gt;              ((mov) (mov arg1 arg2))&lt;br /&gt;              ((add) (add arg1 arg2))&lt;br /&gt;              ((jmp) (jmp arg1))&lt;br /&gt;              ((jnz) (jnz arg1 arg2))&lt;br /&gt;              ((lbl) (noop))&lt;br /&gt;              ((out) (print&lt;br /&gt;                      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; (reg-get arg1)&lt;br /&gt;                          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (eq? arg1 'ip)&lt;br /&gt;                              ip&lt;br /&gt;                              arg1))))&lt;br /&gt;              (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;else&lt;/FONT&gt;&lt;/B&gt; (die op &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;: unknown command.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;            (unless (memq op '(jmp jnz))&lt;br /&gt;              (next-ip)))&lt;br /&gt;          (loop)))))&lt;br /&gt;&lt;br /&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;;; Command line parser&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((args (command-line-arguments)))&lt;br /&gt;  (when (null? args)&lt;br /&gt;    (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Usage: &amp;quot;&lt;/FONT&gt;&lt;/B&gt; (program-name) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; &amp;lt;input-file&amp;gt;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;    (exit 1))&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((file (car args)))&lt;br /&gt;    (unless (file-exists? file)&lt;br /&gt;      (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Could not open &amp;quot;&lt;/FONT&gt;&lt;/B&gt; file)&lt;br /&gt;      (exit 1))&lt;br /&gt;    (run (handle-exceptions&lt;br /&gt;          exn&lt;br /&gt;          (die &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;parse error.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;          (with-input-from-file file read-file)))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; A seguir estão alguns exemplos de código assembly e uso com o interpretador:&lt;br /&gt;&lt;br /&gt; &lt;h3&gt;Multiplicação&lt;/h3&gt;&lt;br /&gt; A linguagem não possui uma instrução para multiplicação.  Abaixo está a implementação de uma rotina para multiplicar dois números (7 x 4):&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(mov r1 7)&lt;br /&gt;(mov r2 4)&lt;br /&gt;(mov r4 ip)&lt;br /&gt;(jmp mul)&lt;br /&gt;(jmp end)&lt;br /&gt;&lt;br /&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; Multiplicacao (x * y)&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; x -&amp;gt; r1&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; y -&amp;gt; r2&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; produto -&amp;gt; r3&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; endereco de retorno -&amp;gt; r4&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;(lbl mul)&lt;br /&gt;(jnz r1 not-zero)&lt;br /&gt;(jmp end)&lt;br /&gt;(lbl not-zero)&lt;br /&gt;(mov r3 0)&lt;br /&gt;(lbl loopmul)&lt;br /&gt;(add r3 r2)&lt;br /&gt;(add r1 -1)&lt;br /&gt;(jnz r1 loopmul)&lt;br /&gt;(add r4 2)&lt;br /&gt;(jmp r4)&lt;br /&gt;&lt;br /&gt;(lbl end)&lt;br /&gt;(out r3)&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;$ csi -s tiny-assembly.scm multiplicacao.asm&lt;br /&gt;28&lt;/pre&gt;&lt;br /&gt; &lt;h3&gt;Fatorial&lt;/h3&gt;&lt;br /&gt; Toda e qualquer implementação de linguagem inútil deve mostrar uma implementação de fatorial como exemplo.  Abaixo está a implementação usando o assembly descrito neste texto (&lt;b&gt;where's your god now?!&lt;/b&gt;):&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(mov r5 7) &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; entrada de dados&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;br /&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; Fatorial&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;;     entrada -&amp;gt; r5&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;;     resultado -&amp;gt; r6&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;(lbl fatorial)&lt;br /&gt;(mov r6 1)&lt;br /&gt;(lbl fat-loop)&lt;br /&gt;(jnz r5 fat-not-0)&lt;br /&gt;(jmp end)&lt;br /&gt;(lbl fat-not-0)&lt;br /&gt;(add r5 -1)&lt;br /&gt;(jnz r5 fat-not-1)&lt;br /&gt;(jmp end)&lt;br /&gt;(lbl fat-not-1)&lt;br /&gt;(add r5 1)&lt;br /&gt;(mov r1 r6)&lt;br /&gt;(mov r2 r5)&lt;br /&gt;(mov r4 ip)&lt;br /&gt;(jmp mul)&lt;br /&gt;(mov r6 r3)&lt;br /&gt;(add r5 -1)&lt;br /&gt;(jmp fat-loop)&lt;br /&gt;&lt;br /&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; Multiplicacao (x * y)&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;;     x -&amp;gt; r1&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;;     y -&amp;gt; r2&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;;     produto -&amp;gt; r3&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;;     endereco de retorno -&amp;gt; r4&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;(lbl mul)&lt;br /&gt;(jnz r1 mul-not-0)&lt;br /&gt;(jmp end)&lt;br /&gt;(lbl mul-not-0)&lt;br /&gt;(mov r3 0)&lt;br /&gt;(lbl loopmul)&lt;br /&gt;(add r3 r2)&lt;br /&gt;(add r1 -1)&lt;br /&gt;(jnz r1 loopmul)&lt;br /&gt;(add r4 2)&lt;br /&gt;(jmp r4)&lt;br /&gt;&lt;br /&gt;(lbl end)&lt;br /&gt;(out r6) &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; imprime o resultado&lt;/font&gt;&lt;/i&gt;&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;$ csi -s tiny-assembly.scm fatorial.asm&lt;br /&gt;5040&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-1170738698149619783?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/1170738698149619783/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=1170738698149619783' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1170738698149619783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1170738698149619783'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/07/interpretador-de-assembly-em-scheme.html' title='Interpretador de assembly em Scheme'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-2818046677603171492</id><published>2008-07-02T06:01:00.000-07:00</published><updated>2008-07-02T08:27:49.991-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken.scheme'/><title type='text'>Contagem de definições no toplevel</title><content type='html'>Dando início a uma série de programas para geração de estatísticas inúteis, abaixo está um pequeno código para contagem de definições feitas no toplevel (em &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; Scheme).&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(use srfi-1)&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;count-defines&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((definers '(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;define-macro&lt;/FONT&gt;&lt;/B&gt; define-constant&lt;br /&gt;                     define-inline define-syntax))&lt;br /&gt;         (count-defines&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (file)&lt;br /&gt;            (cons file&lt;br /&gt;                  (length&lt;br /&gt;                   (filter&lt;br /&gt;                    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (form)&lt;br /&gt;                      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; (pair? form)&lt;br /&gt;                           (memq (car form) definers)))&lt;br /&gt;                    (with-input-from-file&lt;br /&gt;                        file read-file)))))))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (files)&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((defines-count (map count-defines files)))&lt;br /&gt;        (for-each (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (file/defcount)&lt;br /&gt;                    (print (car file/defcount) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;: &amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                           (cdr file/defcount)))&lt;br /&gt;                  defines-count)&lt;br /&gt;        (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Total: &amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;               (reduce + 0 (map cdr defines-count)))))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((files (command-line-arguments)))&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? files)&lt;br /&gt;      (exit 0)&lt;br /&gt;      (count-defines files)))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Exemplos de uso:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;$ csi -s count-defines.scm count-defines.scm&lt;br /&gt;count-defines.scm: 1&lt;br /&gt;Total: 1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;$ csi -s count-defines.scm spiffy/trunk/*.scm&lt;br /&gt;spiffy/trunk/cgi-handler.scm: 5&lt;br /&gt;spiffy/trunk/simple-directory-handler.scm: 4&lt;br /&gt;spiffy/trunk/spiffy-base.scm: 70&lt;br /&gt;spiffy/trunk/spiffy.scm: 1&lt;br /&gt;spiffy/trunk/ssp-handler.scm: 10&lt;br /&gt;spiffy/trunk/web-scheme-handler.scm: 4&lt;br /&gt;Total: 94&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Embora este programa não diga muita coisa de útil sobre o código que analisa, serve para mostrar um dos aspectos mais interessantes de Lisp: a possibilidade de se tratar, naturalmente, código como dados.  Basicamente, a contagem de definições no toplevel consiste em ler todas as expressões de um arquivo e verificar se o &lt;code&gt;car&lt;/code&gt; de cada expressão é um dos símbolos &lt;code&gt;define&lt;/code&gt;, &lt;code&gt;define-macro&lt;/code&gt;, &lt;code&gt;define-constant&lt;/code&gt;, &lt;code&gt;define-inline&lt;/code&gt; ou &lt;code&gt;define-syntax&lt;/code&gt; (se a expressão for um par).&lt;br /&gt;&lt;br /&gt; Este tipo de análise não é muito útil porque, pelo menos em &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt;, é possível especificar o que deve ser "visível" ou não no código compilado.  Isto pode ser feito com as &lt;a  href="http://chicken.wiki.br/Declarations#declare"&gt;declarações&lt;/a&gt; &lt;code&gt;export&lt;/code&gt; e &lt;code&gt;hide&lt;/code&gt;. Outros motivos são que este programa não consegue inferir as definições de toplevel que serão geradas através da expansão de macros (&lt;a  href="http://chicken.wiki.br/web-scheme"&gt;web-scheme&lt;/a&gt;, por exemplo, usa esta estratégia) e que não computa definições feitas dentro de blocos &lt;a  href="http://srfi.schemers.org/srfi-0/srfi-0.html"&gt;&lt;code&gt;cond-expand&lt;/code&gt;&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-2818046677603171492?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/2818046677603171492/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=2818046677603171492' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2818046677603171492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2818046677603171492'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/07/contagem-de-definies-no-toplevel.html' title='Contagem de definições no toplevel'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-6705741220121750381</id><published>2008-06-19T15:53:00.000-07:00</published><updated>2008-06-19T16:12:22.463-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><title type='text'>Acessando base de dados SQL com Scheme</title><content type='html'>Em alguns projetos em que estou trabalhando seguidamente tenho que acessar tabelas de bases de dados.  Costumo usar o &lt;a  href="http://www.postgresql.org"&gt;Postgres&lt;/a&gt; através do &lt;a  href="http://chicken.wiki.br/postgresql"&gt;egg postgresql&lt;/a&gt; do sistema &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Para evitar de esquecer de fechar as conexões com o banco, normalmente uso um procedimento que recebe uma query como argumento.  Este procedimento abre a conexão com o banco, executa a query e fecha a conexão automaticamente (o desempenho que se dane &lt;code&gt;:-)&lt;/code&gt;). As credenciais do banco mantenho em um parâmetro (definido com &lt;a  href="http://chicken.wiki.br/Parameters#make-parameter"&gt;&lt;code&gt;make-parameter&lt;/code&gt;&lt;/a&gt;). O procedimento é algo como:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;db-credentials&lt;/FONT&gt;&lt;/B&gt; (make-parameter '()))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;db-query&lt;/FONT&gt;&lt;/B&gt; query)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((db (pg:connect (db-credentials)))&lt;br /&gt;         (output (pg:query-tuples query db)))&lt;br /&gt;    (pg:close db)&lt;br /&gt;    output))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Mesmo com o uso do procedimento &lt;code&gt;db-query&lt;/code&gt;, o acesso a colunas do banco não é das tarefas mais simples.  Abaixo está um exemplo em que quero acessar as colunas &lt;code&gt;username&lt;/code&gt; e &lt;code&gt;email&lt;/code&gt; de uma tabela e associar o valor delas à variáveis em Scheme:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(db-credentials '((host . &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;localhost&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;                  (user . &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;usuario&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;                  (password . &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;****&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;                  (dbname . &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;nome-da-base&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((results&lt;br /&gt;        (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((results&lt;br /&gt;               (db-query&lt;br /&gt;                &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;select username,email from users where user_id=1&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? results)&lt;br /&gt;              #f&lt;br /&gt;              (car results))))&lt;br /&gt;       (username (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; results (vector-ref results 0)))&lt;br /&gt;       (email (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; results (vector-ref results 1))))&lt;br /&gt;  (print username)&lt;br /&gt;  (print email))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Como pode ser visto no exemplo, associar valores de colunas da base de dados a variáveis em Scheme é uma certa novela.  Para facilitar esta tarefa, fiz o esquema mostrado abaixo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(use postgresql)&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;db-map:credentials&lt;/FONT&gt;&lt;/B&gt; (make-parameter '()))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;db-map:create-object&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;db-query&lt;/FONT&gt;&lt;/B&gt; query)&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((db (pg:connect (db-map:credentials)))&lt;br /&gt;             (output (pg:query-tuples query db)))&lt;br /&gt;        (pg:close db)&lt;br /&gt;        output))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (query fields)&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((query-results (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((results (db-query query)))&lt;br /&gt;                              (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? results)&lt;br /&gt;                                  #f&lt;br /&gt;                                  (car results)))))&lt;br /&gt;        (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (field)&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; query-results&lt;br /&gt;               (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((pos (list-index (cut eq? &amp;lt;&amp;gt; field)&lt;br /&gt;                                      fields)))&lt;br /&gt;                 (vector-ref query-results pos))))))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;O procedimento &lt;code&gt;db-map:create-object&lt;/code&gt; recebe uma query SQL e uma lista de símbolos a serem associados com os valores das colunas obtidos como resultado da execução da query. &lt;code&gt;db-map:create-object&lt;/code&gt; retorna um procedimento que recebe como argumento um símbolo representando uma coluna da base de dados e que retorna o valor associado ao símbolo.&lt;br /&gt;&lt;br /&gt;Assim, para acessar o valor das colunas &lt;code&gt;username&lt;/code&gt; e &lt;code&gt;email&lt;/code&gt;, faço o seguinte:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((obj (db-map:create-object&lt;br /&gt;            &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;select username,email from users where user_id=1&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            '(username email))))&lt;br /&gt;  (print (obj 'username))&lt;br /&gt;  (print (obj 'email)))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A ordem dos símbolos da lista passada como segundo argumento deve ser a mesma dos valores das colunas resultantes da query SQL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-6705741220121750381?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/6705741220121750381/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=6705741220121750381' title='3 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6705741220121750381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/6705741220121750381'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/06/acessando-base-de-dados-sql-com-scheme.html' title='Acessando base de dados SQL com Scheme'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-2558294360486425112</id><published>2008-06-12T07:32:00.000-07:00</published><updated>2008-06-12T07:45:41.929-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken.scheme'/><title type='text'>Persistência de dados (e código!) em Scheme</title><content type='html'>Hoje eu e o &lt;a  href="http://vilson.void.cc"&gt;Vilson&lt;/a&gt; estávamos conversando sobre persistência de dados (e código!) em Lisp. Fiz um exemplo simples e estou colocando abaixo para não perder a viagem. :-)&lt;br /&gt;&lt;br /&gt; O exemplo implementa um objeto &lt;code&gt;mem&lt;/code&gt; (criado com o procedimento &lt;code&gt;make-mem&lt;/code&gt;) e procedimentos para manipulação desse tipo de objeto: &lt;code&gt;mem-get&lt;/code&gt; (para leitura de dados) e &lt;code&gt;mem-set!&lt;/code&gt; (para escrita em memória e em disco).&lt;br /&gt;&lt;br /&gt; A leitura de dados é sempre feita da memória (exceto na criação do objeto, que pode aproveitar dados do arquivo passado como argumento).  As escritas são feitas em memória e em disco.&lt;br /&gt;&lt;br /&gt; Os dados são armazenados em uma hash-table e indexados por símbolos.&lt;br /&gt;&lt;br /&gt; Abaixo está a implementação simplificada (em &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; Scheme), que usa o egg &lt;a  href="http://www.call-with-current-continuation.org/eggs/3/s11n.html"&gt;s11n&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(use s11n)&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;make-mem&lt;/FONT&gt;&lt;/B&gt; file)&lt;br /&gt;  (cons file (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (file-exists? file)&lt;br /&gt;                 (with-input-from-file&lt;br /&gt;                     file&lt;br /&gt;                   (cut deserialize))&lt;br /&gt;                 (make-hash-table))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;mem-get&lt;/FONT&gt;&lt;/B&gt; mem key #!optional default)&lt;br /&gt;  (hash-table-ref/default (cdr mem) key default))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;mem-set!&lt;/FONT&gt;&lt;/B&gt; mem key val)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((file (car mem))&lt;br /&gt;        (data (cdr mem)))&lt;br /&gt;    (hash-table-set! data key val)&lt;br /&gt;    (with-output-to-file file (cut serialize data))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; A seguir está um exemplo que armazena uma lista e um procedimento (código!):&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((mem (make-mem &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;teste.data&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;  (print  (mem-get mem 'a))&lt;br /&gt;  (mem-set! mem 'a '(1 2 3))&lt;br /&gt;  (print  (mem-get mem 'a))&lt;br /&gt;  (mem-set! mem 'soma (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (a b) (+ a b)))&lt;br /&gt;  (print ((mem-get mem 'soma) 2 2)))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; O resultado da execução do código do exemplo é (caso em que &lt;code&gt;teste.data&lt;/code&gt; inicialmente não existe):&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;#f&lt;br /&gt;(1 2 3)&lt;br /&gt;4&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-2558294360486425112?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/2558294360486425112/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=2558294360486425112' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2558294360486425112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/2558294360486425112'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/06/persistncia-de-dados-e-cdigo-em-scheme.html' title='Persistência de dados (e código!) em Scheme'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-7852739489205447785</id><published>2008-05-30T12:52:00.000-07:00</published><updated>2008-05-30T13:07:01.970-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Minimização de poluição no espaço de nomes</title><content type='html'>Uma forma interessante de minimizar a poluição do espaço de nomes em Scheme é usando uma combinação de &lt;code&gt;define&lt;/code&gt;, &lt;code&gt;let&lt;/code&gt; e &lt;code&gt;set!&lt;/code&gt;, tirando proveito das regras de escopo.&lt;br /&gt;&lt;br /&gt; Supondo o seguinte caso: tenho um arquivo (uma biblioteca) que será usado por outras pessoas e embutido em outros códigos.  Neste arquivo estarão alguns procedimentos que serão parte da API e procedimentos auxiliares úteis para o desenvolvimento do próprio código desta biblioteca. Mesmo sem usar um sistema de módulos, é possível minimizar a poluição do espaço de nomes que seria causado pelos procedimentos auxiliares com a seguinte estratégia:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;proc-api-1&lt;/FONT&gt;&lt;/B&gt; #f)&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;proc-api-2&lt;/FONT&gt;&lt;/B&gt; #f)&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;proc-aux&lt;/FONT&gt;&lt;/B&gt; arg) (codigo))&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; proc-api-1 (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; () (proc-aux 3)))&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; proc-api-2 (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; () (proc-aux (proc-aux 1000)))))&lt;/pre&gt;&lt;br /&gt; No exemplo temos dois símbolos visíveis no escopo mais amplo (&lt;i&gt;toplevel&lt;/i&gt;) deste arquivo : &lt;code&gt;proc-api-1&lt;/code&gt; e &lt;code&gt;proc-api-2&lt;/code&gt;. A outra definição &lt;code&gt;proc-aux&lt;/code&gt;, que é útil para a implementação dos procedimentos da API, fica no escopo do bloco &lt;code&gt;(let () ...)&lt;/code&gt;, ou seja, &lt;b&gt;não&lt;/b&gt; é visível do &lt;i&gt;toplevel&lt;/i&gt;. Dentro do bloco &lt;code&gt;(let () ...)&lt;/code&gt;, então, fazemos a atribuição do código dos procedimentos da API às variáveis definidas no &lt;i&gt;toplevel&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt; Um exemplo mais prático (mas não menos besta):&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;ul&lt;/FONT&gt;&lt;/B&gt; #f)&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;li&lt;/FONT&gt;&lt;/B&gt; #f)&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;p&lt;/FONT&gt;&lt;/B&gt; #f)&lt;br /&gt;&lt;br /&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;&lt;br /&gt;   (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;cria-tag&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;     (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (nome)&lt;br /&gt;       (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((nome (symbol-&amp;gt;string nome)))&lt;br /&gt;         (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; args&lt;br /&gt;           (string-append &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;lt;&amp;quot;&lt;/FONT&gt;&lt;/B&gt; nome &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;gt;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                          (string-intersperse args &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;                          &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;lt;/&amp;quot;&lt;/FONT&gt;&lt;/B&gt; nome &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;gt;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;br /&gt;&lt;br /&gt;     (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; ul (cria-tag 'ul))&lt;br /&gt;     (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; li (cria-tag 'li))&lt;br /&gt;     (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt; p (cria-tag 'p)))&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Executando isso no REPL, podemos ver o efeito da estratégia usada:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;$ csi -n&lt;br /&gt;&lt;br /&gt;CHICKEN&lt;br /&gt;(c)2008 The Chicken Team&lt;br /&gt;(c)2000-2007 Felix L. Winkelmann&lt;br /&gt;Version 3.2.0 - linux-unix-gnu-x86      [ manyargs dload ptables applyhook ]&lt;br /&gt;SVN rev. 10664  compiled 2008-05-08 on ze-dureza (Linux)&lt;br /&gt;&lt;br /&gt;#;1&amp;gt; (load &amp;quot;cria-tag.scm&amp;quot;)&lt;br /&gt;; loading cria-tag.scm ...&lt;br /&gt;#;2&amp;gt; p&lt;br /&gt;#&amp;lt;procedure (? . args)&amp;gt;&lt;br /&gt;#;3&amp;gt; li&lt;br /&gt;#&amp;lt;procedure (? . args)&amp;gt;&lt;br /&gt;#;4&amp;gt; ul&lt;br /&gt;#&amp;lt;procedure (? . args)&amp;gt;&lt;br /&gt;#;5&amp;gt; cria-tag&lt;br /&gt;Error: unbound variable: cria-tag&lt;br /&gt;#;5&amp;gt; (p &amp;quot;nada&amp;quot;)&lt;br /&gt;&amp;quot;&amp;lt;p&amp;gt;nada&amp;lt;/p&amp;gt;&amp;quot;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Conforme esperado, a definição de &lt;code&gt;cria-tag&lt;/code&gt; não é visível no &lt;i&gt;toplevel&lt;/i&gt;, mas as funções que a usam funcionam.&lt;br /&gt;&lt;br /&gt; Esta estratégia é bastante usada na implementação do sistema &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt;, por exemplo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-7852739489205447785?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/7852739489205447785/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=7852739489205447785' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7852739489205447785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7852739489205447785'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/05/minimizao-de-poluio-no-espao-de-nomes.html' title='Minimização de poluição no espaço de nomes'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-3814662504476248091</id><published>2008-05-24T19:16:00.000-07:00</published><updated>2008-05-24T19:31:32.569-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='amplificador'/><category scheme='http://www.blogger.com/atom/ns#' term='música'/><title type='text'>Giannini Thunder Sound Bass II</title><content type='html'>Neste final de semana meu pai me trouxe de presente um amplificador valvulado da década de 70, um Thunder Sound II, da Giannini.  Um amplificador desses estava em uma das posições mais altas da minha lista de sonhos de consumo.&lt;br /&gt;&lt;br /&gt;Inicialmente ele só ligava, as vávulas acendiam, mas o sinal da entrada não era amplificado.  Havia apenas um zumbido no alto-falante da caixa em que liguei o amplificador.&lt;br /&gt;&lt;br /&gt;Hoje decidi abri-lo para ver se descobria qual era o defeito.  Para a minha sorte, era apenas um capacitor solto.  Bastou soldá-lo de volta no lugar e o amplificador passou a funcionar.  Os potenciômetros não estão lá grandes coisas (aceitável, dada a idade do troço), provavelmente serão trocados.&lt;br /&gt;&lt;br /&gt;Fotos do amplificador em &lt;a href="http://g3pd.ucpel.tche.br/~mario/fotos/thunder-sound/"&gt;http://g3pd.ucpel.tche.br/~mario/fotos/thunder-sound&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-3814662504476248091?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/3814662504476248091/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=3814662504476248091' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/3814662504476248091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/3814662504476248091'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/05/giannini-thunder-sound-bass-ii.html' title='Giannini Thunder Sound Bass II'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-7617946052341294685</id><published>2008-05-14T07:18:00.000-07:00</published><updated>2008-05-14T07:31:14.019-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='musica'/><title type='text'>Geração de tablaturas em Scheme</title><content type='html'>O &lt;a  href="http://kroger.lisp-br.org/"&gt;Pedro&lt;/a&gt; provavelmente vai me chamar de &lt;a  href="http://en.wikipedia.org/wiki/Imbecile#Traditional_terms"&gt;imbecil&lt;/a&gt; por eu estar apresentando um programa para geração de um tipo de notação musical tão primitiva, simplória e pouco representativa.  Mas azar :-).  Para analfabetos musicais como eu, &lt;a  href="http://pt.wikipedia.org/wiki/Tablatura"&gt;tablaturas&lt;/a&gt; são uma forma simples de representar notas a serem tocadas em um instrumento.&lt;br /&gt;&lt;br /&gt; O programa a seguir (em &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; Scheme) gera tablaturas para contrabaixos de quatro cordas com duas oitavas por corda.  Adaptar para guitarra/violão e para a notação de acordes não deve ser difícil.&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(use (srfi 1))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;deriva-nota&lt;/FONT&gt;&lt;/B&gt; corda #!optional (desloc 0) oitava)&lt;br /&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; deriva notas a partir de corda e posicao de referencia&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; representando a nota mais grave&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((corda-vazia (make-vector 4 '-))&lt;br /&gt;         (pos-corda-0 (+ desloc (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; oitava 12 0)))&lt;br /&gt;         (pos (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;case&lt;/FONT&gt;&lt;/B&gt; corda&lt;br /&gt;                ((0) pos-corda-0)&lt;br /&gt;                ((1) (+ pos-corda-0 7))&lt;br /&gt;                ((2) (+ pos-corda-0 2))&lt;br /&gt;                ((3) (+ pos-corda-0 9)))))&lt;br /&gt;    (vector-set! corda-vazia corda&lt;br /&gt;                 (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; (&amp;gt;= pos 12) (not oitava))&lt;br /&gt;                     (- pos 12)&lt;br /&gt;                     pos))&lt;br /&gt;    (vector-&amp;gt;list corda-vazia)))&lt;br /&gt;&lt;br /&gt;(define-macro (cria-notas)&lt;br /&gt;  &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; cria funcoes com nome correspondente `as notas&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((notas/desloc '((E  . 0)&lt;br /&gt;                        (F  . 1)&lt;br /&gt;                        (F# . 2)&lt;br /&gt;                        (G  . 3)&lt;br /&gt;                        (G# . 4)&lt;br /&gt;                        (Ab . 4)&lt;br /&gt;                        (A  . 5)&lt;br /&gt;                        (A# . 6)&lt;br /&gt;                        (Bb . 6)&lt;br /&gt;                        (B  . 7)&lt;br /&gt;                        (C  . 8)&lt;br /&gt;                        (C# . 9)&lt;br /&gt;                        (Db . 9)&lt;br /&gt;                        (D  . 10)&lt;br /&gt;                        (D# . 11)&lt;br /&gt;                        (Eb . 11))))&lt;br /&gt;    (append&lt;br /&gt;     '(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;begin&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;     (map (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (nota)&lt;br /&gt;            `(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (,(car nota) corda #!optional oitava)&lt;br /&gt;               (deriva-nota corda ,(cdr nota) oitava)))&lt;br /&gt;          notas/desloc))))&lt;br /&gt;&lt;br /&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; gera as definicoes das funcoes&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;(cria-notas)&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;formata-corda&lt;/FONT&gt;&lt;/B&gt; corda notas)&lt;br /&gt;  (string-append&lt;br /&gt;   (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;case&lt;/FONT&gt;&lt;/B&gt; corda&lt;br /&gt;     ((0) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;G&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;     ((1) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;D&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;     ((2) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;A&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;     ((3) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;E&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;   &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; |&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;   (string-intersperse&lt;br /&gt;    (map (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (nota)&lt;br /&gt;           (string-append&lt;br /&gt;            &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;--&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            (-&amp;gt;string nota)&lt;br /&gt;            (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; (number? nota) (&amp;gt; nota 9))&lt;br /&gt;                &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;-&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;--&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;         (map&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;case&lt;/FONT&gt;&lt;/B&gt; corda&lt;br /&gt;            ((0) cadddr)&lt;br /&gt;            ((1) caddr)&lt;br /&gt;            ((2) cadr)&lt;br /&gt;            ((3) car))&lt;br /&gt;          notas))&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;|&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;tablatura&lt;/FONT&gt;&lt;/B&gt; . notas)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;notas/corda&lt;/FONT&gt;&lt;/B&gt; 10) &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; numero maximo de notas por&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;                          &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; linha da tablatura&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;tab&lt;/FONT&gt;&lt;/B&gt; notas)&lt;br /&gt;    (for-each (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (corda)&lt;br /&gt;                (print (formata-corda corda notas)))&lt;br /&gt;              '(0 1 2 3)))&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; loop ((bloco notas))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;cond&lt;/FONT&gt;&lt;/B&gt; ((&amp;gt; (length bloco) notas/corda)&lt;br /&gt;           (tab (take bloco notas/corda))&lt;br /&gt;           (loop (drop bloco notas/corda)))&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;else&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;           (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;           (tab (append &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; preenche ate' o final da linha&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;                 bloco&lt;br /&gt;                 (make-list (- notas/corda (length bloco))&lt;br /&gt;                            '(- - - -) )))))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Para gerar uma tablatura, o usuário especifica as notas através de funções, e as passa como argumento para a função &lt;code&gt;tablatura&lt;/code&gt;. As funções para representação de notas usam como argumentos a corda em que devem ser tocadas (de 0 a 3) e, opcionalmente, se uma oitava acima.  Um exemplo com a escala pentatônica é mostrado abaixo:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(tablatura (G 0) (A# 0) (C 1) (D 1) (F 2))&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;G |--------------------------------------------------|&lt;br /&gt;D |----------------------3---------------------------|&lt;br /&gt;A |------------3----5--------------------------------|&lt;br /&gt;E |--3----6------------------------------------------|&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; O programa quebra a linha da tablatura depois de um determinado número de notas (no código este parâmetro está com o valor 10) e completa a linha caso o número de notas seja menor que 10.&lt;br /&gt;&lt;br /&gt; Uma tablatura com mais de 10 notas:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(tablatura&lt;br /&gt;    (G 0) (A# 0) (C 1) (D 1) (F 2)&lt;br /&gt;    (G 0) (A# 0) (C 1) (D 1) (F 2)&lt;br /&gt;    (G 0) (A# 0) (C 1) (D 1) (F 2))&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;G |--------------------------------------------------|&lt;br /&gt;D |----------------------3------------------------3--|&lt;br /&gt;A |------------3----5-------------------3----5-------|&lt;br /&gt;E |--3----6-------------------3----6-----------------|&lt;br /&gt;&lt;br /&gt;G |--------------------------------------------------|&lt;br /&gt;D |----------------------3---------------------------|&lt;br /&gt;A |------------3----5--------------------------------|&lt;br /&gt;E |--3----6------------------------------------------|&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-7617946052341294685?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/7617946052341294685/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=7617946052341294685' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7617946052341294685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7617946052341294685'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/05/gerao-de-tablaturas-em-scheme.html' title='Geração de tablaturas em Scheme'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-7795026796595543741</id><published>2008-05-13T15:06:00.000-07:00</published><updated>2008-05-13T15:22:58.914-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Programação para Web com Chicken e Ajax</title><content type='html'>&lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; possui uma &lt;a  href="http://chicken.wiki.br/eggs"&gt;extensão&lt;/a&gt; interessante para desenvolvimento para a Web: o egg &lt;a  href="http://www.call-with-current-continuation.org/eggs/3/ajax.html"&gt;ajax&lt;/a&gt;.  Essa extensão é, na realidade, um &lt;i&gt;wrapper&lt;/i&gt; para a biblioteca &lt;a  href="http://www.prototypejs.org/"&gt;prototype&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;O uso do egg &lt;a  href="http://www.call-with-current-continuation.org/eggs/3/ajax.html"&gt;ajax&lt;/a&gt; é bem fácil depois que se entende como ele funciona. Confesso que quebrei um pouco a cabeça para começar a usá-lo, e a dificuldade foi agravada pelo fato de eu não conhecer muito bem a biblioteca &lt;a  href="http://www.prototypejs.org/"&gt;prototype&lt;/a&gt; na época.&lt;br /&gt;&lt;br /&gt;Para facilitar o entendimento do egg &lt;a  href="http://www.call-with-current-continuation.org/eggs/3/ajax.html"&gt;ajax&lt;/a&gt;, vale a pena mencionar um recurso interessante do egg &lt;a  href="http://chicken.wiki.br/http"&gt;http&lt;/a&gt;: a possibilidade de definição de &lt;a  href="http://chicken.wiki.br/http#http-add-resource"&gt;&lt;i&gt;recursos&lt;/i&gt;&lt;/a&gt; (&lt;i&gt;resources&lt;/i&gt;). Com isso, é possível associar uma URL a um procedimento que será executado no servidor. Esta colocação, embora pareça "solta" agora, é necessária para entender como o egg &lt;a  href="http://www.call-with-current-continuation.org/eggs/3/ajax.html"&gt;ajax&lt;/a&gt; funciona (espero que ela venha a fazer sentido até o final deste texto...).&lt;br /&gt;&lt;br /&gt;Uma das funções mais práticas do egg &lt;a  href="http://www.call-with-current-continuation.org/eggs/3/ajax.html"&gt;ajax&lt;/a&gt; é a &lt;code&gt;remote-link&lt;/code&gt;. Com ela, é possível realizar várias operações no cliente com base no resultado do procedimento executado no servidor.  A seguir está um exemplo de aplicação básica de &lt;code&gt;remote-link&lt;/code&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(remote-link&lt;br /&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Clique aqui&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;   (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Oi&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt; update: &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;resultado&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;code&gt;remote-link&lt;/code&gt; recebe três argumentos:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;O texto do link&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Uma função sem argumentos a ser executada no servidor&lt;/li&gt;&lt;br /&gt;&lt;li&gt;O tipo de ação a ser executada no cliente e em qual elemento da página aplicar o resultado da função executada no servidor.  O tipo de ação a ser executada é determinado pelo parâmetro de palavra-chave escolhido (&lt;code&gt;update&lt;/code&gt; no exemplo) e o elemento a aplicar o resultado é a string associada ao parâmetro de palavra-chave (&lt;code&gt;resultado&lt;/code&gt; no exemplo).&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;O exemplo com &lt;code&gt;remote-link&lt;/code&gt;, então,  gera os códigos HTML e Javascript necessários para atualizar o elemento de identificador &lt;code&gt;resultado&lt;/code&gt; com o texto &lt;code&gt;Oi&lt;/code&gt; quando o usuário clicar no link &lt;code&gt;Clique aqui&lt;/code&gt;. O código gerado é mostrado abaixo:&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;a href='#' onclick=&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;new Ajax.Updater('resultado', '/9fa328569dc39078f13e29086bbf3b93', {  });&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;Clique aqui&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/a&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;/tt&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;O código Javascript gerado corresponde a criação de um objeto &lt;code&gt;Updater&lt;/code&gt; da bilioteca &lt;a  href="http://www.prototypejs.org/"&gt;prototype&lt;/a&gt;, cujos argumentos são o identificador do elemento a ser atualizado no cliente depois da execução do procedimento associado à URL usada como segundo argumento (&lt;code&gt;/9fa328569dc39078f13e29086bbf3b93&lt;/code&gt;). Essa URL é gerada pelo egg &lt;a  href="http://www.call-with-current-continuation.org/eggs/3/ajax.html"&gt;ajax&lt;/a&gt;, usando a funcionalidade de &lt;i&gt;recursos&lt;/i&gt; do egg &lt;a  href="http://chicken.wiki.br/http"&gt;http&lt;/a&gt;, mencionada no início deste texto.  A URL fica associada à função usada como argumento para &lt;code&gt;remote-link&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Vamos ver um exemplo prático com o servidor web &lt;a  href="http://chicken.wiki.br/spiffy"&gt;Spiffy&lt;/a&gt;. São necessários os seguintes &lt;a  href="http://chicken.wiki.br/eggs"&gt;eggs&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a  href="http://www.chicken.wiki.br/spiffy"&gt;spiffy&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a  href="http://chicken.wiki.br/web-scheme"&gt;web-scheme&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a  href="http://www.call-with-current-continuation.org/eggs/3/ajax.html"&gt;ajax&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a  href="http://www.call-with-current-continuation.org/eggs/3/spiffy-utils.html"&gt;spiffy-utils&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Os &lt;a  href="http://chicken.wiki.br/eggs"&gt;eggs&lt;/a&gt; podem ser instalados da seguinte forma:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ chicken-setup spiffy web-scheme ajax spiffy-utils&lt;/pre&gt;&lt;br /&gt;Todas as dependências serão instaladas automaticamente.&lt;br /&gt;&lt;br /&gt;O programa para execução do servidor web está abaixo (&lt;code&gt;web-server.scm&lt;/code&gt;):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(use spiffy web-scheme web-scheme-handler ajax spiffy-utils)&lt;br /&gt;&lt;br /&gt;(spiffy-file-ext-handlers `((&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;ws&amp;quot;&lt;/FONT&gt;&lt;/B&gt; . ,web-scheme-handler)))&lt;br /&gt;(spiffy-tcp-port 8080)&lt;br /&gt;(spiffy-root-path &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;(spiffy-debug-mode #t)&lt;br /&gt;(start-server)&lt;/pre&gt;&lt;br /&gt;Para usar o egg &lt;a  href="http://www.call-with-current-continuation.org/eggs/3/ajax.html"&gt;ajax&lt;/a&gt;, é necessária a biblioteca &lt;a  href="http://www.prototypejs.org/"&gt;prototype&lt;/a&gt;, que acompanha a extensão (o arquivo encontra-se em &lt;code&gt;CHICKEN_PREFIX/lib/chicken/3/prototype.js&lt;/code&gt;, onde &lt;code&gt;CHICKEN_PREFIX&lt;/code&gt; é o diretório onde o sistema Chicken foi instalado).  Copie o arquivo &lt;code&gt;prototype.js&lt;/code&gt; para o mesmo diretório onde foi criado o arquivo &lt;code&gt;web-server.scm&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;O arquivo para gerar a página HTML (index.ws) é mostrado abaixo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(ws:page&lt;br /&gt; (string-append&lt;br /&gt;  (div 'id &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;resultado&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (remote-link&lt;br /&gt;   &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Clique aqui&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;   (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;     (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Oi&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;   update: &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;resultado&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt; additional-headers: (ajax))&lt;/pre&gt;&lt;br /&gt;Para ver o resultado, basta executar o servidor web:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ csi -s web-server.scm&lt;/pre&gt;&lt;br /&gt;e acessar &lt;code&gt;http://localhost:8080&lt;/code&gt; no seu navegador preferido (algum que tenha suporte a Javascript).&lt;br /&gt;&lt;br /&gt;A função &lt;code&gt;ajax&lt;/code&gt; usada no exemplo gera o código HTML necessário para referenciar a biblioteca &lt;a  href="http://www.prototypejs.org/"&gt;prototype&lt;/a&gt; na página.&lt;br /&gt;&lt;br /&gt;Obviamente, é possível fazer algo de mais útil com isso.  A seguir é mostrado um exemplo mais elaborado (&lt;code&gt;tamanho.ws&lt;/code&gt;): uma aplicação que mostra em uma caixa do tipo &lt;code&gt;select&lt;/code&gt; os arquivos no diretório raíz do servidor e exibe o tamanho quando são selecionados.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(use posix)&lt;br /&gt;&lt;br /&gt;(ws:page&lt;br /&gt; (string-append&lt;br /&gt;  (ws:select&lt;br /&gt;   'id &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;file-box&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;   'onchange (remote-action&lt;br /&gt;              (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;                (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((file (post-var &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;file&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;                  (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Tamanho de &amp;quot;&lt;/FONT&gt;&lt;/B&gt; file &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; = &amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                         (file-size file) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; bytes&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;              update: &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;resultado&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;              arguments: &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;'file=' + $F('file-box')&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;   (string-intersperse&lt;br /&gt;    (map (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (opt)&lt;br /&gt;           (option 'value opt opt))&lt;br /&gt;         (glob (make-pathname&lt;br /&gt;                (spiffy-root-path) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;*&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;  (div 'id &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;resultado&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt; additional-headers: (ajax))&lt;/pre&gt;&lt;br /&gt;O código acima monta uma caixa de opções (&lt;code&gt;select&lt;/code&gt; de HTML) com os arquivos no diretório raíz do servidor (parâmetro &lt;code&gt;(spiffy-root-path)&lt;/code&gt;) e usa &lt;code&gt;remote-action&lt;/code&gt; para registrar a função que é executada no lado do servidor e executá-la quando um arquivo for selecionado na caixa de seleção.&lt;br /&gt;&lt;br /&gt;O parâmetro de palavra-chave &lt;code&gt;arguments&lt;/code&gt; especifica as variáveis a serem passadas através dos métodos GET e POST do HTTP.  Se nenhum método for especificado, POST é usado (o parâmetro de palavra-chave &lt;code&gt;method&lt;/code&gt; permite especificar o método a ser usado).  A função &lt;code&gt;$F&lt;/code&gt; em Javascript, da biblioteca &lt;a  href="http://www.prototypejs.org/"&gt;prototype&lt;/a&gt;, retorna o conteúdo do widget cujo identificador é passado como argumento.&lt;br /&gt;&lt;br /&gt;Para ver a aplicação em funcionamento, acesse &lt;code&gt;http://localhost:8080/tamanho.ws&lt;/code&gt; no seu navegador&lt;br /&gt;&lt;br /&gt;Mais detalhes sobre o funcionamento do egg &lt;a  href="http://www.call-with-current-continuation.org/eggs/3/ajax.html"&gt;ajax&lt;/a&gt; podem ser obtidos na documentação da extensão, em &lt;a  href="http://www.call-with-current-continuation.org/eggs/3/ajax.html"&gt;http://www.call-with-current-continuation.org/eggs/3/ajax.html&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-7795026796595543741?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/7795026796595543741/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=7795026796595543741' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7795026796595543741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7795026796595543741'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/05/programao-para-web-com-chicken-e-ajax.html' title='Programação para Web com Chicken e Ajax'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-1316142630478438269</id><published>2008-05-12T07:04:00.000-07:00</published><updated>2008-05-12T14:43:49.525-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Objetos em Scheme</title><content type='html'>Há uns dias o tópico "objetos" surgiu nas discussões no &lt;a  href="http://freenode.net"&gt;canal #lisp-br&lt;/a&gt;. A especificação de Scheme não oferece nenhum sistema de objetos para ser prontamente usado, mas a linguagem possui características que permitem a implementação de sistemas de objetos (tanto que há &lt;a  href="http://chicken.wiki.br/Eggs%20Unlimited%203#object-oriented-programming"&gt;vários&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt; A seguir está um exemplo de implementação bem simplificada de um criador de objetos em Scheme (&lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; Scheme).&lt;br /&gt;&lt;br /&gt; Considerações:&lt;br /&gt;&lt;br /&gt; &lt;ul&gt;&lt;li&gt;Objetos são representados por &lt;i&gt;&lt;a  href="http://en.wikipedia.org/wiki/Closure_%28computer_science%29"&gt;closures&lt;/a&gt;&lt;/i&gt; que aceitam &lt;a  href="http://en.wikipedia.org/wiki/Message_%28computer_science%29#OOP"&gt;mensagens&lt;/a&gt; para acesso a atributos internos.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Em Scheme, funções (&lt;i&gt;procedures&lt;/i&gt;) são objetos de primeira classe, ou seja, podem ser manipuladas como qualquer outro tipo de valor (e.g., números, strings). Assim, uma "chamada de método" nesse sistema de objetos exemplo corresponde ao acesso a um atributo cujo valor é uma função.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt; &lt;pre&gt;(use (srfi 1))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;cria-ponto&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;letrec&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      ((atributos&lt;br /&gt;        `((pos-x . 0)&lt;br /&gt;          (pos-y . 0)&lt;br /&gt;          (posicao . ,(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;                        (cons (this 'pos-x)&lt;br /&gt;                              (this 'pos-y)&lt;br /&gt;                              )))))&lt;br /&gt;       (this (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (var)&lt;br /&gt;               (alist-ref var atributos))))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; args&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? args)&lt;br /&gt;          (error &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Nenhuma mensagem.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((acao (car args)))&lt;br /&gt;            (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;case&lt;/FONT&gt;&lt;/B&gt; acao&lt;br /&gt;              ((&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt;) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((atributo (cadr args))&lt;br /&gt;                            (valor (caddr args)))&lt;br /&gt;                        (alist-update! atributo valor&lt;br /&gt;                                       atributos)&lt;br /&gt;                        (void)))&lt;br /&gt;              ((get) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((atributo (this (cadr args))))&lt;br /&gt;                       (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; atributo&lt;br /&gt;                           (error &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Atributo inexistente.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;br /&gt;              (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;else&lt;/FONT&gt;&lt;/B&gt; (error &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Mensagem nao conhecida.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;              ))))))&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; A função &lt;code&gt;cria-ponto&lt;/code&gt; retorna um objeto ponto, o qual é representado por uma função que aceita um número arbitrário de argumentos, que correspondem a mensagens. Os atributos do objeto são declarados na alist &lt;code&gt;atributos&lt;/code&gt;, com um valor inicial.  Um dos atributos (&lt;code&gt;posicao&lt;/code&gt;) é uma função, que retorna um par representando as coordenadas do ponto.&lt;br /&gt;&lt;br /&gt; A criação de um objeto ponto é feita com a avaliação da expressão &lt;code&gt;(cria-ponto)&lt;/code&gt;:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;ponto&lt;/FONT&gt;&lt;/B&gt; (cria-ponto))&lt;/pre&gt;&lt;br /&gt; &lt;code&gt;ponto&lt;/code&gt;, então, passa a representar um objeto ponto, o qual aceita mensagens.  Alguns exemplos:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;csi&amp;gt; (define ponto (cria-ponto))&lt;br /&gt;csi&amp;gt; (ponto 'get 'pos-x)&lt;br /&gt;0&lt;br /&gt;csi&amp;gt; (ponto 'get 'pos-y)&lt;br /&gt;0&lt;br /&gt;csi&amp;gt; (ponto 'set! 'pos-y 10)&lt;br /&gt;csi&amp;gt; (ponto 'get 'pos-y)&lt;br /&gt;10&lt;br /&gt;csi&amp;gt; (ponto 'get 'posicao)&lt;br /&gt;#&amp;lt;procedure (?)&amp;gt;&lt;br /&gt;csi&amp;gt; ((ponto 'get 'posicao))&lt;br /&gt;(0 . 10)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Algumas mensagens causam alteração nos objetos (i.e., &lt;code&gt;set!&lt;/code&gt;). Como a representação de pontos é feita com closures, a alteração do estado interno de um objeto não deve alterar o dos outros:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;csi&gt; (define outro-ponto (cria-ponto))&lt;br /&gt;csi&gt; (outro-ponto 'get 'pos-x)&lt;br /&gt;0&lt;br /&gt;csi&gt; (outro-ponto 'set! 'pos-x 15)&lt;br /&gt;csi&gt; ((outro-ponto 'get 'posicao))&lt;br /&gt;(15 . 0)&lt;br /&gt;csi&gt; ((ponto 'get 'posicao))&lt;br /&gt;(0 . 10)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; A implementação de &lt;a  href="http://en.wikipedia.org/wiki/Introspection_%28computer_science%29"&gt;introspecção&lt;/a&gt; pode ser feita com a implementação tratadores para duas novas mensagens: &lt;code&gt;tipo&lt;/code&gt; e &lt;code&gt;atributos&lt;/code&gt;, ou seja, fazemos com que objetos ponto respondam a mensagens &lt;code&gt;tipo&lt;/code&gt; e &lt;code&gt;atributos&lt;/code&gt;:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(use (srfi 1))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;cria-ponto&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;letrec&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      ((tipo 'ponto)&lt;br /&gt;       (atributos&lt;br /&gt;        `((pos-x . 0)&lt;br /&gt;          (pos-y . 0)&lt;br /&gt;          (posicao . ,(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;                        (cons (this 'pos-x)&lt;br /&gt;                              (this 'pos-y)&lt;br /&gt;                              )))))&lt;br /&gt;       (this (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (var)&lt;br /&gt;               (alist-ref var atributos))))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; args&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? args)&lt;br /&gt;          (error &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Nenhuma mensagem.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((acao (car args)))&lt;br /&gt;            (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;case&lt;/FONT&gt;&lt;/B&gt; acao&lt;br /&gt;              ((&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt;) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((atributo (cadr args))&lt;br /&gt;                            (valor (caddr args)))&lt;br /&gt;                        (alist-update! atributo valor&lt;br /&gt;                                       atributos)&lt;br /&gt;                        (void)))&lt;br /&gt;              ((get) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((atributo (this (cadr args))))&lt;br /&gt;                       (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; atributo&lt;br /&gt;                           (error &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Atributo inexistente.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;br /&gt;              ((tipo) tipo)&lt;br /&gt;              ((atributos) atributos)&lt;br /&gt;              (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;else&lt;/FONT&gt;&lt;/B&gt; (error &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Mensagem nao conhecida.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;              ))))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Para obter as informações de tipo e atributos do objeto ponto, então:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;csi&amp;gt; (define ponto (cria-ponto))&lt;br /&gt;csi&amp;gt; (ponto 'tipo)&lt;br /&gt;ponto&lt;br /&gt;csi&amp;gt; (ponto 'atributos)&lt;br /&gt;((pos-x . 0) (pos-y . 0) (posicao . #&amp;lt;procedure (?)&amp;gt;))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Para a implementação de um simples mecanismo de &lt;a  href="http://en.wikipedia.org/wiki/Inheritance_%28computer_science%29"&gt;herança&lt;/a&gt;, fazemos com que a função criadora de objetos passe a aceitar uma lista de ancestrais, e incorpore a lista de atributos dos ancestrais aos atributos do objeto sendo criado.  O exemplo a seguir mostra a criação de um objeto representando um ponto em três dimensões, aproveitando características de um ponto em duas dimensões (&lt;code&gt;pos-x&lt;/code&gt; e &lt;code&gt;pos-y&lt;/code&gt;):&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(use (srfi 1))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;cria-ponto-3D&lt;/FONT&gt;&lt;/B&gt; . pais)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;letrec&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      ((tipo 'ponto-3D)&lt;br /&gt;       (tipos (cons tipo&lt;br /&gt;                    (map (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (pai)&lt;br /&gt;                           (pai 'tipo))&lt;br /&gt;                         pais)))&lt;br /&gt;       (supers (apply append&lt;br /&gt;                      (map (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (pai)&lt;br /&gt;                             (pai 'atributos))&lt;br /&gt;                           pais)))&lt;br /&gt;       (atributos&lt;br /&gt;        `((pos-z . 0)&lt;br /&gt;          (posicao . ,(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;                        (list (this 'pos-x)&lt;br /&gt;                              (this 'pos-y)&lt;br /&gt;                              (this 'pos-z)&lt;br /&gt;                              )))))&lt;br /&gt;       (this (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (var)&lt;br /&gt;               (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; (alist-ref var atributos)&lt;br /&gt;                   (alist-ref var supers)))))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; args&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? args)&lt;br /&gt;          (error &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Nenhuma mensagem.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;          (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((acao (car args)))&lt;br /&gt;            (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;case&lt;/FONT&gt;&lt;/B&gt; acao&lt;br /&gt;              ((&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt;) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((atrib (cadr args))&lt;br /&gt;                            (valor (caddr args)))&lt;br /&gt;                        (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (alist-ref atrib atributos)&lt;br /&gt;                            (alist-update! atrib valor&lt;br /&gt;                                           atributos)&lt;br /&gt;                            (alist-update! atrib valor&lt;br /&gt;                                           supers))&lt;br /&gt;                        (void)))&lt;br /&gt;              ((get) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((atributo (this (cadr args))))&lt;br /&gt;                       (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; atributo&lt;br /&gt;                           (error &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Atributo inexistente.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;br /&gt;              ((tipo) tipo)&lt;br /&gt;              ((atributos) (append supers atributos))&lt;br /&gt;              ((is-a?) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (t)&lt;br /&gt;                         (not (not (memq t tipos)))))&lt;br /&gt;              (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;else&lt;/FONT&gt;&lt;/B&gt; (error &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Mensagem nao conhecida.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;              ))))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; O objeto ponto 3D incorpora as características de seus ancestrais e adiciona uma nova: &lt;code&gt;pos-z&lt;/code&gt;, além de responder mensagens novas, como &lt;code&gt;is-a?&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;csi&gt; (define ponto-3D (cria-ponto-3D ponto))&lt;br /&gt;csi&gt;  (ponto-3D 'tipo)&lt;br /&gt;ponto-3D&lt;br /&gt;csi&gt; ((ponto-3D 'is-a?) 'ponto)&lt;br /&gt;#t&lt;br /&gt;csi&gt; ((ponto-3D 'is-a?) 'ponto-3D)&lt;br /&gt;#t&lt;br /&gt;csi&gt; ((ponto-3D 'is-a?) 'ponto-4D)&lt;br /&gt;#f&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; É possível generalizar a função criadora de objetos para que ela receba como argumentos o tipo, os atributos e os ancestrais dos objetos a serem criados:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(use (srfi 1))&lt;br /&gt;&lt;br /&gt;(define-macro (cria tipo atributos pais)&lt;br /&gt;  `(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;letrec&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;       ((tipo ,tipo)&lt;br /&gt;        (tipos (cons ,tipo&lt;br /&gt;                     (map (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (pai)&lt;br /&gt;                            (pai 'tipo))&lt;br /&gt;                          ,pais)))&lt;br /&gt;        (supers (apply append&lt;br /&gt;                       (map (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (pai)&lt;br /&gt;                              (alist-copy (pai 'atributos)))&lt;br /&gt;                            ,pais)))&lt;br /&gt;        (atributos ,atributos)&lt;br /&gt;        (this (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (var)&lt;br /&gt;                (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; (alist-ref var atributos)&lt;br /&gt;                    (alist-ref var supers)))))&lt;br /&gt;     (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; args&lt;br /&gt;       (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? args)&lt;br /&gt;           (error &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Nenhuma mensagem.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;           (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((acao (car args)))&lt;br /&gt;             (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;case&lt;/FONT&gt;&lt;/B&gt; acao&lt;br /&gt;               ((&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;set!&lt;/FONT&gt;&lt;/B&gt;) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((atrib (cadr args))&lt;br /&gt;                             (valor (caddr args)))&lt;br /&gt;                         (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (alist-ref atrib atributos)&lt;br /&gt;                             (alist-update! atrib valor&lt;br /&gt;                                            atributos)&lt;br /&gt;                             (alist-update! atrib valor&lt;br /&gt;                                            supers))&lt;br /&gt;                         (void)))&lt;br /&gt;               ((get) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((atributo (this (cadr args))))&lt;br /&gt;                        (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; atributo&lt;br /&gt;                            (error &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Atributo inexistente.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;br /&gt;               ((tipo) tipo)&lt;br /&gt;               ((atributos) (append supers atributos))&lt;br /&gt;               ((is-a?) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (t)&lt;br /&gt;                          (not (not (memq t tipos)))))&lt;br /&gt;               (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;else&lt;/FONT&gt;&lt;/B&gt; (error &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Mensagem nao conhecida.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;               ))))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;csi&amp;gt; (define obj (cria 'ponto&lt;br /&gt;---&amp;gt;                   `((pos-x . 0)&lt;br /&gt;---&amp;gt;                     (pos-y . 0)&lt;br /&gt;---&amp;gt;                     (posicao . ,(lambda ()&lt;br /&gt;---&amp;gt;                                   (cons (this 'pos-x)&lt;br /&gt;---&amp;gt;                                         (this 'pos-y)))))&lt;br /&gt;---&amp;gt;                   '()))&lt;br /&gt;csi&amp;gt;&lt;br /&gt;csi&amp;gt; (obj 'get 'pos-x)&lt;br /&gt;0&lt;br /&gt;csi&amp;gt; (obj 'set! 'pos-x 30)&lt;br /&gt;csi&amp;gt; (obj 'get 'pos-x)&lt;br /&gt;30&lt;br /&gt;csi&amp;gt; (obj 'tipo)&lt;br /&gt;ponto&lt;br /&gt;csi&amp;gt; ((obj 'is-a?) 'ponto)&lt;br /&gt;#t&lt;br /&gt;csi&amp;gt; ((obj 'is-a?) 'ponto00)&lt;br /&gt;#f&lt;br /&gt;csi&amp;gt;&lt;br /&gt;csi&amp;gt; (define obj2 (cria 'ponto-3D&lt;br /&gt;---&amp;gt;                    `((pos-z . 0)&lt;br /&gt;---&amp;gt;                      (posicao . ,(lambda ()&lt;br /&gt;---&amp;gt;                                    (list (this 'pos-x)&lt;br /&gt;---&amp;gt;                                          (this 'pos-y)&lt;br /&gt;---&amp;gt;                                          (this 'pos-z)))))&lt;br /&gt;---&amp;gt;                    (list obj)))&lt;br /&gt;csi&amp;gt;&lt;br /&gt;csi&amp;gt; ((obj2 'is-a?) 'ponto)&lt;br /&gt;#t&lt;br /&gt;csi&amp;gt; (obj2 'get 'pos-x)&lt;br /&gt;30&lt;br /&gt;csi&amp;gt; (obj2 'set! 'pos-x 90)&lt;br /&gt;csi&amp;gt; (obj 'get 'pos-x)&lt;br /&gt;30&lt;br /&gt;csi&amp;gt; (obj2 'get 'pos-x)&lt;br /&gt;90&lt;br /&gt;csi&amp;gt; ((obj2 'get 'posicao))&lt;br /&gt;(90 0 0)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; O sistema de objetos mostrado aqui não utiliza classes para a representação de características de objetos.  As características de objetos são representadas em uma função geradora de objetos.  A herança utiliza objetos para a representação de ancestrais, não classes, havendo a clonagem dos objetos usados como ancestrais. A ordem para resolução de atributos é a ordem de passagem de ancestrais na criação de objetos, ou seja, se dois ancestrais possuem um atributo comum, o atributo do primeiro antecestral será o usado pelo objeto filho.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-1316142630478438269?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/1316142630478438269/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=1316142630478438269' title='3 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1316142630478438269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/1316142630478438269'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/05/objetos-em-scheme.html' title='Objetos em Scheme'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-4697093940922470895</id><published>2008-05-08T07:06:00.000-07:00</published><updated>2008-05-08T19:14:29.429-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='repl'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Clip no REPL</title><content type='html'>A procrastinação leva o cara a fazer coisas como essa:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(use utils)&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;stupid-clip&lt;/FONT&gt;&lt;/B&gt; text)&lt;br /&gt;  (string-append&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; --&lt;br /&gt;/  \\&lt;br /&gt;|  |&lt;br /&gt;@  @&lt;br /&gt;|| ||&lt;br /&gt;|| ||&lt;br /&gt;|\\_/|&lt;br /&gt;\\___/\n&lt;br /&gt;&lt;br /&gt;What do you want to mess up with today?&lt;br /&gt;&lt;br /&gt;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;text&lt;br /&gt;))&lt;br /&gt;&lt;br /&gt;(toplevel-command&lt;br /&gt; 'annoy&lt;br /&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;   (print&lt;br /&gt;    (stupid-clip (with-output-to-string&lt;br /&gt;                   (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;                     (apropos (read))))))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Usando isso no REPL:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;$ csi -n&lt;br /&gt;&lt;br /&gt;CHICKEN&lt;br /&gt;(c)2008 The Chicken Team&lt;br /&gt;(c)2000-2007 Felix L. Winkelmann&lt;br /&gt;Version 3.2.0 - linux-unix-gnu-x86 [ manyargs dload ptables applyhook ]&lt;br /&gt;SVN rev. 10664  compiled 2008-05-07 on ze-dureza (Linux)&lt;br /&gt;&lt;br /&gt;#;1&gt; (load "annoy.scm")&lt;br /&gt;; loading annoy.scm ...&lt;br /&gt;; loading library utils ...&lt;br /&gt;#;2&gt; ,annoy close&lt;br /&gt; --&lt;br /&gt;/  \&lt;br /&gt;|  |&lt;br /&gt;@  @&lt;br /&gt;|| ||&lt;br /&gt;|| ||&lt;br /&gt;|\_/|&lt;br /&gt;\___/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;What do you want to mess up with today?&lt;br /&gt;&lt;br /&gt;close-input-port  : (procedure port948)&lt;br /&gt;close-input-file  : variable&lt;br /&gt;close-output-file : variable&lt;br /&gt;close-output-port : (procedure port949)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;b&gt;Atualização&lt;/b&gt;&lt;br /&gt;&lt;br /&gt; Na realidade, o código pode ser um pouco mais simples:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;br /&gt;(use utils)&lt;br /&gt;&lt;br /&gt;(toplevel-command&lt;br /&gt; 'annoy&lt;br /&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;   (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; --&lt;br /&gt;/  \\&lt;br /&gt;|  |&lt;br /&gt;@  @&lt;br /&gt;|| ||&lt;br /&gt;|| ||&lt;br /&gt;|\\_/|&lt;br /&gt;\\___/\n&lt;br /&gt;&lt;br /&gt;What do you want to mess up with today?&lt;br /&gt;&lt;br /&gt;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;   (apropos (read))))&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-4697093940922470895?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/4697093940922470895/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=4697093940922470895' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4697093940922470895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/4697093940922470895'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/05/clip-no-repl.html' title='Clip no REPL'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-5714780903665534949</id><published>2008-05-08T04:36:00.000-07:00</published><updated>2008-05-08T05:20:02.614-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Apresentações em Scheme</title><content type='html'>Não sou um especialista em apresentações, mas de vez em quando surgem algumas para eu fazer.  Não tenho o hábito de usar softwares para edição de apresentações como o &lt;a  href="http://www.openoffice.org/product/impress.html"&gt;Impress&lt;/a&gt; do &lt;a  href="http://www.openoffice.org"&gt;Openoffice.org&lt;/a&gt; (é uma questão de preferência pessoal como usuário -- nada contra o Openoffice.org).  Sobretudo, faço as apresentações com o visual mais simples possível, normalmente fundo branco com letras pretas, como uma página de livro tradicional.&lt;br /&gt;&lt;br /&gt; Durante um bom tempo fui usuário de &lt;a  href="http://www.latex-project.org/"&gt;LaTeX&lt;/a&gt; (cheguei a fazer uma classe para apresentações -- &lt;a  href="http://g3pd.ucpel.tche.br/~mario/utils/pauerpoint/"&gt;Pauerpoint&lt;/a&gt;), mas algumas coisas são desnecessariamente difíceis de se fazer em &lt;a  href="http://www.latex-project.org/"&gt;LaTeX&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt; Então me ocorreu a idéia de implementar algo em Scheme para fazer apresentações.  Com o uso de &lt;a  href="http://www.w3.org/Talks/Tools/Slidy"&gt;algumas coisas prontas em CSS e Javascript&lt;/a&gt;, a implementação em Scheme é surpreendentemente simples:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(use web-scheme)&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;slide&lt;/FONT&gt;&lt;/B&gt; title-text . contents)&lt;br /&gt;  (div 'class &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;slide&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;       (h1 title-text)&lt;br /&gt;       (string-intersperse contents)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;cover&lt;/FONT&gt;&lt;/B&gt; title-text . contents)&lt;br /&gt;  (div 'class &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;slide cover&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;       (h1 title-text)&lt;br /&gt;       (string-intersperse contents)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;presentation&lt;/FONT&gt;&lt;/B&gt; . slides)&lt;br /&gt;  (ws:page&lt;br /&gt;   (string-intersperse slides)&lt;br /&gt;   additional-headers: (string-append&lt;br /&gt;                        (link 'rel &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;stylesheet&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                              'type &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;text/css&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                              'media &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;screen, projection&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                              'href &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;show.css&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;                        (script 'src &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;slidy.js&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                                'type &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;text/javascript&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;/pre&gt;&lt;br /&gt; O código acima, em &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; Scheme, mostra as três funções para a montagem de uma apresentação. As partes de CSS e Javascript são do &lt;a  href="http://www.w3.org/Talks/Tools/Slidy"&gt;HTML Slidy&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt; Para criar uma apresentação, basta fazer algo como:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(presentation&lt;br /&gt;    (cover &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Minha capa&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;    (slide &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Introdução&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;    (slide &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Fim&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Para gerar o código HTML, que pode ser visualizado em qualquer browser, executo:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;$ web-scheme2html minha-apresentacao.scm &gt; minha-apresentacao.html&lt;/pre&gt;&lt;br /&gt; &lt;code&gt;web-scheme2html&lt;/code&gt; é um script que acompanha a extensão &lt;a  href="http://chicken.wiki.br/web-scheme"&gt;web-scheme&lt;/a&gt; de &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt; Em &lt;a  href="http://g3pd.ucpel.tche.br/~mario/misc/upgrade-v2"&gt;http://g3pd.ucpel.tche.br/~mario/misc/upgrade-v2&lt;/a&gt; está um exemplo de apresentação que fiz sobre programação para a Web com Scheme (boa parte da apresentação é sobre o básico da linguagem).  O código fonte da apresentação está em &lt;a  href="http://g3pd.ucpel.tche.br/~mario/misc/upgrade-v2/index.ws"&gt;http://g3pd.ucpel.tche.br/~mario/misc/upgrade-v2/index.ws&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-5714780903665534949?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/5714780903665534949/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=5714780903665534949' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5714780903665534949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/5714780903665534949'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/05/apresentaes-em-scheme.html' title='Apresentações em Scheme'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-8974680093110074576</id><published>2008-05-06T15:48:00.000-07:00</published><updated>2008-05-06T16:09:09.519-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Compilador ingênuo de Scheme para Javascript</title><content type='html'>Por curiosidade, há algum tempo tentei ver como seria fazer um compilador simples de Scheme para Javascript.  Obviamente, um compilador "de verdade" não é uma tarefa fácil, embora haja &lt;a  href="http://www.omnigia.com/scheme/cpscm/home"&gt;esforços nesta direção&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt; De qualquer forma, é impressionante o que dá para fazer com algumas poucas linhas de código. :-)&lt;br /&gt;&lt;br /&gt; Várias formas básicas de Scheme não estão implementadas: &lt;code&gt;cond&lt;/code&gt;, &lt;code&gt;begin&lt;/code&gt;, &lt;code&gt;call/cc&lt;/code&gt; e muitas outras.&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;#!/usr/bin/csi -script&lt;br /&gt;&lt;br /&gt;(use (srfi 1))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;infix-op&lt;/FONT&gt;&lt;/B&gt; op args)&lt;br /&gt;  (string-intersperse&lt;br /&gt;   (map -&amp;gt;string (map scm-&amp;gt;js args)) (-&amp;gt;string op)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;mapconcat&lt;/FONT&gt;&lt;/B&gt; elts #!optional sep)&lt;br /&gt;  (string-intersperse (map -&amp;gt;string elts) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; sep &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;scm-body-&amp;gt;js&lt;/FONT&gt;&lt;/B&gt; body)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((body-butlast (butlast body))&lt;br /&gt;        (last-expr (last body)))&lt;br /&gt;    (conc (mapconcat (map scm-&amp;gt;js body-butlast) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;return &amp;quot;&lt;/FONT&gt;&lt;/B&gt; (scm-&amp;gt;js last-expr) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;  &lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;scm-&amp;gt;js&lt;/FONT&gt;&lt;/B&gt; expr)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (atom? expr)&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;cond&lt;/FONT&gt;&lt;/B&gt; ((string? expr)&lt;br /&gt;             (conc &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;'&amp;quot;&lt;/FONT&gt;&lt;/B&gt; expr &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;'&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;            ((boolean? expr)&lt;br /&gt;             (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (eq? expr '#t) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;true&amp;quot;&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;false&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;            (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;else&lt;/FONT&gt;&lt;/B&gt; expr))&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;case&lt;/FONT&gt;&lt;/B&gt; (car expr)&lt;br /&gt;        ((&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt;) (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((condition (cadr expr))&lt;br /&gt;                    (branch1 (caddr expr))&lt;br /&gt;                    (branch2 (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; (= 4 (length expr))&lt;br /&gt;                                  (cadddr expr))))&lt;br /&gt;                (conc &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;(function(){if(&amp;quot;&lt;/FONT&gt;&lt;/B&gt; (scm-&amp;gt;js condition)&lt;br /&gt;                      &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;){return(&amp;quot;&lt;/FONT&gt;&lt;/B&gt; (scm-&amp;gt;js branch1) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;);}&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; branch2&lt;br /&gt;                          (conc &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;else{return(&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                                (scm-&amp;gt;js branch2) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;);}&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;                          &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;                      &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;})();&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))&lt;br /&gt;        ((return) (conc &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;return(&amp;quot;&lt;/FONT&gt;&lt;/B&gt; (scm-&amp;gt;js (cadr expr))&lt;br /&gt;                        &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;);&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;        ((&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;         (conc &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;function&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;               (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? (cadr expr))&lt;br /&gt;                   &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;()&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                   (conc &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;(&amp;quot;&lt;/FONT&gt;&lt;/B&gt; (mapconcat (cadr expr) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;,&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;                         &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;)&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;{&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                         (scm-body-&amp;gt;js (cddr expr)) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;}&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;        ((&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt;) (conc &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;;var &amp;quot;&lt;/FONT&gt;&lt;/B&gt; (cadr expr) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;=&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                        (scm-&amp;gt;js (caddr expr)) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;        ((+ - * / &amp;lt; &amp;gt;)  (infix-op (car expr) (cdr expr)))&lt;br /&gt;        ((=)  (infix-op '== (cdr expr)))&lt;br /&gt;        ((&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt;) (infix-op &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;||&amp;quot;&lt;/FONT&gt;&lt;/B&gt; (cdr expr)))&lt;br /&gt;        ((&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt;) (infix-op &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;amp;&amp;amp;&amp;quot;&lt;/FONT&gt;&lt;/B&gt; (cdr expr)))&lt;br /&gt;        ((&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt;) (conc &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;(function(){&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                     (string-intersperse&lt;br /&gt;                      (map (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (binding)&lt;br /&gt;                             (conc &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;var &amp;quot;&lt;/FONT&gt;&lt;/B&gt; (car binding) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;=&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                                   (scm-&amp;gt;js (cadr binding))&lt;br /&gt;                                   &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;                           (cadr expr)))&lt;br /&gt;                     (scm-body-&amp;gt;js (cddr expr))&lt;br /&gt;                     &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;})()&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;        ((&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt;) (scm-&amp;gt;js (macroexpand expr)))&lt;br /&gt;        (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;else&lt;/FONT&gt;&lt;/B&gt; (conc (car expr) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;(&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                    (string-intersperse&lt;br /&gt;                     (map -&amp;gt;string&lt;br /&gt;                          (map scm-&amp;gt;js (cdr expr)))&lt;br /&gt;                     &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;,&amp;quot;&lt;/FONT&gt;&lt;/B&gt;) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;)&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;js&lt;/FONT&gt;&lt;/B&gt; exprs)&lt;br /&gt;  (string-intersperse (map scm-&amp;gt;js exprs) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;&lt;br /&gt;(print (js (read-file (car (command-line-arguments)))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Alguns exemplos "práticos" estão a seguir. &lt;code&gt;scm2js.scm&lt;/code&gt; é o compilador, implementado em &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; Scheme; &lt;code&gt;js&lt;/code&gt; é um &lt;a  href="http://www.mozilla.org/js/spidermonkey/"&gt;interpretador de Javascript&lt;/a&gt; que pode ser executado na linha de comando.&lt;br /&gt;&lt;br /&gt; Obs.: o código Javascript gerado é bastante indigesto:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;$ ./scm2js.scm ex1.scm&lt;/pre&gt;&lt;br /&gt; &lt;tt&gt;;var fatorial=function(n){;return (function(){if(n&lt;1){return(1);}else{return(n*fatorial(n-1));}})();;};print(fatorial(4))&lt;/tt&gt; &lt;pre&gt;$ cat ex1.scm&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;fatorial&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (n)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (&amp;lt; n 1)&lt;br /&gt;        1&lt;br /&gt;        (* n (fatorial (- n 1))))))&lt;br /&gt;&lt;br /&gt;(print (fatorial 4))&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;$ ./scm2js.scm ex1.scm | js&lt;br /&gt;24&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;$ cat ex2.scm&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;a&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (n)&lt;br /&gt;            (print &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;aqui&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;            n))&lt;br /&gt;(print (a 6))&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;$ ./scm2js.scm ex2.scm | js&lt;br /&gt;aqui&lt;br /&gt;6&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;$ cat ex3.scm&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;x&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; #t &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;ok&amp;quot;&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;false&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;(print x)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt; $ ./scm2js.scm ex3.scm | js&lt;br /&gt;ok&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;$ cat ex4.scm&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;func&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (a b c d)&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((a (+ b c d))&lt;br /&gt;           (dif (- a b c d)))&lt;br /&gt;      (+ a dif))))&lt;br /&gt;&lt;br /&gt;(print (func 1 2 3 4))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;pre&gt;$ ./scm2js.scm ex4.scm | js&lt;br /&gt;9&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-8974680093110074576?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/8974680093110074576/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=8974680093110074576' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8974680093110074576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/8974680093110074576'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/05/por-curiosidade-h-algum-tempo-tentei.html' title='Compilador ingênuo de Scheme para Javascript'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-7240081251193807512</id><published>2008-05-06T06:24:00.000-07:00</published><updated>2008-05-06T08:16:16.583-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web-scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Código formatado no Blogger</title><content type='html'>A minha primeira tentiva de escrita de código no Blogger foi frustrante: sem destaque de sintaxe (&lt;i&gt;syntax highlight&lt;/i&gt;) e um editor com poucos recursos.&lt;br /&gt;&lt;br /&gt; Vi que a marcação do texto era feita com HTML (surpresa!) e decidi fazer um script para gerar texto formatado para o Blogger.  Faço a marcação do texto com &lt;a  href="http://chicken.wiki.br/web-scheme"&gt;web-scheme&lt;/a&gt; e o programa se encarrega de gerar o HTML.  Depois só copio e colo o código HTML na caixa de edição do Blogger.&lt;br /&gt;&lt;br /&gt; O programa para geração de HTML está a seguir (em &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; Scheme).  O "embelezamento" do código é feito com o programa &lt;a  href="http://www.gnu.org/software/enscript/"&gt;Enscript&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(use posix utils web-scheme (srfi 1))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;run&lt;/FONT&gt;&lt;/B&gt; . cmd)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((p (open-input-pipe (sprintf &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;~A 2&amp;gt;&amp;amp;1&amp;quot;&lt;/FONT&gt;&lt;/B&gt; (apply conc cmd)))))&lt;br /&gt;    (read-all p)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;run-enscript&lt;/FONT&gt;&lt;/B&gt; code lang #!optional pretty)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((tmp (create-temporary-file)))&lt;br /&gt;    (with-output-to-file tmp (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; ()&lt;br /&gt;                               (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; pretty&lt;br /&gt;                                   (pp code)&lt;br /&gt;                                   (print code))))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((out (run &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;enscript -q --color --highlight=&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;                    lang &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; -o - -whtml &amp;quot;&lt;/FONT&gt;&lt;/B&gt; tmp)))&lt;br /&gt;      (delete-file tmp)&lt;br /&gt;      out)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;htmlize&lt;/FONT&gt;&lt;/B&gt; code lang #!optional no-pre)&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let*&lt;/FONT&gt;&lt;/B&gt; ((out (run-enscript code lang (not (string? code))))&lt;br /&gt;         (lines (with-input-from-string out read-lines)))&lt;br /&gt;    (string-append&lt;br /&gt;     ((&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; no-pre &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; pre nao quebra linhas&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;          tt&lt;br /&gt;          pre)&lt;br /&gt;      (string-intersperse&lt;br /&gt;       &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; retira cabecalho e rodape colocados pelo enscript&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;       (drop-right (take-right lines (- (length lines) 11)) 5)&lt;br /&gt;       &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;\n&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;     (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; no-pre &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;\n&amp;quot;&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; -&amp;gt;&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((bookmarks&lt;br /&gt;         '((Chicken . &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;http://www.call-with-current-continuation.org&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;           (web-scheme . &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;http://chicken.wiki.br/web-scheme&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;           (eggs . &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;http://chicken.wiki.br/eggs&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))))&lt;br /&gt;    (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;lambda&lt;/FONT&gt;&lt;/B&gt; (url #!optional text)&lt;br /&gt;      (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((bookmarked (alist-ref url bookmarks)))&lt;br /&gt;        (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;and&lt;/FONT&gt;&lt;/B&gt; (symbol? url) bookmarked)&lt;br /&gt;            (a 'href bookmarked (symbol-&amp;gt;string url))&lt;br /&gt;            (a 'href url (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;or&lt;/FONT&gt;&lt;/B&gt; text url)))))))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;p&lt;/FONT&gt;&lt;/B&gt; . text) &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;;; paragrafo do blogger&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;  (string-append (apply conc text) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;\n\n&amp;quot;&lt;/FONT&gt;&lt;/B&gt;))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;define&lt;/FONT&gt;&lt;/B&gt; (&lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;usage&lt;/FONT&gt;&lt;/B&gt; #!optional exit-code)&lt;br /&gt;  (print (program-name) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; &amp;lt;input-file&amp;gt;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  (when exit-code (exit exit-code)))&lt;br /&gt;&lt;br /&gt;(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;let&lt;/FONT&gt;&lt;/B&gt; ((args (command-line-arguments)))&lt;br /&gt;  (&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; (null? args)&lt;br /&gt;      (usage 1)&lt;br /&gt;      (print&lt;br /&gt;       (string-intersperse&lt;br /&gt;        (map eval (with-input-from-file (car args) read-file))))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; A função &lt;code&gt;-&gt;&lt;/code&gt; é especialmente interessante: admite como argumentos uma URL e um texto, somente uma URL, ou uma palavra-chave para acesso aos &lt;i&gt;bookmarks&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt; O código fonte &lt;b&gt;deste artigo inteiro&lt;/b&gt;  é:&lt;br /&gt;&lt;br /&gt; &lt;tt&gt;(p &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;A minha primeira tentiva de escrita de código no Blogger foi frustrante: sem destaque de sintaxe (&amp;quot;&lt;/FONT&gt;&lt;/B&gt; (i &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;syntax highlight&amp;quot;&lt;/FONT&gt;&lt;/B&gt;) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;) e um editor com poucos recursos.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;&lt;br /&gt;(p &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Vi que a marcação do texto era feita com HTML (surpresa!) e decidi fazer um script para gerar texto formatado para o Blogger.  Faço a marcação do texto com &amp;quot;&lt;/FONT&gt;&lt;/B&gt; (-&amp;gt; 'web-scheme) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; e o programa se encarrega de gerar o HTML.  Depois só copio e colo o código HTML na caixa de edição do Blogger.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;&lt;br /&gt;(p &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;O programa para geração de HTML está a seguir (em &amp;quot;&lt;/FONT&gt;&lt;/B&gt; (-&amp;gt; 'Chicken) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; Scheme).  O \&amp;quot;embelezamento\&amp;quot; do código é feito com o programa &amp;quot;&lt;/FONT&gt;&lt;/B&gt; (-&amp;gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;http://www.gnu.org/software/enscript/&amp;quot;&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Enscript&amp;quot;&lt;/FONT&gt;&lt;/B&gt;) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;&lt;br /&gt;(htmlize (read-all &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;./bin/blog.scm&amp;quot;&lt;/FONT&gt;&lt;/B&gt;) 'scheme)&lt;br /&gt;&lt;br /&gt;(p &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;A função &amp;quot;&lt;/FONT&gt;&lt;/B&gt; (code &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;-&amp;gt;&amp;quot;&lt;/FONT&gt;&lt;/B&gt;) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot; é especialmente interessante: admite como argumentos uma URL e um texto, somente uma URL, ou uma palavra-chave para acesso aos &amp;quot;&lt;/FONT&gt;&lt;/B&gt; (i &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;bookmarks&amp;quot;&lt;/FONT&gt;&lt;/B&gt;) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;.&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;&lt;br /&gt;(p &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;O código fonte &amp;quot;&lt;/FONT&gt;&lt;/B&gt; (b &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;deste artigo inteiro&amp;quot;&lt;/FONT&gt;&lt;/B&gt;) &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;  é:&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;&lt;br /&gt;(htmlize (read-all &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;./call-hc/codigo-formatado-no-blogger.scm&amp;quot;&lt;/FONT&gt;&lt;/B&gt;) 'scheme 'no-pre)&lt;br /&gt;&lt;/tt&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7213650200249361122-7240081251193807512?l=call-with-hopeless-continuation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://call-with-hopeless-continuation.blogspot.com/feeds/7240081251193807512/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7213650200249361122&amp;postID=7240081251193807512' title='3 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7240081251193807512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7213650200249361122/posts/default/7240081251193807512'/><link rel='alternate' type='text/html' href='http://call-with-hopeless-continuation.blogspot.com/2008/05/cdigo-formatado-no-blogger.html' title='Código formatado no Blogger'/><author><name>Mario Domenech Goulart</name><uri>http://www.blogger.com/profile/12469685106259862011</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7213650200249361122.post-6379672657222070246</id><published>2008-05-05T08:11:00.000-07:00</published><updated>2008-05-06T07:40:19.181-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web-scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='chicken'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>web-scheme for dummies</title><content type='html'>&lt;a  href="http://chicken.wiki.br/web-scheme"&gt;web-scheme&lt;/a&gt; é uma extensão do sistema do sistema &lt;a  href="http://www.call-with-current-continuation.org"&gt;Chicken&lt;/a&gt; que implementa uma linguagem de programação baseada em Scheme para a Web.&lt;br /&gt;&lt;br /&gt; &lt;a  href="http://chicken.wiki.br/web-scheme"&gt;web-scheme&lt;/a&gt; disponibiliza funções para a geração de código HTML a partir de código Scheme.  Exemplo:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(div 'id &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;caixa&amp;quot;&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Texto&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;/pre&gt;&lt;br /&gt; produz a string&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;div  id=&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;caixa&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;Texto&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/div&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Todas as tags de HTML são representadas como funções em Scheme de mesmo nome, exceto nomes conflitantes, como, por exemplo, &lt;code&gt;map&lt;/code&gt; e &lt;code&gt;select&lt;/code&gt; (nomeadas &lt;code&gt;ws:map&lt;/code&gt; e &lt;code&gt;ws:select&lt;/code&gt;, respectivamente).&lt;br /&gt;&lt;br /&gt; Além da representação de tags HTML como funções em Scheme, &lt;a  href="http://chicken.wiki.br/web-scheme"&gt;web-scheme&lt;/a&gt; também disponibiliza algumas funções que podem facilitar a geração de código HTML.&lt;br /&gt;&lt;br /&gt; Um exemplo é a função &lt;code&gt;ws:page&lt;/code&gt;, para gerar páginas HTML de forma desburocratizada.  Exemplo:&lt;br /&gt;&lt;br /&gt; &lt;pre&gt;(ws:page &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Oi&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;/pre&gt;&lt;br /&gt; gera a seguinte string com código HTML:&lt;br /&gt;&lt;br /&gt; &lt;tt&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;!DOCTYPE HTML PUBLIC &lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; &lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;html&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;head&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;meta  http-equiv=&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;Content-Type&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; content=&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;text/html; charset=iso-8859-1&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;title&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/title&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/head&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;body&amp;gt;&lt;/FONT&gt;&lt;/B&gt;Oi&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/body&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/html&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt; É possível alterar o código HTML gerado por &lt;code&gt;ws:page&lt;/code&gt; através do uso de parâmetros.  Por exemplo, o conjunto de caracteres da página pode ser alterado com o parâmetro &lt;code&gt;charset&lt;/code&gt;:&lt;br /&gt;&lt;b
