<?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-3006142001944566780</id><updated>2012-02-17T01:52:28.275-02:00</updated><category term='sociedade'/><category term='conto'/><category term='dança'/><category term='política'/><category term='manga'/><category term='SIVUCA'/><category term='literatura'/><category term='java'/><category term='software'/><category term='cinema'/><category term='filosofia'/><category term='anime'/><category term='etc'/><category term='música'/><category term='quadrinhos'/><category term='crônica'/><category term='cxx'/><title type='text'>Tumulto</title><subtitle type='html'>...do cansaço dessa vida, e do peso de ter que ser alguém...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/-/software'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/search/label/software'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/-/software/-/software?start-index=26&amp;max-results=25'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>46</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-3939253268873345034</id><published>2010-05-10T20:47:00.000-03:00</published><updated>2010-05-10T20:47:36.708-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Web Services infinitamente fáceis com JAX-WS</title><content type='html'>Isso provavelmente é notícia antiga para os praticantes do J2EE, mas hoje eu aprendi a notação mais básica do JAX-WS e estou impressionado com o esquema em geral.&lt;br /&gt;&lt;br /&gt;Eu experimentei um pouco com o esquema do Apache Axis e, apesar de fácil, me fez um pouco perdido por não dominar ainda o macete dos arquivos de configuração e dos artefatos gerados.&lt;br /&gt;&lt;br /&gt;Fora isso, eu não vi, no tanto que estudei, o meio de trocar argumentos de um tipo não primitivo com o Axis, o que me deixou um pouco ressabiado -- ou é difícil, ou é impossível.&lt;br /&gt;&lt;br /&gt;Agora, com o Metro no GlassFish?&lt;br /&gt;&lt;br /&gt;@WebService&lt;br /&gt;public class Echo {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String echo (String value) { return value; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Está pronto o EchoService.&lt;br /&gt;&lt;br /&gt;Empacotando este negócio em um "Dynamic Web Project" e implantando no GlassFish, o Metro descobre sozinho a existência da classe Echo e configura automaticamente um EchoService muito razoável.&lt;br /&gt;&lt;br /&gt;Eu achei, originalmente, que era preciso instalar a ferramenta Apache CXF na incubadora do projeto Eclipse Web Tools mas é desnecessário.&lt;br /&gt;&lt;br /&gt;Aparentemente, a engenharia da norma JAX-WS foi muito boa, e existe também uma JAX-B que especifica a tradução de "java" para "xsd" de um modo que o seguinte também funciona como esperado:&lt;br /&gt;&lt;br /&gt;public class Bar {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String data;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Bar (String data) { this.data = data; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@WebService&lt;br /&gt;public class Echo {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Bar echo (String value) { return new Bar(value); }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;É tudo o que eu preciso pra passar de fase.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-3939253268873345034?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/3939253268873345034/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=3939253268873345034' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/3939253268873345034'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/3939253268873345034'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2010/05/web-services-infinitamente-faceis-com.html' title='Web Services infinitamente fáceis com JAX-WS'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-3654367210115631952</id><published>2010-04-24T18:01:00.000-03:00</published><updated>2010-04-24T20:30:32.920-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>GlassFish em servidor Fedora 11</title><content type='html'>Consegui, afinal, configurar um servidor Fedora 11 com o GlassFish instalado.&lt;br /&gt;&lt;br /&gt;Estou usando o seguinte script em /etc/init.d para gerenciar o serviço no sistema.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;#!/bin/sh&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;#&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;# glassfish Sun GlassFish v3&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;#&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;# chkconfig:&amp;nbsp;&amp;nbsp; - 99 1&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;# description: Sun's modern J2EE implementation based on OSGi&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;### BEGIN INIT INFO&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;# Provides: glassfish&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;# Required-Start: $network&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;# Required-Stop: $network&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;# Short-Description: J2EE implementation&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;# Description: Sun's modern J2EE implementation based on OSGi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;### END INIT INFO&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;# Source function library.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;. /etc/rc.d/init.d/functions&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;exec="/opt/glassfishv3/glassfish/bin/asadmin"&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;prog="glassfish"&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;config="/opt/glassfishv3/glassfish/domains/domain1/config/domain.xml"&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[ -e /etc/sysconfig/$prog ] &amp;amp;&amp;amp; . /etc/sysconfig/$prog&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;lockfile=/var/lock/subsys/$prog&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;start() {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ -x $exec ] || exit 5&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ -f $config ] || exit 6&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; echo -n $"Starting $prog: "&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ${exec} start-domain domain1 &amp;gt;/dev/null 2&amp;gt;&amp;amp;1&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; retval=$?&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ $retval -eq 0 ] &amp;amp;&amp;amp; success $"$prog startup" || failure $"$prog startup"&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; echo&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ $retval -eq 0 ] &amp;amp;&amp;amp; touch $lockfile&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return $retval&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;stop() {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; echo -n $"Stopping $prog: "&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ${exec} stop-domain &amp;gt;/dev/null 2&amp;gt;&amp;amp;1&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; retval=$?&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ $retval -eq 0 ] &amp;amp;&amp;amp; success $"$prog shutdown" || failure $"$prog shutdown"&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; echo&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ $retval -eq 0 ] &amp;amp;&amp;amp; rm -f $lockfile&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return $retval&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;restart() {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stop&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; start&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;reload() {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; restart&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;force_reload() {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; restart&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;rh_status() {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ${exec} uptime&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; uptime_retval=$?&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if [ $uptime_retval -eq 0 ]; then&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fi&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if [ -z $lockfile ]; then&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 2&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fi&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 3&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;rh_status_q() {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rh_status &amp;gt;/dev/null 2&amp;gt;&amp;amp;1&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;case "$1" in&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; start)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rh_status_q &amp;amp;&amp;amp; exit 0&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $1&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stop)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rh_status_q || exit 0&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $1&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; restart)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $1&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; reload)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rh_status_q || exit 7&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $1&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; force-reload)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; force_reload&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; status)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rh_status&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; condrestart|try-restart)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rh_status_q || exit 0&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; restart&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; *)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit 2&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;esac&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;exit $?&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-3654367210115631952?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/3654367210115631952/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=3654367210115631952' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/3654367210115631952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/3654367210115631952'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2010/04/glassfish-em-servidor-fedora-11.html' title='GlassFish em servidor Fedora 11'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-4454663766171323473</id><published>2010-04-07T00:41:00.002-03:00</published><updated>2010-04-24T20:30:25.137-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Algoritmos da Amazon</title><content type='html'>"As someone who has purchased or rated books by Erich Gamma, you might like to know that &lt;i&gt;How You Could Be A Better Friend&lt;/i&gt; is now available."&lt;br /&gt;&lt;br /&gt;(...)&lt;br /&gt;&lt;br /&gt;Amazon, Erich Gamma é autor de um livro sobre engenharia de software. Que porra é essa?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-4454663766171323473?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/4454663766171323473/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=4454663766171323473' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4454663766171323473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4454663766171323473'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2010/04/algoritmos-da-amazon.html' title='Algoritmos da Amazon'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-7503640128285063032</id><published>2010-03-31T01:14:00.002-03:00</published><updated>2010-04-24T20:29:36.844-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>O estilo funcional em C++</title><content type='html'>Estava de mau humor e resolvi ironizar a vida estudando numa aula de Java o artigo "&lt;a href="http://www.md.chalmers.se/%7Erjmh/Papers/whyfp.html"&gt;Why Functional Programming Matters&lt;/a&gt;", que eu copiei do site do Haskell.&lt;br /&gt;&lt;br /&gt;Acabei finalmente entendendo (eu acho!) as primeiras implicações importantes de &lt;i&gt;lazy evaluation&lt;/i&gt;. O exemplo mais simples dessas implicações no artigo, na minha opinião, está no programa que computa aproximações da raiz quadrada pelo método de Newton-Raphson.&lt;br /&gt;&lt;br /&gt;Esse método é basicamente uma expressão matemática que começa com um resultado anterior e usa esse resultado para computar um próximo, garantindo que o próximo é melhor que o anterior.&lt;br /&gt;&lt;br /&gt;Seja N o número cuja raiz quadrada você deseja aproximar, e uma aproximação anterior x. O procedimento começa chutando x, por exemplo 1. O método afirma que o próximo x deve ser &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;( x + ( N / x ) / 2&lt;/span&gt; .&lt;br /&gt;&lt;br /&gt;O artigo descreve um programa para resolver o método. O programa segue abaixo; para entendê-lo completamente, estude o artigo.&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;repeat f a = cons a ( repeat f ( f a ) )&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;within e ( cons a ( cons b rest ) ) =&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; = b , if abs(a - b) &amp;lt;= eps&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; = within e ( cons b rest), otherwise&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;next N x = ( x + N / x ) / 2&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;sqrt a0 e N = within e ( repeat ( next N ) a0 )&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O espírito geral do programa é assim:&lt;br /&gt;&lt;br /&gt;repeat é uma função que gera uma lista contendo um elemento inicial seguido do resultado da função f com argumento elemento-anterior. Observe que repeat gera uma lista infinita, assumindo que f está definida para todo a.&lt;br /&gt;&lt;br /&gt;within é uma função que percorre uma lista procurando um par de elementos cuja diferença seja menor que um &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;epsilon&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;A notação de parâmetros em within faz o que eu chamo de "desempacotar a lista". O segundo argumento é uma lista; a definição de within desempacota os dois primeiros, chamando-os de a e b. &lt;br /&gt;&lt;br /&gt;next computa a próxima aproximação da raiz quadrada de N com aproximação anterior x segundo o método de Newton-Raphson.&lt;br /&gt;&lt;br /&gt;sqrt computa a raiz quadrada de um número conforme uma tolerância e e um chute inicial a0; sua definição aplica within a repeat, e repeat a next.&lt;br /&gt;&lt;br /&gt;sqrt basicamente avalia within à lista gerada por repeat , e repeat gera a lista de resultados de next.&lt;br /&gt;&lt;br /&gt;Este programa, segundo a intuição de um programador acostumado a linguagens imperativas, nunca termina, porque repeat nunca termina de gerar a lista infinita.&lt;br /&gt;&lt;br /&gt;Porém, &lt;i&gt;lazy evaluation&lt;/i&gt; garante que esse programa termina -- garante que repeat será avaliado apenas o número de vezes necessária para que within se satisfaça. Eu entendo que o segredo disso está no momento em que o interpretador avalia o "desempacotamento" de uma lista, porque este é o momento em que o processamento exige a geração de mais um elemento.&lt;br /&gt;&lt;br /&gt;Isso é mesmo sensacional. Como seriam esses pequenos componentes em C++0x?&lt;br /&gt;&lt;br /&gt;Vamos começar brincando com uma versão muito eficiente de abs, o que não tem nada a ver com o problema em questão.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;template &lt;typename number=""&gt;&lt;/typename&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;auto abs (Number x) -&amp;gt; typename std::enable_if&amp;lt; std::is_signed&lt;number&gt;::value, Number&amp;gt;::type&lt;/number&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; return x &amp;lt; 0 ? -x : x ;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;template &lt;typename number=""&gt;&lt;/typename&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;auto abs (Number x) -&amp;gt; typename std::enable_if&amp;lt; ! std::is_signed&lt;number&gt;::value, Number&amp;gt;::type&lt;/number&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; return x;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A notação acima é a nova notação para funções em C++0x, onde a especificação do retorno fica depois da lista de argumentos.&lt;br /&gt;&lt;br /&gt;A definição de abs faz uso de SFINAE para sobrecarregar dois templates, de outro modo indistinguíveis, usando std::enable_if.&lt;br /&gt;&lt;br /&gt;Assim, abs pode se reduzir a nada quando nem mesmo faz sentido que o número possua um sinal.&lt;br /&gt;&lt;br /&gt;Em seguida, vamos chamar as listas de Range e declarar a forma geral de uma função unpack.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;template &lt;typename range="" typename="" value,=""&gt;&lt;/typename&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;auto unpack (Range&amp;amp; r) -&amp;gt; Value;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;template &lt;typename sequence=""&gt;&lt;/typename&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;auto unpack (Sequence&amp;amp; s) -&amp;gt; decltype(s.front())&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; typename Sequence::value_type v = s.front();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; s.pop_front();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; return v;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Definimos o significado de unpack providenciando uma sobrecarga, exclusiva para Containers da STL, que faz o que deve fazer. Em português, unpack resulta o elemento à esquerda e modifica a lista para conter o resto.&lt;br /&gt;&lt;br /&gt;Assim, definimos within:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;namespace detail&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;&amp;nbsp; template &lt;typename number,="" range="" typename=""&gt;&lt;br /&gt;&amp;nbsp; auto within (Number eps, Number a, Number b, Range rest) -&amp;gt; Number&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (abs(a - b) &amp;lt;= eps) return b;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else {&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; const Number c = unpack(rest);&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return within(eps, b, c, rest);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;template &lt;typename number,="" range="" typename=""&gt;&lt;br /&gt;// requires(ValueType(Range) == Number)&lt;br /&gt;auto within (Number eps, Range list) -&amp;gt; Number&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; const Number a = unpack(list);&lt;br /&gt;&amp;nbsp; const Number b = unpack(list);&lt;br /&gt;&amp;nbsp; return detail::within(eps, a, b, list);&lt;br /&gt;}&lt;/typename&gt;&lt;/typename&gt;&lt;/div&gt;&lt;br /&gt;within desempacota a e b e delega para uma subrotina; a subrotina faz o que se espera. Observe que a lista a processar é um desses tais Ranges.&lt;br /&gt;&lt;br /&gt;O componente equivalente a repeat deve gerar esse Range.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;namespace detail&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; template &lt;typename function,="" typename="" value=""&gt;&lt;/typename&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; struct repeat_range&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Function f;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value x;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; auto operator() () -&amp;gt; decltype(f(x))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return x = f(x);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; };&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; template &lt;typename t,="" typename="" u=""&gt;&lt;/typename&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; auto unpack (repeat_range&lt;t,u&gt;&amp;amp; r) -&amp;gt; decltype(r())&lt;/t,u&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return r();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;template &lt;typename function,="" typename="" value=""&gt;&lt;/typename&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;// requires(UnaryFunction(Function) &amp;amp;&amp;amp; Domain(Function) == Value)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;auto repeat (Function f, Value a) -&amp;gt; detail::repeat_range&lt;function, value=""&gt;&lt;/function,&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; return detail::repeat_range &lt;function, value=""&gt; { f, a };&lt;/function,&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Um Range é um objeto especial, que representa a lista; definimos um repeat_range que continuamente aplica uma função, e definimos unpack para este Range. (Observe como repeat_range usa o último valor gerado na geração do próximo.) &lt;br /&gt;A função repeat é utilitária e constrói o Range com os argumentos certos.&lt;br /&gt;&lt;br /&gt;A notação de construção usada na definição de repeat também é nova, e generaliza a inicialização entre structs C e objetos C++.&lt;br /&gt;&lt;br /&gt;Por último, implementamos a função importante para a aplicação, sqrt. Escolhi ocultar o equivalente a next porque a mim não interessa muito.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;namespace detail&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; template &lt;typename number=""&gt;&lt;/typename&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; auto sqrt (Number N, Number x) -&amp;gt; Number&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (x + (N / x)) / 2;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;template &lt;typename number=""&gt;&lt;/typename&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;auto sqrt (Number N, Number x, Number eps) -&amp;gt; Number&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; return&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; within(eps,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; repeat(&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [=] (Number x) { return detail::sqrt(N, x); },&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Agora, isso é &lt;i&gt;punk&lt;/i&gt;. A função no detail computa a próxima aproximação é trivial. O driver principal, por outro lado, é complexo.&lt;br /&gt;&lt;br /&gt;Em primeiro lugar, aquela notação esquisita ali é uma expressão lambda. Para todos os efeitos, a avaliação desta expressão produz uma função, que vira argumento para repeat.&lt;br /&gt;&lt;br /&gt;repeat, portanto, aplicará uma função lambda -- que por sua vez computa a próxima aproximação da raiz de N com chute x -- ao valor inicial x. O símbolo [=] significa que os nomes dentro do lambda se tornam cópias por valor dos objetos de mesmo nome no escopo maior.&lt;br /&gt;&lt;br /&gt;repeat, como vimos antes, produz um Range, sobre o qual within opera. E within procura um par de valores neste Range -- aplicando unpack quando necessário -- em busca de um par cuja diferença seja menor que eps.&lt;br /&gt;&lt;br /&gt;Assim, nesmo programa C++, simulamos com significativo esforço a &lt;i&gt;lazy evaluation&lt;/i&gt; funcional, para computar a raiz quadrada. Usando __attribute__((const)) esse programa deve otimizar até o Nirvana, mas eu não verifiquei.&lt;br /&gt;&lt;br /&gt;O programa esparramado no texto acima funciona de verdade com o GCC 4.5 e provavelmente funciona também com o ICC 11.1.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-7503640128285063032?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/7503640128285063032/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=7503640128285063032' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7503640128285063032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7503640128285063032'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2010/03/o-estilo-funcional-em-c.html' title='O estilo funcional em C++'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-251435543626130236</id><published>2010-03-18T21:08:00.001-03:00</published><updated>2010-04-24T20:29:36.845-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Interface Programador-Máquina</title><content type='html'>Ouvi algo interessante em uma aula do curso 6.00 do MIT, vendo o vídeo no celular, sobre a sobrecarga de operadores; o professor argumentava que essa era uma carecterística boa da linguagem de programação porque permitia uma interface consistente de programação.&lt;br /&gt;&lt;br /&gt;Esse é um uso interessante das palavras; em geral, dizemos &lt;i&gt;interface&lt;/i&gt; para nos referir a um contrato de comunicação entre dois pedaços de código executável.&lt;br /&gt;&lt;br /&gt;Realmente, da mesma forma como essa representação é um contrato ou protocolo entre dois pedaços de código executável que se comunicam, também há contrato ou protocolo entre quaisquer duas coisas que se comunicam, como por exemplo o programador e a máquina.&lt;br /&gt;&lt;br /&gt;Isso nos leva a pensar na linguagem de programação, como regra de sintaxe e semântica, como uma interface; e em pensar na qualidade de uma linguagem de programação como a qualidade dessa interface.&lt;br /&gt;&lt;br /&gt;O meta-caso-de-uso que essa interface pretende realizar é "expressar o programa que eu tenho em mente"; o componente que implementa essa interface é o compilador. Realmente é o compilador, e não a máquina física; o compilador, sob essa ótica, é a máquina abstrata, que interpreta a expressão do programa e faz algo de útil. De fato, normas como C e C++ descrevem o efeito do programa sobre uma máquina abstrata.&lt;br /&gt;&lt;br /&gt;Então, o que há com &lt;i&gt;y + x&lt;/i&gt; ?&lt;br /&gt;&lt;br /&gt;Há interface de alta qualidade na medida em que + significa o que você aprendeu ao longo de uma década de ensino de aritmética. Este julgamento fundamenta ambos os lados da divergência sobre se este símbolo deve ou deve não ser sobrecarregado para significar "concatenar duas strings". O lado &lt;i&gt;deve&lt;/i&gt; entende que qualquer indivíduo compreende + como "juntar", "unir", "somar". O lado &lt;i&gt;deve não&lt;/i&gt; entende que concatenar é "pôr um na frente do outro", que não possui a propriedade de associatividade.&lt;br /&gt;&lt;br /&gt;O tema da aula no vídeo que eu estava assistindo era classes em Python e uma introdução aos &lt;i&gt;abstract data types&lt;/i&gt;. Acho essa discussão pertinente porque ADTs são um conceito de meta-linguagem, e um ADT existe apenas na mente do programador. Faço essa distinção como a distinção entre o conjunto dos inteiros de que trata a álgebra e o tipo int da linguagem de programação.&lt;br /&gt;&lt;br /&gt;Quando o programador representa um ADT na linguagem de programação como uma classe, ele por sua vez oferece a outro programador uma interface de programação. O usuário do ADT, por assim dizer, escreverá programas que dissertam sobre esse ou aquele valor. Assim, eu concordo com o professor: se eu estou descrevendo um ADT numérico, é muito conveniente poder sobrecarregar o símbolo + e permitir aos meus usuários falar sobre coisas na forma de &lt;i&gt;y + x&lt;/i&gt; .&lt;br /&gt;&lt;br /&gt;Agora, há algo de estético nessa história toda. Suponha que por qualquer motivo você não pode usar o símbolo + . Que nome você escolheria, &lt;i&gt;add&lt;/i&gt; ou &lt;i&gt;sum&lt;/i&gt;? Ou &lt;i&gt;plus&lt;/i&gt;? &lt;i&gt;add&lt;/i&gt; tem algo de imperativo, enquanto &lt;i&gt;sum&lt;/i&gt; é um substantivo; ambos sugerem uma leitura diferente da expressão; e &lt;i&gt;plus&lt;/i&gt; é apenas o nome de um símbolo!&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &lt;i&gt;add(y, x)&lt;/i&gt; // add y to x&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&amp;nbsp; sum(y, x)&lt;/i&gt; // the sum of y and x&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&amp;nbsp; plus(y, x)&lt;/i&gt; // y plus x&lt;br /&gt;&lt;br /&gt;O &lt;i&gt;Elements of Programming&lt;/i&gt; argumenta que o projetista de um ADT deve se esforçar para determinar uma "base computacional" para o ADT, um conjunto mínimo de operações básicas e eficientes que permitem ao programador expressar todos os programas úteis possíveis que discursam sobre seus valores.&lt;br /&gt;&lt;br /&gt;Este é o aspecto aritmético de uma interface programador-máquina, por assim dizer; uma boa escolha de nomes é seu aspecto estético, talvez. Parte do processo de decifragem ou aprendizagem de um sistema -- rotina de um arqueólogo de sistemas legados -- é justamente aprender os símbolos na caótica cultura desse sistema, que podem ou não fazer sentido como se espera de um sistema "fresquinho".&lt;br /&gt;&lt;br /&gt;Parte do esforço hercúleo em se convencer de um teorema de matemática avançada é justamente ler a notação simbólica usada -- que, sendo altamente abstrata, é frequentemente irreprodutível em linguagem natural. (E às vezes a diferença entre um signo e outro é meia dúzia de três ou quatro &lt;i&gt;pixel&lt;/i&gt;.)&lt;br /&gt;&lt;br /&gt;Produzir uma interface programador-máquina eficiente é sempre bom, mas programadores em execesso usam a eficiência como desculpa para produzir interfaces incompreensíveis. E no fim das contas todos nós sabemos que o custo de um projeto de sistema convencional é dominado por seu custo de manutenção.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-251435543626130236?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/251435543626130236/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=251435543626130236' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/251435543626130236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/251435543626130236'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2010/03/interface-programador-maquina.html' title='Interface Programador-Máquina'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-8017344001175039152</id><published>2010-03-09T00:02:00.000-03:00</published><updated>2010-04-24T20:29:36.846-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Problema os ícones especiais do Nautilus</title><content type='html'>Não sei por que cargas d'água o ícone especial da pasta "Vídeos" na minha pasta de usuário no Nautilus perdeu a graça.&lt;br /&gt;&lt;br /&gt;O Nautilus, para pastas especiais como "Imagens", "Música" etc. usa ícones especiais com umas figuras bem legais, como um trecho de rolo de filme pro "Vídeos".&lt;br /&gt;&lt;br /&gt;Depois de muito procurar, percebi que o responsável pelo tema dos ícones usava alguma fonte de informação pra decidir quais pastas são especiais e aplicar ícones especiais -- ou não aplicar, de acordo com o tema.&lt;br /&gt;&lt;br /&gt;Depois de procurar ainda mais, descobri esta fonte de informação no Fedora 12:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$HOME/.config/user-dirs.dirs&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Realmente a linha de configuração para a pasta de vídeos estava com o nome errado.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-8017344001175039152?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/8017344001175039152/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=8017344001175039152' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8017344001175039152'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8017344001175039152'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2010/03/problema-os-icones-especiais-do.html' title='Problema os ícones especiais do Nautilus'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-3924940320046791391</id><published>2010-02-25T23:22:00.000-03:00</published><updated>2010-04-24T20:30:39.813-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Instalando o J2EE da Sun no Fedora 11</title><content type='html'>Dois pequenos probleminhas.&lt;br /&gt;&lt;br /&gt;Em primeiro lugar, o instalador reclama dizendo "Expression NOME_DO_PRODUTO is undefined on line 86, column 289 in /templates/components.ftl."&lt;br /&gt;&lt;br /&gt;O problema é o código de localização; execute o instalador com LANG=C e pronto.&lt;br /&gt;&lt;br /&gt;Em segundo lugar, eu uso um hostname personalizado meus sistemas -- este aqui se chama elisa. Nunca me dei ao trabalho de colocar o nome no /etc/hosts porque o mDNS funciona muito bem sem isso.&lt;br /&gt;&lt;br /&gt;O instalador não gosta dessa situação e reclama em uma caixa de diálogo sobre "host name invalid".&lt;br /&gt;&lt;br /&gt;Já estou usando esse esquema em outro lugar -- GlassFish J2EE 6 com Eclipse Galileo no Fedora 11 -- e funciona muito bem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-3924940320046791391?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/3924940320046791391/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=3924940320046791391' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/3924940320046791391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/3924940320046791391'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2010/02/instalando-o-j2ee-da-sun-no-fedora-11.html' title='Instalando o J2EE da Sun no Fedora 11'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-2335876123911953979</id><published>2010-01-26T14:14:00.000-02:00</published><updated>2010-04-24T20:29:36.847-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Funções/Objetos</title><content type='html'>Hoje vi em uma base de código-fonte uma função cujo nome é "signalCatcher" -- um substantivo. A regra geral de estilo é: dados são chamados por substantivos, funções por verbos no infinitivo.&lt;br /&gt;&lt;br /&gt;Mas faz sentido que "signalCatcher" seja o nome daquilo que você vai entregar ao mecanismo de sinais para tratar os sinais da aplicação, certo?&lt;br /&gt;&lt;br /&gt;Eu acredito que a linguagem de programação do futuro não deve fazer distinção entre objetos-dados e objetos-função, mesmo sintaticamente; ambos ocupam espaço na memória e portanto exigem alocação, e são mencionados através de referências.&lt;br /&gt;&lt;br /&gt;Em C, todas as funções são efetivamente objetos imutáveis, mas houve o tempo em que funções não eram imutáveis; esse tempo poderia voltar. E apesar de a maioria dos objetos ser mutável, alguns objetos são propositalmente imutáveis, e seus projetistas procuram maneiras de armazená-los em ROM.&lt;br /&gt;&lt;br /&gt;Uma função deve ser um objeto cujo tipo é &lt;b&gt;função&lt;/b&gt;, um tipo genérico variando na &lt;b&gt;lista de parâmetros&lt;/b&gt; e na &lt;b&gt;lista de resultados&lt;/b&gt;. O valor de um objeto do tipo função deve ser interpretado como uma sequência de instruções para o processador alvo, organizada de acordo com uma convenção de chamada apropriada. Esta convenção apóia a operação fundamental que o programa realiza sobre o objeto, &lt;b&gt;chamar&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;É claro que, ainda assim, uma função é um objeto bem especial. Em particular porque não é um objeto cujo tamanho é regular -- não se pode saber qual é o tamanho de um objeto função apenas conhecendo seu tipo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-2335876123911953979?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/2335876123911953979/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=2335876123911953979' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/2335876123911953979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/2335876123911953979'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2010/01/funcoesobjetos.html' title='Funções/Objetos'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-6399571980090391732</id><published>2010-01-13T14:17:00.000-02:00</published><updated>2010-04-24T20:29:36.848-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Programação e Semiótica 7</title><content type='html'>Um novo exemplo para diminuir o tédio dos leitores e usar esses conceitos para entender o processamento de texto nos computadores.&lt;br /&gt;&lt;br /&gt;Falemos sobre um programa que, por sua vez, deseja falar sobre textos em linguagem natural. Este programa fará referência a objetos cujo interpretante é "texto em linguagem de gente".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;O que é texto em linguagem de gente? É uma sequência de símbolos que os seres humanos são capazes de entender como &lt;b&gt;caracteres&lt;/b&gt; do seu idioma, que por sua vez se agrupam para formar palavras, frases etc. Nos idiomas latinos dizemos que as letras se agrupam para formar palavras; em idiomas como o japonês muitas vezes apenas um caracteres já é uma palavra inteira.&lt;br /&gt;&lt;br /&gt;Mas o computador não sabe nada sobre caracteres, apenas sobre números. Com certeza o computador é capaz de representar na memória números uns na frente dos outros.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A intuição fundamental é a possibilidade de estabelecer um &lt;b&gt;mapa de caracteres&lt;/b&gt; onde cada caractere está mapeado para um número e vice-versa. Formalmente, o mapa é uma função bijetora entre os conjuntos "números inteiros" e "caracteres".&lt;br /&gt;&lt;br /&gt;Assim, um programa processador de texto faz referência a objetos cujo primeiro tipo é "número inteiro" e cujo segundo tipo é "caractere do mapa tal".&lt;br /&gt;&lt;br /&gt;Suponha o seguinte mapa: a = 1, b = 2, c = 3 etc. O texto "abc" seria um objeto composto por três objetos numéricos contíguos 123.&lt;br /&gt;&lt;br /&gt;Como poderia um programa colocar palavras em ordem alfabética? Toma dois objetos "palavra" e compara os dois caracteres iniciais como números; se forem diferentes, a ordem é numérica; se forem iguais fazemos a mesma coisa com o segundo caractere e assim por diante. Essa é a &lt;b&gt;ordenação lexicográfica&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Esse esquema é interessante quando podemos usar um objeto de tamanho fixo e tipo "número" para todos os caracteres desejados. Mas com o advento da Internet e a interligação entre sistemas de todo o mundo se tornou inviável usar mapas de caracteres pequenos.&lt;br /&gt;&lt;br /&gt;O que acontece quando um sistema do Japão envia 123 para um sistema do Brasil? Que mapa de caracteres o sistema do Brasil deve tomar como interpretante desses números? Essa dificuldade é a causa de muitos fenômenos bizarros na Internet, onde páginas mostram um monte de lixo onde deveriam estar caracteres latinos acentuados ou coisa parecida.&lt;br /&gt;&lt;br /&gt;A primeira lição da interligação de sistemas processadores de texto é que não existe objeto "texto" compreensível sem um interpretante "mapa de caracteres" associado. Essa associação é um problema que sempre deve ser resolvido, mesmo que a solução seja um contrato entre todas as partes definindo um e apenas um mapa válido. Esse tipo de contrato não se mostrou viável a longo prazo.&lt;br /&gt;&lt;br /&gt;Alguns sistemas de programação experimentaram construir tipos mais complexos para objetos; não apenas "texto" mas "texto ASCII" ou "texto ISO-8859-1" -- embutindo no tipo do objeto também o tipo do mapa de caracteres. Isso é interessante para apoiar contratos como o anterior, mas um pouco estranho quando o sistema deve aceitar diversos tipos de texto de diversas partes do mundo.&lt;br /&gt;&lt;br /&gt;Estas parecem as coisas básicas que sempre queremos fazer com texto: contar o número de caracteres, decidir se dois textos são iguais, decidir qual de dois textos deve aparecer antes na ordem do dicionário, e inspecionar o texto letra por letra (para imprimir na tela, por exemplo). Com os mapas numéricos simples, podemos fazer todas essas coisas simplesmente trabalhando com pares de números: os primeiros de cada texto, depois os segundos de cada texto, etc.&lt;br /&gt;&lt;br /&gt;Nesses mapas, existe uma referência sensata que atravessa a representação dos objetos da mais pura -- os números -- para a mais abstrata -- o caractere do texto.&lt;br /&gt;&lt;br /&gt;Essa facilidade eventualmente terminou, o que ainda parece muito traumático para programadores acostumados com essa situação tão segura.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Eventualmente a comunidade internacional decidiu dar um basta na multiplicidade dos mapas e resolveu produzir o super-mapa Unicode. Este mapa é um catálogo de praticamente todos os caracteres usados na galáxia, associados cada um deles a um número inteiro positivo. Infelizmente, são muitos caracteres, que não podem ser representados com números pequenos.&lt;br /&gt;&lt;br /&gt;A princípio, os indivíduos decidiram usar números grandes e manter o esquema de mapa com objetos de tamanho fixo. Assim, o processamento par-a-par continuaria possível. Mas os objetos texto explodiram de tamanho e essa esquema se mostrou inviável.&lt;br /&gt;&lt;br /&gt;Então um compromisso foi firmado: um novo mapa foi produzido para o Unicode onde quase 90% dos textos continuaria com o mesmo tamanho, e apenas 10% seria maior. Este mapa às vezes usa um número por caracteres, às vezes dois, às vezes três e às vezes quatro. Este simples fato é o pesadelo dos programadores novatos de processamento de texto.&lt;br /&gt;&lt;br /&gt;Por que este mapa &lt;b&gt;UTF-8&lt;/b&gt; possui uma representação tão estranha com objetos caractere de tamanho variável, deixou de ser sensata a referência direta número-a-caractere. Um sistema que recebe 1234 3456 5678 e deve interpretar esses números como texto deve não mais assumir que o primeiro número é um caractere, e o segundo um caractere etc. É possível que na realidade os dois primeros números sejam um caractere juntos.&lt;br /&gt;&lt;br /&gt;Uma sequência de números que deve ser interpretada como UTF-8 não pode mais ser percorrida ingenuamente número a número, e os algoritmos de processamento baseados em comparações par-a-par estão quebrados. Isso, novamente, se deve ao fato de que UTF-8 viola propositalmente premissas simples de significação dos números que compõe um texto.&lt;br /&gt;&lt;br /&gt;Isso foi um problema grave porque programas antigos despreocupadamente tratavam seu texto de forma crua, diretamente com os números, confortados pelas premissas do processamento de texto -- ao invés de fazer isso com funções especiais em módulos de processamento de texto.&lt;br /&gt;&lt;br /&gt;Quando o significado dos números foi alterado nos processos de substituição de mapa por mapa, consertar esses programas foi tarefa infernal. Os programas com funções especiais de tratamento de texto modificaram apenas estas funções e foram livrados deste mal.&lt;br /&gt;&lt;br /&gt;Esta vitória do encapsulamento pode ser compreendida pelo encapsulamento de uma função sígnica -- a compreensão dos signos-número como signos-letra encapsulada em certos entes responsáveis, e uma transformação cultural pôde ser efetivada apenas instruindo estes entes responsáveis, e não todos os entes.&lt;br /&gt;&lt;br /&gt;No final das contas o problema se tornou tão bem resolvido que surgiu um componente tão reusável que surge por toda parte, a &lt;a href="http://www.gnu.org/software/libiconv/"&gt;libiconv&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-6399571980090391732?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/6399571980090391732/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=6399571980090391732' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/6399571980090391732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/6399571980090391732'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2010/01/programacao-e-semiotica-7.html' title='Programação e Semiótica 7'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-1364536187229267009</id><published>2010-01-12T13:37:00.000-02:00</published><updated>2010-04-24T20:29:36.849-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Programação e Semiótica 6</title><content type='html'>Entender o texto de um programa sob a ótica da semiótica é um pouco mais fácil do que entender outros tipos de texto porque o limiar de realidade do programa está bem delineado e bem próximo: a máquina.&lt;br /&gt;&lt;br /&gt;Por essa razão, não é preciso uma poderosa metafísica para entender o que é um &lt;b&gt;objeto&lt;/b&gt;, mesmo que este esteja, para o programa escrito, totalmente oculto.&lt;br /&gt;&lt;br /&gt;Bolei o seguinte diagrama para descrever as três propriedades fundamentais de um objeto segundo as regras da máquina.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_O7vJ6agDv_c/S0x6XkjobsI/AAAAAAAAAGM/SrzqX-nZOWI/s1600-h/object_01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_O7vJ6agDv_c/S0x6XkjobsI/AAAAAAAAAGM/SrzqX-nZOWI/s320/object_01.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Estas três propriedades são a "base" de um objeto e o determinam completamente; seu estado ou padrão de bits, seu local ou endereço, seu tamanho ou comprimento em bytes.&lt;br /&gt;&lt;br /&gt;Local e tamanho são propriedades espaciais, sendo a memória um universo unidimensional. Falamos sobre onde um objeto está, e ao longo de que comprimento. Estado é uma propriedade temporal, e (potencialmente) muda a cada instante.&amp;nbsp; Falamos sobre qual é o estado de um objeto (agora).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Mas eu venho insistindo que o programa escrito em linguagem de alto nível nada sabe sobre objetos, exceto aquilo que pode falar sobre eles através de referências, e tentando aplicar a nomenclatura da semiótica para dizer isso.&lt;br /&gt;&lt;br /&gt;Bolei o seguinte diagrama para relacionar os três conceitos que eu estou tentando usar, que envolvem toda expressão no programa escrito sobre objetos.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_O7vJ6agDv_c/S0x7fwGAAaI/AAAAAAAAAGU/A0GPUN3wC6s/s1600-h/object_02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_O7vJ6agDv_c/S0x7fwGAAaI/AAAAAAAAAGU/A0GPUN3wC6s/s320/object_02.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Uma expressão em um programa escrito como "y = x + x" possui, além dos elementos sintáticos &lt;i&gt;=&lt;/i&gt; e &lt;i&gt;+&lt;/i&gt; os nomes &lt;i&gt;y&lt;/i&gt; e &lt;i&gt;x&lt;/i&gt;; estes nomes são tradicionalmente chamados &lt;b&gt;variáveis&lt;/b&gt; e eu os estou chamando aqui de &lt;b&gt;referências&lt;/b&gt;. Esses nomes significam objetos por intermédio de um &lt;b&gt;tipo&lt;/b&gt; (que eu acredito ser equivalente ao &lt;b&gt;interpretante&lt;/b&gt;.)&lt;br /&gt;&lt;br /&gt;Linguagens como C++ prendem referência e tipo através da sintaxe; a ferramenta que interpreta o programa sempre sabe qual é o tipo associado a um nome como &lt;i&gt;x&lt;/i&gt;. Linguagens como Javascript não prendem referência e tipo dessa forma, de modo que a ferramenta deve sempre considerar o contexto de uma expressão para inferir um tipo para &lt;i&gt;x&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;A vantagem do C++ (e similares) é a possibilidade de se apoiar em uma ferramenta para evitar que uma referência absurda seja formada e usada; linguagens como essa permitem a dedução da validade semântica a partir da validade sintática. Este é o sonho da &lt;b&gt;análise estática&lt;/b&gt; de programas: descobrir erros no significado a partir do (uso da) sintaxe.&lt;br /&gt;&lt;br /&gt;No seguinte exemplo em C++:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;complex c1 = { 1.0, 1.0 };&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;c1&lt;/i&gt; é uma referência cujo interpretante estático é "número complexo". Conhecendo os segredos deste interpretante, poderíamos compreender o resto do texto, o próprio objeto, como o número complexo 1 + i.&lt;br /&gt;&lt;br /&gt;A vantagem do Javascript (e similares) é a possibilidade de se expressar&lt;br /&gt;sobre objetos através de múltiplos tipos viáveis de acordo com a conveniência; linguagens como essa simplificam a validade sintática para aumentar as opções de validade semântica.&lt;br /&gt;&lt;br /&gt;No seguinte exemplo em Javascript:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;nome = "Pedro Lamarão";&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;nome&lt;/i&gt; é uma referência sem interpretante estático. Conhecendo os segredos da sintaxe da linguagem, saberíamos que aspas duplas implicam o interpretante "texto", e portanto nome significa o meu nome.&lt;br /&gt;&lt;br /&gt;Independentemente de onde o leitor obtém um tipo-interpretante para uma variável-referência, é através deste que o objeto-estado possuirá uma conotação -- um significado imediato. Os três tipos fundamentais em máquinas contemporâneas são o inteiro-sem-sinal, o inteiro-com-sinal e o ponto-flutuante.&lt;br /&gt;&lt;br /&gt;Programas do mundo real, porém, estão muito interessados em coisas como letras, textos, nomes de pessoas e lugares, valores em moeda local, fotos etc. Diversos programas precisam impor significados adicionais a objetos fundamentalmente aritméticos para serem úteis.&lt;br /&gt;&lt;br /&gt;Essa necessidade nos leva naturalmente a pensar em &lt;b&gt;objetos compostos&lt;/b&gt; por &lt;b&gt;objetos simples&lt;/b&gt; e sobre a diferença conceitual entre um objeto na máquina concreta e um &lt;b&gt;valor&lt;/b&gt; em um &lt;b&gt;conjunto abstrato&lt;/b&gt;. Certos programas dirão que um certo objeto possui o valor "Pedro Lamarão" -- mesmo sabendo que a máquina fundamentalmente só compreende números.&lt;br /&gt;&lt;br /&gt;O relacionamento entre as idéias objeto e valor, e a idéia de composição de objetos, torna o processo semiótico de um programa muito mais rico, interessante e passível de absurdos -- onde nem sempre se consegue responder com facilidade a perguntas simples como "&lt;i&gt;x&lt;/i&gt; é igual a &lt;i&gt;y&lt;/i&gt;?"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-1364536187229267009?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/1364536187229267009/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=1364536187229267009' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/1364536187229267009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/1364536187229267009'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2010/01/programacao-e-semiotica-6.html' title='Programação e Semiótica 6'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_O7vJ6agDv_c/S0x6XkjobsI/AAAAAAAAAGM/SrzqX-nZOWI/s72-c/object_01.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-7131115908644246508</id><published>2010-01-07T10:51:00.002-02:00</published><updated>2010-04-24T20:29:36.850-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Semiótica e Programação 5</title><content type='html'>Agora, para um pensamento menos entediante.&lt;br /&gt;&lt;br /&gt;Considere que autenticação é o processo pelo qual um sujeito se convence que um certo signo de fato significa um certo objeto -- uma certa credencial de fato significa um certo indivíduo, por exemplo.&lt;br /&gt;&lt;br /&gt;Quando você ouve a campainha e alguém dizer "Olá" e pensa "Deve ser fulano" você autentica o signo vocal para se convencer ainda mais usando o olho mágico.&lt;br /&gt;&lt;br /&gt;O método de autenticação em sistemas de informação com a interação mais simples é a checagem de um segredo compartilhado. O sistema conhece um segredo para um username e assume que se alguém apresentar o username e o segredo, então deve ser o significado daquele username.&lt;br /&gt;&lt;br /&gt;O programa em execução, após executar essa interação com sucesso, construirá um objeto na memória, e manterá uma referência para ele cujo significado ulterior é username-do-usuário. Já que a autenticação foi bem sucedida, o programa confiará até terminar que esta referência é adequada, e poderá usá-la para julgar se deve ou deve não permitir o usuário a abrir certos arquivos etc.&lt;br /&gt;&lt;br /&gt;Esta confiança no significado daquela referência é perfeitamente adequada para programas convencionais: a memória de um programa convencional em um sistema convencional é exclusiva, de modo que ele pode facilmente se convencer de que o objeto referenciado é íntegro.&lt;br /&gt;&lt;br /&gt;Às vezes programadores movem para sistemas diferentes onde as regras são diferentes, e esse tipo de expectativa implícita é violada com consequências drásticas.&lt;br /&gt;&lt;br /&gt;O jovem programador que move sua atividade para a web pode escrever um site em script que autentica o usuário e guarda o username em um objeto da sessão. O programa subjacente então continuamente fará certa referência a este objeto para tomar decisões de segurança, afinal, esta referência está para o objeto certo, não é?&lt;br /&gt;&lt;br /&gt;Porém, neste ambiente, o programador não pode assumir a integridade do objeto -- não ingenuamente, como eu assumi acima. Como a web é um sistema bem distribuído e como o browser acessa o site um arquivo por vez, sem qualquer continuidade, este objeto ao qual o script faz referência não está sob seu controle. Ele existe em uma memória distante, fora do seu controle.&lt;br /&gt;&lt;br /&gt;Fora do seu controle significa sob controle de um outro agente: o cliente. Suponha então que eu faça um acesso a uma página restrita e posicione arbitrariamente um objeto com o &lt;i&gt;username&lt;/i&gt; de outra pessoa justamente no local onde a referência do programa assume que ele esteja. Assim, eu posso &lt;b&gt;mentir&lt;/b&gt; ao programa sobre quem eu sou, me valendo de uma ingenuidade no significado do programa.&lt;br /&gt;&lt;br /&gt;Perceber esse furo de segurança no site pode ser difícil porque o texto do programa do site pode adequadamente obter o &lt;i&gt;username&lt;/i&gt; e compará-lo com regras de autorização em todos os lugares. O problema aqui é semanticamente anterior a esta comparação: o problema está na premissa de que uma certa referência está de fato para um objeto com o significado esperado.&lt;br /&gt;&lt;br /&gt;Assim, os defeitos nos processos de autenticação em sistemas de informação são compreensíveis sob a ótica de uma função sígnica com "defeito" -- uma oportunidade através da qual o par em uma conversação tem condições de mentir. Concretamente, esse defeito existe no programa na forma de uma confiança indevida sobre o objeto de uma referência.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-7131115908644246508?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/7131115908644246508/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=7131115908644246508' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7131115908644246508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7131115908644246508'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2010/01/semiotica-e-programacao-5.html' title='Semiótica e Programação 5'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-4611088759351494385</id><published>2010-01-06T11:29:00.000-02:00</published><updated>2010-04-24T20:29:36.851-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Semiótica e Programação 4</title><content type='html'>O padrão Proxy ocorre sempre que um objeto no sistema existe como substituto de outro objeto, por alguma razão. Em um sistema distribuído entre muitos computadores físicos, um objeto local pode ser substituto de um objeto que está em outro computador, ocultando o mecanismo de comunicação entre computadores.&lt;br /&gt;&lt;br /&gt;O objeto proxy, de um modo ou de outro, possuirá uma referência ao objeto proxied; e o programa que possui uma referência ao objeto proxy possuirá uma referência ao objeto proxied.&lt;br /&gt;&lt;br /&gt;Esses múltiplos níveis de indireção trazem problema para a expressão e compreensão do programa devido a frequente ausência de interpretantes para humanos -- também conhecidos como &lt;b&gt;documentação&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Considere um objeto whatever que é um proxy para um objeto em um computador central, e uma rotina com essa aparência:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; get_name (whatever) -&amp;gt; (s1)&lt;br /&gt;&amp;nbsp;&amp;nbsp; ; s1 is the name of whatever&lt;br /&gt;&lt;br /&gt;Um programa chama get_name e obtém uma referência ao objeto "nome" de um outro objeto qualquer.&lt;br /&gt;&lt;br /&gt;Agora, resta a pergunta: se o programa que eu estou rodando modificar o valor de s1, o que acontece com whatever? Se Fulana rodar o mesmo programa depois que eu, que valor de s1 ela vai obter? s1 é uma referência para uma cópia ou é uma referência para o original?&lt;br /&gt;&lt;br /&gt;Essa diferença é importante por razões que não apenas as consequências de modificar o objeto. A memória do computador é finita e portanto os programas devem cuidar de destruir os objetos que já acabaram de usar. Mas o que o programa que usa get_name deve fazer com o objeto referenciado por s1? Ele deve destruí-lo? Ele pode destruí-lo? Com certeza ele não pode destruir um objeto que está referenciado por diversos outros programas.&lt;br /&gt;&lt;br /&gt;Por que (alguns) programas devem cuidar da presença dos objetos na memória, e dar manutenção nessa memória, existe sempre o problema de dispor de espaço para objetos ocuparem e por quanto tempo. Quando um programa faz algo como:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; string s4 = "Marcelinho"&lt;br /&gt;&lt;br /&gt;a expressão de que "existe um s4 que é um texto" é interpretada implicitamente como "precisamos arranjar espaço para um texto pelo tempo necessário".&lt;br /&gt;&lt;br /&gt;Quando o programa lida com objetos que foram criados por ele mesmo e são locais, o uso do espaço e do tempo é óbvio porque explícito; referências a objetos ocultos demandam maiores explicações.&lt;br /&gt;&lt;br /&gt;As referências indiretas como os objetos proxies levam o problema além quando tornam possível que uma referência seja absurda -- uma referência a nenhum-objeto. Há programas onde faz sentido uma referência a nenhum-objeto e há programas onde isso não faz sentido. O programador deve deixar isso sempre claro sob pena de não ser compreendido.&lt;br /&gt;&lt;br /&gt;Documentação é a única solução geral na medida em que linguagens de programação em geral não oferecem mecanismos sintáticos para se especificar esses atributos de uma referência.&lt;br /&gt;&lt;br /&gt;Nem mesmo C++, que possui duas notações para referências com diversos graus de rigor sintático, consegue expressar tudo o que se deseja expressar, e a confusão sobre a especificação de "rvalue references" indica que ainda não está firmada a sintaxe do futuro.&lt;br /&gt;&lt;br /&gt;Linguagens como Java, onde a quase totalidade dos objetos são criados por um gestor central em memória desconhecida, permitem ao programa ignorar a manutenção da memória mas ainda sofrem do problema de compreensão das referências.&lt;br /&gt;&lt;br /&gt;Quando começamos a considerar as referências polimórficas a situação fica ainda mais punk.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-4611088759351494385?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/4611088759351494385/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=4611088759351494385' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4611088759351494385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4611088759351494385'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2010/01/semiotica-e-programacao-4.html' title='Semiótica e Programação 4'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-3516084182757798238</id><published>2010-01-04T17:15:00.000-02:00</published><updated>2010-04-24T20:29:36.851-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>URIs e a semiose da web</title><content type='html'>(TODO: Será que estou usando os termos certos? Suponho que "significante" seja o mesmo que "interpretante" mas a nomenclatura da Semiótica não está bem firme na minha memória.)&lt;br /&gt;&lt;br /&gt;Existe bastante semiose na comunicação entre programas de computador, mesmo que seja uma semiose extremamente simples, com um universo de possibilidades bastante limitado.&lt;br /&gt;&lt;br /&gt;O serumano ao acessar uma página na Web digita no browser: http://www.twitter.com/pedrolamarao -- uma URI.&lt;br /&gt;&lt;br /&gt;Existe algo de muito interessante acontecendo entre o serumano, o browser e um servidor perdido na rede; algo descrito em grande pompa teórica na especificação das URIs.&lt;br /&gt;&lt;br /&gt;Em primeiro lugar, esse texto é bastante opaco para a maioria das pessoas; muitas delas compreendem que "twitter" é o nome de um "site" e que estão querendo ver as paradas de "pedrolamarao".&lt;br /&gt;&lt;br /&gt;Alguns mais acostumados com a Web sabem que "http" é o nome das coisas que são da Web, e que existem outros nomes próprios de outros programas, como "ftp".&lt;br /&gt;&lt;br /&gt;Realmente esse texto, ou esse símbolo, se divide em duas partes, e deve ser interpretado em dois estágios, ou como composto de dois símbolos distintos.&lt;br /&gt;&lt;br /&gt;O primeiro símbolo é "http" que deve ser interpretado de acordo com um esquema bem simples -- a pura comparação textual. "http" vai para cá, "ftp" vai para lá e assim por diante. O nome desse símbolo é &lt;b&gt;schema&lt;/b&gt; e esse símbolo será o interpretante do símbolo seguinte: deve-se interpretar o resto do texto de acordo com este princípio do texto.&lt;br /&gt;&lt;br /&gt;Existe uma infinitude de possíveis schemas, já que um schema é apenas e tão somente um monte de letras em sequência. Além disso, o acordo entre todos nós sobre o que um schema significa pode ou pode não ser bem definido; é claro que a Internet inteira concorda sobre o que é "http", mas duvido que algum de vocês saiba como interpretar "astrotv" da mesma forma que eu.&lt;br /&gt;&lt;br /&gt;Quando o schema é "http" o sistema sabe que deve usar o browser Web. Ao menos, assim esperamos que seja, quando clicamos em "http://www.twitter.com/pedrolamarao" sublinhado em azul naquele email que recebemos. O browser Web, por sua vez, sabe que&amp;nbsp; o segundo símbolo -- "www.twitter.com/pedrolamarao" -- é composto também por diversos símbolos, quando a URI é "http".&lt;br /&gt;&lt;br /&gt;O primeiro deste último conjunto é chamado &lt;b&gt;authority&lt;/b&gt; e possui um entre poucos interpretantes aceitáveis. Neste caso, o&lt;b&gt; domain name system&lt;/b&gt; ou &lt;b&gt;DNS&lt;/b&gt; é o nome do sistema responsável. Este sistema dirá ao browser Web onde está o servidor responsável. Mais detalhes são irrelevantes. Restam poucos outros interpretantes aceitáveis, e seus sistemas são cheios de números.&lt;br /&gt;&lt;br /&gt;O segundo deste último conjunto é chamado &lt;b&gt;path&lt;/b&gt;. Este path possui um interpretante básico: o sistema de arquivos do servidor significado pelo authority. É o mesmo que os arquivos na máquina de qualquer pessoa. É claro que, como é da natureza do mundo, existem diversos outros interpretantes possíveis, como por exemplo algum outro programa dentro do servidor Web que mapeia "pedrolamarao" para um negócio em um banco de dados.&lt;br /&gt;&lt;br /&gt;Porém, tudo o que o browser Web precisa saber, parte do seu acordo com o servidor Web, é que para qualquer path o servidor Web enviará uma porção de dados. Na maioria das vezes, esses dados estão de acordo com a norma&amp;nbsp; HTML ou CSS e devem ser interpretados através destas -- seus interpretantes. É claro que nem sempre é assim, já que vêm também scripts Javascript, fotos JPEG, música MP3 etc. etc.&lt;br /&gt;&lt;br /&gt;Como o browser sabe qual será o interpretante mais adequado para cada um desses símbolos bizarros de 0s e 1s que vêm pela rede? A semiose durante um simples abrir de página é complexa e cheia de elementos, e será finita apenas até o ponto em que o engenheiro perder o interesse nos detalhes do sistema.&lt;br /&gt;&lt;br /&gt;A cada passagem de símbolo a símbolo por um interpretante escolhido por qualquer agente nessa confusão toda há chance para algum problema. Administradores de servidor Web vivem às voltas com "página não encontrada" e arrancam os cabelos para entender porque um determinado path não foi encontrado. Volta e meia um browser Web resolve imprimir um monte de lixo na tela quando o usuário tem certeza que está baixando um filme. Às vezes um sujeito digita o nome de um site e o browser Web diz "nome não encontrado". O que acontece quando a configuração do DNS está com defeito!? E alguns infelizes usam sistemas que não tem muita certeza sobre o que fazer com nomes começando com "http".&lt;br /&gt;&lt;br /&gt;Toda vez que surge um novo sistema de componentes na indústria há bravatas sobre o desenvolvimento de um novo tipo de "nome globalmente único". É o grande sonho da humanidade, ser capaz de nomear os entes sem ambiguidade. Todo um conjunto de sociedades esotéricas existe em desespero para aprender o Idioma de Adão, que soube nomear todas as coisas sem hesitação. Os humanos com senso prático compreendem que nomes são acordos entre as partes e estabelecem tais acordos entre si. O schema "http" por exemplo possui um significado em acordo estabelecido sob a autoridade do &lt;b&gt;IANA&lt;/b&gt;. Mas você sabe o que IANA significa?..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-3516084182757798238?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/3516084182757798238/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=3516084182757798238' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/3516084182757798238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/3516084182757798238'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2010/01/uris-e-semiose-da-web.html' title='URIs e a semiose da web'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-8799538485271959819</id><published>2009-12-30T15:50:00.000-02:00</published><updated>2010-04-24T20:29:36.852-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Semiótica e Programação 3</title><content type='html'>Do ponto de vista do Java e do C#, C++ é uma linguagem fracamente tipada. Apesar de dizer isso abusar dos termos, existe um fundo de verdade ali.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;C++, ao contrário de Java e C#, permite a formação de referências arbitrárias a qualquer objeto -- mesmo objetos hipotéticos.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Programas como este são aceitáveis, para o compilador:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;list&amp;lt;string&amp;gt;* l = (list&amp;lt;string&amp;gt;*)0x12345;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;l-&amp;gt;sort();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Esta propriedade é inútil para a maioria dos programas, o que torna C++ excessivamente complicada aos olhos da maioria dos programadores. Se o programa está dizendo que naquele lugar ocorre um &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;list&amp;lt;string&amp;gt;&lt;/span&gt; então isso deve ser verdade, certo? Boa sorte!&lt;br /&gt;&lt;br /&gt;Existem programas que fazem uso dessa possibilidade, como programas para máquinas onde certos endereços são especiais e têm significado pré-definido.&lt;br /&gt;&lt;br /&gt;Programas como este também são aceitáveis:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;dog* marley = new dog();&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;spaceship* one = (spaceship*)marley;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;one-&amp;gt;launch();&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Essa possibilidade é inerente à máquina, na medida em que o significante de uma referência existe apenas no mundo do discurso; a máquina conhece apenas bits. A reinterpretação de um padrão de bits é uma operação de pura semiótica: não é necessário computar nada, apenas compreender os bits de uma forma diferente. Assim sendo, C++ se limita a dizer que não fará esforço para garantir que esse programa faz sentido -- o problema é todo seu.&lt;br /&gt;&lt;br /&gt;A estrutura que o tipo de uma referência impõe ao programa pode ser tal que nem todos os padrões de bits possíveis para aquele segmento de memória tenham um significado. Assim, apesar de o programa afirmar que ali está um objeto &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;spaceship&lt;/span&gt;, o padrão de bits que ocorre ali pode não representar um objeto &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;spaceship&lt;/span&gt; -- e o programa é literalmente um absurdo.&lt;br /&gt;&lt;br /&gt;Em outras palavras, esse programa potencialmente viola invariantes do tipo &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;spaceship&lt;/span&gt;, que são pré-condições automáticas para a chamada da função &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;launch&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;A reinterpretação irrestrita de objetos é uma das características mais estranhas dessa linguagem, e mais difícil de pôr em prática de forma útil.&lt;br /&gt;&lt;br /&gt;Um desses usos é a transferência de objetos entre programas através de um dispositivo, técnica em que o programa receptor obtém uma pura sequência de bytes e assume que ali está o objeto transferido. Isso é chamado &lt;b&gt;serialização&lt;/b&gt; porque torna o objeto, que possui significado e estrutura, em um série de bits.&lt;br /&gt;&lt;br /&gt;Outro desses usos é a técnica de &lt;i&gt;&lt;b&gt;move construction&lt;/b&gt;&lt;/i&gt; do Elements of Programming, onde o objeto é reinterpretado de acordo com sua &lt;i&gt;&lt;b&gt;underlying class&lt;/b&gt;&lt;/i&gt; e copiado como tal -- e esta cópia é justamente a movimentação desejada.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-8799538485271959819?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/8799538485271959819/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=8799538485271959819' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8799538485271959819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8799538485271959819'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/12/semiotica-e-programacao-3.html' title='Semiótica e Programação 3'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-4823731260482466946</id><published>2009-12-29T16:48:00.001-02:00</published><updated>2010-04-24T20:29:36.853-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Semiótica e Programação 2</title><content type='html'>Linguagens cuja proposta é &lt;b&gt;tipagem forte&lt;/b&gt; permitem através de sua sintaxe a expressão de constrições sobre a manipulação do estado de um objeto denotado por uma referência. Linguagens cuja proposta é &lt;b&gt;tipagem fraca&lt;/b&gt; permitem manipulações de objetos com pouca constrição.&lt;br /&gt;&lt;br /&gt;Entendendo uma referência nesse contexto como o mesmo que um &lt;b&gt;signo&lt;/b&gt;, o &lt;b&gt;tipo&lt;/b&gt; é o &lt;b&gt;significante&lt;/b&gt; de uma referência, impondo significado ao objeto denotado.&lt;br /&gt;&lt;br /&gt;Para o programa, o tipo impõe constrições sobre as manipulações possíveis ou válidas desse objeto. Em linguagens como C++, a diferenciação dos tipos permite a seleção de uma entre diversas operações possíveis de modo particularmente significativo para o objeto referenciado.&lt;br /&gt;&lt;br /&gt;Naturalmente, programas podem formar diversas referências ao mesmo objeto, o que causa diversas dificuldades à especificação do significado de um programa como um todo e atrapalha ferramentas de transformação de código -- o "problema de &lt;i&gt;&lt;b&gt;aliasing&lt;/b&gt;&lt;/i&gt;".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A especificação da máquina abstrata que determina o significado de um programa deve responder de algum modo a questão: suponha uma referência &lt;i&gt;a&lt;/i&gt; cujo tipo é &lt;i&gt;A&lt;/i&gt; e uma referência&lt;i&gt; b&lt;/i&gt; cujo tipo é &lt;i&gt;B&lt;/i&gt; onde ambas denotam o mesmo objeto; suponha que um programa escreva um valor válido através de &lt;i&gt;a&lt;/i&gt; e então leia um valor através de &lt;i&gt;b&lt;/i&gt;; qual é o significado desse programa para &lt;i&gt;A&lt;/i&gt; e &lt;i&gt;B&lt;/i&gt; arbitrários?&lt;br /&gt;&lt;br /&gt;Linguagens de tipagem fraca frequentemente realizam conversões auto-mágicas internamente de modo que o programa acima sempre possui um significado compreensível. C++ dirá que o programa acima possui em geral um significado &lt;b&gt;indefinido&lt;/b&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-4823731260482466946?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/4823731260482466946/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=4823731260482466946' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4823731260482466946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4823731260482466946'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/12/semiotia-e-programacao-2.html' title='Semiótica e Programação 2'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-7784965457060396589</id><published>2009-12-28T11:11:00.000-02:00</published><updated>2010-04-24T20:29:36.854-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Semiótica e Programação</title><content type='html'>É interessante observar que podemos sem erro considerar todo nome de variável e função em um programa C++ como uma &lt;b&gt;referência&lt;/b&gt;. Esta referência, assim como possivelmente muitas outras, &lt;b&gt;denotam&lt;/b&gt; um certo objeto que, em si, não passa de uma combinação de três informações: um local, uma quantidade de armazenagem, e um estado atual. Referências cujo tipo é ponteiro-para-Foo &lt;b&gt;conotam&lt;/b&gt; um objeto do tipo Foo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-7784965457060396589?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/7784965457060396589/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=7784965457060396589' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7784965457060396589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7784965457060396589'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/12/semiotica-e-programacao.html' title='Semiótica e Programação'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-8180731313504964483</id><published>2009-12-01T21:29:00.001-02:00</published><updated>2010-04-24T20:29:36.855-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>bytes e suas interpretações</title><content type='html'>Houve época em que, ao programar C#, sempre me irritava ver a notação byte -- me parecia estúpido ter um tipo na linguagem de programação chamado byte.&lt;br /&gt;&lt;br /&gt;Li hoje em um manual da Intel:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;"Although bytes, words, and doublewords are fundamental data types, some instructions support additional interpretations of these data types to allow operations to beperformed on numeric data types (signed and unsigned integers, and floating-point numbers)."&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Hoje, programando em C++, me irrita que não exista uma distinção entre char-que-é-sequência-opaca-de-bits, char-que-é-número-inteiro e char-que-é-elemento-alfabético.&lt;br /&gt;&lt;br /&gt;O texto do manual é interessante; para a máquina, realmente existe apenas o byte e suas variantes como padrões de bits; o que quer que você faça de interessante com esse byte implica uma interpretação desse byte.&lt;br /&gt;&lt;br /&gt;A máquina é &lt;i&gt;untyped&lt;/i&gt;; não existe mecanismo formal pelo qual se possa deduzir que uma interpretação para este byte é correta ou incorreta. Dependendo de quem você é, isso pode parecer ótimo ou absurdo.&lt;br /&gt;&lt;br /&gt;As razões porque isso é ótimo são boas, mas diminuiriam muito com algumas poucas extensões do C++. Programadores de aritmética com poucos recursos computacionais aprendem rapidamente, por exemplo, que a máquina pode computar muito rapidamente produto e divisão por 2 sem usar as instruções de produto e divisão de inteiros -- usando as instruções de shift de sequências de bytes. Esses programadores podem argumentar que essa é a vantagem da programação &lt;i&gt;untyped&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Felizmente, podemos pensar de trás pra frente; aceitando como axioma que a memória representa sempre &lt;i&gt;bits&lt;/i&gt;, então devem haver implementações ótimas para produto_por_2 e quociente_por_2 -- assim como é_par e é_negativo. Isso sugere que uma linguagem de programação com esses operadores nativos para números inteiros satisfaz as necessidades do programador acima -- diminuindo drasticamente a necessidade de permitir &lt;i&gt;shifts&lt;/i&gt; em objetos do tipo inteiro.&lt;br /&gt;&lt;br /&gt;Essa idéia me vem do "Elements of Programming", de Stepanov e McJones; no livro eles discutem a idéia de "base computacional" de uma estrutura de dados. Quando aritmética inteira é implementada em uma máquina binária, produto_por_2, quociente_por_2, é_par e é_negativo devem fazer parte da base computacional dos tipos inteiros -- simplesmente por serem especialmente rápidas.&lt;br /&gt;&lt;br /&gt;(No livro, eles não estudam representações de números reais; alguém se habilita a compor uma base computacional para números reais representados como em IEEE 754?)&lt;br /&gt;&lt;br /&gt;[Editado!] &lt;br /&gt;&lt;br /&gt;Acho, além disso, interessante a definição de certos tipos de dados inúteis no manual da Intel, como &lt;i&gt;bit field&lt;/i&gt; e &lt;i&gt;string&lt;/i&gt;. Essas definições parecem mais sugestões de uso que definições, já que nem um &lt;i&gt;bit field&lt;/i&gt; nem um &lt;i&gt;string&lt;/i&gt; é mais que um ou mais bytes contíguos.&lt;br /&gt;&lt;br /&gt;Me parece que essas definições apóiam a definição posterior de operações extendidas ou especializadas sobre bytes, como referências a bits individuais ou cópia otimizada de bytes contíguos. É claro que essas são, ainda, operações simples sobre sequências de bits, e não demandam interpretação especial.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-8180731313504964483?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/8180731313504964483/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=8180731313504964483' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8180731313504964483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8180731313504964483'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/12/bytes-e-suas-interpretacoes.html' title='bytes e suas interpretações'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-6746931133681239097</id><published>2009-11-29T12:12:00.000-02:00</published><updated>2010-04-24T20:29:36.856-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>C++ em múltiplas configurações</title><content type='html'>Parte dos meus esforços em entender o ambiente de programação C++ é buscar os padrões de uso do pré-processador, algo que eu nunca encontrei catalogado sistematicamente.&lt;br /&gt;&lt;br /&gt;Ao meu ver, existem dois grandes grupos de usuários do pré-processador: programadores que usam macros como formas de reusar código totalmente &lt;i&gt;inline&lt;/i&gt;, e programadores que usam macros para variar a definição de um programa C++ de acordo com variáveis de configuração.&lt;br /&gt;&lt;br /&gt;A comunidade do C++ acredita que a necessidade de usar macros hoje praticamente não existe; essas pessoas deveriam ser mais específicas e dizer que a necessidade de usar macros para reusar código totalmente &lt;i&gt;inline&lt;/i&gt; já não existe, porque compiladores otimizadores e templates de função são capazes de fazer isso.&lt;br /&gt;&lt;br /&gt;(Eu chamo reusar código totalmente &lt;i&gt;inline&lt;/i&gt; a uma forma de reuso que insere código diretamente no chamador, sem utilizar o mecanismo de chamada de subrotina, que envolve empilhamento, desempilhamento e saltos.)&lt;br /&gt;&lt;br /&gt;Porém, não há solução sintática para o problema das configurações -- ao menos, não há solução bem conhecida. É interessante ler sobre &lt;a href="http://www.gnu.org/software/autoconf/manual/html_node/Genesis.html"&gt;a história do autoconf&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-6746931133681239097?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/6746931133681239097/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=6746931133681239097' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/6746931133681239097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/6746931133681239097'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/11/c-em-multiplas-configuracoes.html' title='C++ em múltiplas configurações'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-8762140873733601876</id><published>2009-11-26T15:25:00.001-02:00</published><updated>2010-04-24T20:29:36.858-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Otimização nas Sombras do C++</title><content type='html'>Eu não encontro pessoalmente esse tipo de coisa com muita frequência atualmente, mas foi tempo em que volta e meia me aparecia código-fonte muito esperto, ou críticas muito espertas sobre o meu código-fonte, com relação a quão "ótimo" ele é.&lt;br /&gt;&lt;br /&gt;Em C, essas espertezas eram invariavelmente transformações de uma notação legível e imediatamente representativa do algoritmo lógico por uma notação ilegível, equivalente mas que executava mais rápido.&lt;br /&gt;&lt;br /&gt;Truques de aritmética de ponteiros para escrever mais rápido na memória, truques horrendos com while e switch sem break pra desenrolar loops -- vários truques cujo objetivo é escrever o mesmo código gerando um programa melhor.&lt;br /&gt;&lt;br /&gt;De certa forma, os truques dessa época eram motivados pelos compiladores dessa época, máquinas de transformação burra de C para assembler. Com o objetivo de gerar o melhor assembler, programadores produziam pior C -- mais rápido, sim, mas menos legível e de mais difícil manutenção.&lt;br /&gt;&lt;br /&gt;Com o passar do tempo, os compiladores se tornaram otimizadores, capazes de &lt;i&gt;inlining&lt;/i&gt;, remoção de código morto, desenrolamento de &lt;i&gt;loops&lt;/i&gt;, progragação de valores constantes etc.&lt;br /&gt;&lt;br /&gt;As máquinas, por sua vez, introduziram &lt;i&gt;pipelines&lt;/i&gt; para otimizar o trabalho de processador mais e mais rápido que a memória, capazes de execução computações intermediárias simultaneamente a recuperação de dados da memória, especulação sobre valores futuros para adiantar computações etc.&lt;br /&gt;&lt;br /&gt;Compiladores cientes do &lt;i&gt;pipeline&lt;/i&gt; passaram a otimizar ainda mais, ordenando e reordenando instruções de modo a obter o melhor desempenho do otimizador alvo.&lt;br /&gt;&lt;br /&gt;Quem tem à mão um excelente compilador otimizador não precisa mais se preocupar em produzir código esperto. O compilador quase invariavelmente é melhor do que o programador humano. Ele também é a ferramenta adequada para a esperteza -- porque projetos críticos frequentemente transformam um código-fonte em programas para diversas máquinas, onde as peculiaridades variam muito.&lt;br /&gt;&lt;br /&gt;Mas então, um dia, surgiram as máquinas multi-processadas. A seguinte &lt;a href="http://ridiculousfish.com/blog/archives/2007/02/17/barrier/"&gt;citação&lt;/a&gt; resume a tragédia da programação para tais máquinas:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Yeah, I know. "Multithreading is hard" is a cliché, and it bugs me, because it is not some truism describing a fundamental property of nature, but it’s something &lt;/i&gt;&lt;i&gt;we did.  We made multithreading hard because we optimized so heavily for the single threaded case.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;O problema fundamental de um programa &lt;i&gt;multithreaded&lt;/i&gt; em uma máquina onde os processadores compartilham a memória é o de garantir que um certo objeto lógico -- uma sequência de bytes na memória -- não será escrito e lido de forma incosistente por múltiplos processadores -- porque um está escrevendo pela metade quando outro está lendo, etc.&lt;br /&gt;&lt;br /&gt;Por mais que um programador faça esforço para ordenar adequadamente as instruções em um programa -- de modo que qualquer ordem de leitura possível faça algum sentido -- o fato é que o otimizador do compilador, e o otimizador do &lt;i&gt;pipeline&lt;/i&gt;, fará mágicas com a presença e a ordem das instruções, violando a expectativa do programador.&lt;br /&gt;&lt;br /&gt;Desse modo, os truques espertos da atualidade não são truques para otimizar o &lt;i&gt;assembler&lt;/i&gt; e sim truques para evitar inconsistência no acesso concorrente à memória.&lt;br /&gt;&lt;br /&gt;As pessoas legais agora falam sobre &lt;i&gt;atomics&lt;/i&gt; e &lt;i&gt;memory barriers&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;O que há de curioso aqui é que esse problema espirra em certas direções mesmo onde não há múltiplos &lt;i&gt;threads&lt;/i&gt;. Ao programar uma máquina com suporte a &lt;i&gt;memory mapped I/O&lt;/i&gt; o mesmo problema de consistência ocorre sobre um endereço &lt;i&gt;memory mapped&lt;/i&gt; -- reordenar leituras e escritas ali resulta no caos.&lt;br /&gt;&lt;br /&gt;Tendo chegado até aqui, releia seu livro favorito sobre C++ sobre o significado da palavra-chave &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;volatile&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-8762140873733601876?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/8762140873733601876/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=8762140873733601876' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8762140873733601876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8762140873733601876'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/11/otimizacao-nas-sombras-do-c.html' title='Otimização nas Sombras do C++'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-2614224564250838221</id><published>2009-11-23T17:55:00.000-02:00</published><updated>2010-04-24T20:29:36.860-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Mais sombras no Ambiente de Programação C++</title><content type='html'>Estou lendo a ementa do curso de pós-graduação em Análise e Projeto de Sistemas da PUC-Rio, onde ocorre o seguinte:&lt;br /&gt;&lt;br /&gt;"Laboratório de Linguagens de Programação&lt;br /&gt;&lt;br /&gt;Objetivo – Capacitar o aluno a distinguir os principais componentes de linguagens de programação não convencionais tais como: programação orientada a objetos, programação orientada a eventos e programação para Internet/intranet."&lt;br /&gt;&lt;br /&gt;A presença de "programação orientada a eventos" ali é interessante; a ementa prossegue em explicar que neste módulo o aluno aprenderá a programar Applets Java, que são orientados a eventos.&lt;br /&gt;&lt;br /&gt;O que se chama "orientação a eventos" ali é uma técnica de projeto de aplicativos úteis plugados em algum tipo de &lt;i&gt;framework&lt;/i&gt; de apoio, que cuida de enviar os tais eventos para o aplicativo.&lt;br /&gt;&lt;br /&gt;Há um sub-grupo dos programadores de C++ que dirá a você que "não programa interfaces de usuário". Essa é uma afirmação interessante porque, compreendido com rigor máximo, significa que os programas produzidos por essa pessoa produzem resultados totalmente invisíveis.&lt;br /&gt;&lt;br /&gt;Todo programa de computador possui uma interface de usuário -- senão, o usuário nunca veria seu resultado. Programadores C++ são criados desde o berço para produzir programas cuja interface com o usuário é o terminal -- um dispositivo capaz de apresentar um mapa de 80x24 caracteres.&lt;br /&gt;&lt;br /&gt;O que há de interessante nisso é que existe um mecanismo subjacente a esse terminal que suporta a parafernália usada para pôr ali os tais caracteres -- std::cout, printf etc. Esse mecanismo é inicializado, mantido e finalizado pela implementação do C++ de forma oculta ao usuário.&lt;br /&gt;&lt;br /&gt;Existem ambientes peculiares onde o C++ não inicializa nada disso -- ou inicializa essas coisas de forma inesperada. Os compiladores da Microsoft oferecem um parâmetro de chamada ao compilador para selecionar o "subsistema" -- CONSOLE ou WINDOWS. Aplicativos compilados para o subsistema WINDOWS não fazem coisas úteis quando o programa chama printf.&lt;br /&gt;&lt;br /&gt;No projeto onde estou alocado agora, o sistema implantado no dispositivo-alvo é altamente customizado, e a biblioteca padrão C++ apresenta esquisitices parecidas. Não existe um "terminal" e chamar printf às vezes não faz nada, às vezes bloquea o sistema eternamente em um signal handler.&lt;br /&gt;&lt;br /&gt;Bibliotecas como a Qt e a Glib oferecem uma terceira via, que talvez pudesse ser compreendida como um terceiro subsistema, o EVENT_LOOP. Esse subsistema possui sua própria API e faz tudo pela aplicação, que apenas inicia operações no sistema e senta esperando por notificações sobre o resultado. Assim são os Applets Java.&lt;br /&gt;&lt;br /&gt;Tudo isso sugere que o ambiente de execução do C++ executa mais que apenas o código da aplicação, e de fato existem atividades que ocorrem antes de &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;main&lt;/span&gt; iniciar e depois de &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;main&lt;/span&gt; finalizar. O programador atento procurará pelo código-fonte ou executável do CRT no seu sistema -- o C Run-Time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-2614224564250838221?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/2614224564250838221/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=2614224564250838221' title='7 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/2614224564250838221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/2614224564250838221'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/11/mais-sombras-no-ambiente-de-programacao.html' title='Mais sombras no Ambiente de Programação C++'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-5162515058807634604</id><published>2009-11-13T11:55:00.001-02:00</published><updated>2010-04-24T20:29:36.861-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>As sombras do Ambiente de Programação C++</title><content type='html'>Estou realmente escrevendo sobre este assunto! É claro que, até reunir material suficiente para um livro maneiro, vai demorar muito tempo. Até lá espero encontrar alguma publicação legal que aceite artigos.&lt;br /&gt;&lt;br /&gt;Minha motivação inicial para entender os mistérios do ambiente de programação C++ foi estudar a ABI do C++, que seria necessário implementar no sistema operacional C++.&lt;br /&gt;&lt;br /&gt;Existem outros aspectos interessantes desse ambiente, porém, que são pouco focalizados pelas obras educativas sobre a linguagem.&lt;br /&gt;&lt;br /&gt;Um deles é o relacionamento entre o mundo restrito da norma ISO C e o mundo maior do sistema. C fala a você sobre unidades de tradução e estabelece regras mínimas sobre como múltiplas unidades de tradução podem compor um programa válido. Ao redor da linguagem, porém, existe o problema de processar cada uma dessas unidades e produzir de fato um negócio único equivalente a este programa. Existirão então diversos blocos intermediários, os "objetos compilados", e existirá um componente ligador. A norma C não descreve este ligador, apenas impõe seus requisitos.&lt;br /&gt;&lt;br /&gt;Outro é o modo como os mecanismo de linguagem e do sistema são usados na prática como mecanismos de abstração, e como os projetos de engenharia fazem uso desses mecanismos para lidar com problemas reais de configuração. O ambiente como um todo provê diversas maneiras de abstrair certos trechos de código; desde a seleção de arquivos a compilar, onde um arquivo pode conter a listagem para o sistema A enquanto outro contém a listagem para o sistema B; até a composição de bibliotecas dinâmicas no momento da carga na memória, onde o programa usa a versão A da biblioteca no sistema A, e a versão B da biblioteca no sistema B.&lt;br /&gt;&lt;br /&gt;Para lidar com toda essa parafernália sistêmica ao redor do C são imprescindíveis ferramentas que operam fora da linguagem, dirigindo todas as ferramentas de forma conveniente. O projeto de middleware de televisão digital da TQTVD tem, por exemplo, aproximadamente mil unidades de tradução individuais a processar. Certamente o programador não deve chamar as ferramentas uma vez para cada um desses arquivos, sob pena de tornar o dia de trabalho um desperdício de horas absurdo. Existem portanto ferramentas para apoiar essa tarefa que, apesar de não fazer parte da definição da linguagem ou do compilador, são absolutamente imprescindíveis para se trabalhar com ela.&lt;br /&gt;&lt;br /&gt;Tudo isso implica que a expertise no desenvolvimento de sistemas em C++ envolve diversas outras habilidades e técnicas individuais, fora aquelas envolvendo a expressão de programas em C++. Essas outras habilidades e técnicas se tornam tão mais importantes quanto o projeto pressione o programador para fora da abstração de um sistema para o mundo concreto das diversas máquinas.&lt;br /&gt;&lt;br /&gt;Sob outro ângulo, posso comparar as listas de componentes teórica e prática que compõe o pipeline de transformação de código-fonte. Teoricamente, o pipeline C é: pré-processador, compilador, ligador ou arquivador. Na prática do projeto onde estou envolvido é: configurador de build, ferramenta de build, compilador.&lt;br /&gt;&lt;br /&gt;Uma lição que estou tirando de tudo isso é que os melhores pensamentos sobre a linguagem de programação ideal nunca resultariam em um excelente sistema construído se essa linguagem não for implementada em ferramentas adequadas, que suportem um ciclo de desenvolvimento extremamente conveniente. O esquema de compilação separada do C oferece bons mecanismos de abstração, sem dúvida, mas torna o tempo de compilação uma infinitude de "começa e termina" processos.&lt;br /&gt;&lt;br /&gt;Em contra-partida, opiniões sobre características de linguagem de programação do tipo "viagem na maionese" ou "impossível" parecem refletir o fato de que, até então, ninguém soube produzir uma ferramenta que a implementasse. O mecanismo de "export" do C++ por exemplo foi considerado um fracasso; agora que as técnicas de LTO e serialização de ASTs de programas estão se tornando mais difundidas, talvez com mais cinco ou dez anos "export" seja trivial.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-5162515058807634604?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/5162515058807634604/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=5162515058807634604' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/5162515058807634604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/5162515058807634604'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/11/as-sombras-do-ambiente-de-programacao-c.html' title='As sombras do Ambiente de Programação C++'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-8150608308716521903</id><published>2009-11-03T19:55:00.002-02:00</published><updated>2010-04-24T20:29:36.862-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Java vs. C#, uma perspectiva estranha</title><content type='html'>Você pode achar o que quiser na disputa entre Java e C#, mas onde na documentação da Microsoft você vai encontrar uma afirmação tão direta, sincera e esclarecedora?&lt;br /&gt;&lt;br /&gt;"Prior to Java 2 Standard Edition, JDK 1.4, the AWT focus subsystem was inadequate."&lt;br /&gt;&lt;br /&gt;http://java.sun.com/javase/6/docs/api/java/awt/doc-files/FocusSpec.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-8150608308716521903?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/8150608308716521903/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=8150608308716521903' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8150608308716521903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/8150608308716521903'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/11/java-vs-c-uma-perspectiva-estranha.html' title='Java vs. C#, uma perspectiva estranha'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-4943739368251659661</id><published>2009-10-29T15:13:00.002-02:00</published><updated>2010-04-24T20:29:36.864-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>bug bizarro no RVCT 2.2</title><content type='html'>Descobrimos um bug bizarro no RVCT 2.2 onde a compilação de uma chamada a um operador de conversão do std::auto_ptr gera as seguintes instruções:&lt;br /&gt;&lt;br /&gt;1. push into stack from register&lt;br /&gt;2. unconditionally jump to (1)&lt;br /&gt;&lt;br /&gt;Alguém já viu isso?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-4943739368251659661?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/4943739368251659661/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=4943739368251659661' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4943739368251659661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4943739368251659661'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/10/bug-bizarro-no-rvct-22.html' title='bug bizarro no RVCT 2.2'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-7120115301703993572</id><published>2009-09-18T17:27:00.002-03:00</published><updated>2010-04-24T20:29:36.864-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>C++ e puramente funcional</title><content type='html'>Usando GCC 4.5, Dehydra e um script maroto, seria possível implementar uma verificação estática de que uma função é puramente funcional?&lt;br /&gt;&lt;br /&gt;__attribute__((user("functionally_pure")) int foo_free_of_side_effects (int x, int y);&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-7120115301703993572?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/7120115301703993572/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=7120115301703993572' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7120115301703993572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7120115301703993572'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/09/c-e-puramente-funcional.html' title='C++ e puramente funcional'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-991456882861235300</id><published>2009-09-02T22:44:00.004-03:00</published><updated>2010-04-24T20:29:36.865-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cxx'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>byte, address e dispositivos</title><content type='html'>Suponha que você tem uma variante de C++0x onde existem apenas os tipos: byte, address e size. byte é uma sequência de oito bits, address é uma posição na memória e size é a distância entre duas posições na memória.&lt;br /&gt;&lt;br /&gt;Com bytes você pode fazer bit shifting e outras operações próprias de sequências de bits; com address você pode navegar pela memória, obtendo sucessores e predecessores; com size você pode navegar pela memória a passos largos.&lt;br /&gt;&lt;br /&gt;Suponha, além disso, que o programa tem à disposição um allocator que obtém pedaços de memória com tamanho fixo, e acesso a dispositivos por uma API razoável.&lt;br /&gt;&lt;br /&gt;Que tipos de programa você poderia escrever?&lt;br /&gt;&lt;br /&gt;Você poderia copiar dados de um dispositivo para outro:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void copy (device&amp; in, device&amp; out)&lt;br /&gt;{&lt;br /&gt;  const size length = allocator.page_size();&lt;br /&gt;  address buffer = allocator.allocate_page();&lt;br /&gt;&lt;br /&gt;  size n;&lt;br /&gt;  while ((n = in.read(buffer, length)) &gt; 0) out.write(buffer, n);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Você poderia copiar dados, criptografando com XOR:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void copy_and_encrypt (device&amp; in, device&amp; out, byte key)&lt;br /&gt;{&lt;br /&gt;  const size length = allocator.page_size();&lt;br /&gt;  address buffer = allocator.allocate_page();&lt;br /&gt;&lt;br /&gt;  size n;&lt;br /&gt;  while ((n = in.read(buffer, length)) &gt; 0)&lt;br /&gt;  {&lt;br /&gt;    for (address i = buffer; i != buffer + length; ++i) *i ^= key;&lt;br /&gt;    out.write(buffer, n);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Acredito que você poderia realizar praticamente todo tipo de criptografia apenas com operações binárias.&lt;br /&gt;&lt;br /&gt;De onde um programa obteria a chave? De outro dispositivo de entrada, talvez.&lt;br /&gt;&lt;br /&gt;Meu ponto é que nada disso está relacionado com aritmética em domínios numéricos; mesmo com a existência de size no programa, que é claramente uma "quantidade". Ainda é possível escrever programas interessantes mesmo sem a possibilidade de realizar aritmética com valores do tipo size.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-991456882861235300?l=blog.pedro.lamarao.nom.br' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.pedro.lamarao.nom.br/feeds/991456882861235300/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=991456882861235300' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/991456882861235300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/991456882861235300'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/09/byte-address-e-dispositivos.html' title='byte, address e dispositivos'/><author><name>Pedro Lamarão</name><uri>https://profiles.google.com/117815968071916408257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-SqyK9g6gq3U/AAAAAAAAAAI/AAAAAAAAAAA/cDD7qL_kWlI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry></feed>
