<?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'><id>tag:blogger.com,1999:blog-3006142001944566780</id><updated>2010-03-16T20:55:44.432-03:00</updated><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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>41</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-8017344001175039152</id><published>2010-03-09T00:02:00.000-03:00</published><updated>2010-03-09T00:02:06.268-03:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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-02-25T23:22:46.701-03:00</updated><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='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=3924940320046791391' title='3 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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</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-01-26T14:14:25.458-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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-01-13T14:17:07.458-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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-01-12T13:37:30.058-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></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 xmlns:thr='http://purl.org/syndication/thread/1.0'>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-01-07T10:57:46.040-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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-01-06T11:29:04.683-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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-01-04T17:15:58.954-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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>2009-12-30T15:50:06.292-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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>2009-12-30T12:55:38.262-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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>2009-12-28T11:11:47.138-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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>2009-12-01T21:36:54.368-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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>2009-11-29T12:12:39.110-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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>2009-11-26T15:50:09.629-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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>2009-11-23T17:55:04.509-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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>2009-11-16T22:17:32.951-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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>2009-11-03T19:55:44.016-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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>2009-10-29T15:13:27.544-02:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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>2009-09-18T17:29:56.489-03:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>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>2009-09-02T23:35:57.211-03:00</updated><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='https://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>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-7279776522065663243</id><published>2009-08-31T21:21:00.004-03:00</published><updated>2009-08-31T21:44:25.763-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Dualidade memória/dispositivo</title><content type='html'>Ainda pensando sobre linguagem de programação e sistema, e na possibilidade de se projetar uma API de dispositivos apenas com &lt;span style="font-family:courier new;"&gt;byte&lt;/span&gt; e &lt;span style="font-family:courier new;"&gt;address&lt;&gt;&lt;/span&gt;, me ocorreram os seguintes pensamentos sobre a relação entre os dispositivos e a memória.&lt;br /&gt;&lt;br /&gt;A memória é uma sequência onde ocorrem símbolos, na máquina binária contemporânea esses símbolos são bits e a unidade de armazenagem prática aos programas é o &lt;span style="font-family:courier new;"&gt;byte&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Além disso, na máquina de von Neumann, toda a operação do programa ocorre sobre a memória, inclusive operação sobre dispositivos, que ocorrem ao programa na forma de intervalos especialmente posicionados na memória.&lt;br /&gt;&lt;br /&gt;Programas no sistema Unix, por outro lado, vêem dispositivos na forma de arquivos, com o qual trocam dados; o dispositivo é uma origem de dados e um destino de dados. A API fundamental de dispositivos é &lt;span style="font-family:courier new;"&gt;read&lt;/span&gt; e &lt;span style="font-family:courier new;"&gt;write&lt;/span&gt;. A realização básica de um arquivo é o próprio arquivo de dados, ocorrendo em um sistema de arquivamento.&lt;br /&gt;&lt;br /&gt;É claro que o Unix, aplicando sua filosofia de simplicidade, exibe tudo como arquivo, inclusive todos os dispositivos; programas podem trocar dados com qualquer dispositivo representável em &lt;span style="font-family:courier new;"&gt;/dev&lt;/span&gt;. De fato, existe &lt;span style="font-family:courier new;"&gt;/dev/mem&lt;/span&gt; que reflete como um dispositivo a própria memória.&lt;br /&gt;&lt;br /&gt;Por fim, borrando a distinção entre o que o processo de usuário vê e o que o sistema vê, existem os mecanismo de mapeamento em memória, que representam dispositivos (entre outras coisas) como intervalos de memória ao processo.&lt;br /&gt;&lt;br /&gt;É fácil observar que a memória, fisicamente, e o dispositivo, abstratamente, são elementos e conceitos que se substituem e se sobrepõe. A noção de &lt;span style="font-style: italic;"&gt;character device&lt;/span&gt; no Unix parece nascer exatamente daqueles dispositivos cuja natureza é a de um intervalo de átomos, um conceito cuja necessidade surge após a decisão de representar tudo como arquivos.&lt;br /&gt;&lt;br /&gt;A união de memória virtual e o aspecto memória de um dispositivo ocorre no mecanismo de mapeamento em memória; no projeto de uma API de I/O assíncrono, a necessidade de expor páginas da memória de um processo ao &lt;span style="font-style: italic;"&gt;driver&lt;/span&gt; do dispositivo para DMA também ocorre.&lt;br /&gt;&lt;br /&gt;Programas sintonizados à API de arquivos frequentemente desejam comunicar a subprogramas dados em memória, e então a necessidade de um pseudo-dispositivo cuja representação é memória surge.&lt;br /&gt;&lt;br /&gt;Tudo isso implica que o projeto de uma API de dispositivos é o projeto de uma API de memória, e todo projeto de um &lt;span style="font-style: italic;"&gt;abstract data type&lt;/span&gt; dispositivo implica o projeto de um &lt;span style="font-style: italic;"&gt;abstract data type&lt;/span&gt; intervalo-de-memória.&lt;br /&gt;&lt;br /&gt;Que um aspecto ofereça melhor desempenho a um programa é função das necessidades desse programa. Programas que lêem arquivos frequentemente mapeiam este arquivo na memória e o lêem como um intervalo de memória. Programas que computam na memória o &lt;span style="font-style: italic;"&gt;digest&lt;/span&gt; SHA-1 de uma informação frequentemente operam um pseudo-dispositivo onde escrevem blocos fixos de dados iterativamente.&lt;br /&gt;&lt;br /&gt;Fundamentalmente, eis a questão: um dispositivo deve ser convertível para um intervalo-de-memória e vice-versa. O desafio é projetar tal API segundo todos os critérios de boas práticas realisticamente em um sistema.&lt;br /&gt;&lt;br /&gt;Mudando de assunto, eis o projeto 9.1 do &lt;span style="font-style: italic;"&gt;Elements of Programming&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;"Modern computing systems include highly optimized library procedures for copying memory; for example, memmove and memcpy, which use optimization techniques not discussed in this book. Study the procedures provided on your platform, determine the techniques they use (for example, loop unrolling and software pipelining), and design abstract procedures expressing as many of these techniques as possible. What type requirements and preconditions are necessary for each technique? What language extensions would allow a compiler full flexibility to carry out these optimizations?"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-7279776522065663243?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/7279776522065663243/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=7279776522065663243' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7279776522065663243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/7279776522065663243'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/08/dualidade-memoriadispositivo.html' title='Dualidade memória/dispositivo'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-4788212197291742917</id><published>2009-08-25T21:30:00.002-03:00</published><updated>2009-08-25T23:00:31.916-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Máquina de Turing</title><content type='html'>Acho que atingi uma compreensão de como uma máquina de computação contemporânea cumpre os requisitos restritos da máquina universal de computação.&lt;br /&gt;&lt;br /&gt;A máquina universal de computação é uma máquina que opera sobre símbolos ocorrendo um espaço unidimensional infinito. A máquina transforma seu estado de acordo com o símbolo atual; ela pode, por exemplo, avançar ou retroceder no espaço de símbolos, reescrever o símbolo em uma determinada posição, ou qualquer outra coisa.&lt;br /&gt;&lt;br /&gt;A máquina se torna útil com a especificação do conjunto de símbolos representáveis e do significado de todos esses símbolos. Assim, um símbolo pode significar "avance três posições" e outro símbolo pode significa "substitua o próximo símbolo com o símbolo seguinte a esse, e vice-versa.&lt;br /&gt;&lt;br /&gt;É claro que nenhuma máquina concreta terá acesso a um espaço infinito para símbolos; portanto, podemos falar sobre uma máquina universal restrita com espaço finito para símbolos.&lt;br /&gt;&lt;br /&gt;Uma máquina universal binária é uma máquina cujos símbolos são 0 e 1. Uma tal máquina não pode significar muita coisa com apenas um símbolo, mas nada impede que significados especiais sejam atribuídos a sequências específicas de símbolos.&lt;br /&gt;&lt;br /&gt;Assim, podemos falar sobre símbolos complexos, compostos por uma sequência de símbolos, que na máquina binária será uma sequência de 0s e 1s. A máquina binária possui portanto uma regra implícita: enquanto um símbolo complexo não for compreendido, ela avança para o próximo símbolo.&lt;br /&gt;&lt;br /&gt;Quando um símbolo completo é compreendido, a máquina realiza a transformação especificada para aquele símbolo complexo.&lt;br /&gt;&lt;br /&gt;É claro que, em uma máquina concreta, o número de símbolos complexos especificáveis é finito, já que os próprios símbolos complexos devem ser sequências finitas de símbolos fundamentais, e portanto existe uma combinação finita de tais símbolos complexos.&lt;br /&gt;&lt;br /&gt;Mas um conjunto suficientemente grande pode representar todas as operações possíveis sobre uma memória sequencial de símbolos fundamentais, como: se o valor lógico do próximo símbolo complexo for verdade avance para a posição determinada pelo símbolo complexo seguinte a este, senão pelo símbolo complexo duas posições depois.&lt;br /&gt;&lt;br /&gt;Isso é verdade porque, se podemos computar matemática fundamental, podemos computar qualquer coisa.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-4788212197291742917?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/4788212197291742917/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=4788212197291742917' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4788212197291742917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/4788212197291742917'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/08/maquina-de-turing.html' title='Máquina de Turing'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-9125880897422327369</id><published>2009-08-21T14:10:00.003-03:00</published><updated>2009-08-21T15:27:27.137-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Tipos de dados primitivos 2</title><content type='html'>Em C++, existe uma certa ambiguidade no significado dos tipos primitivos.&lt;br /&gt;&lt;br /&gt;Tome char, por exemplo. char pode ser apenas char, pode ser signed char ou pode ser unsigned char. Mas char deve ser caractere, certo? Qual é o significado de um caractere ser signed ou unsigned? Nenhuma.&lt;br /&gt;&lt;br /&gt;Existe, é claro, uma razão porque é possível especificar unsigned ou signed char; porque char é um valor inteiro de tamanho 1. De certa forma, char é o menor de todos os int, e foi projetado para ser usado como tal. Em uma máquina convencional, char é um inteiro de 8 bits. C99 na prática exige que char ocupe 8 bits.&lt;br /&gt;&lt;br /&gt;Em C original, o ponteiro para char possuía a propriedade adicional de representar qualquer endereço válido de memória. Portanto, uma função que lê dados de um dispositivo qualquer para a memória aceitaria um parâmetro do tipo ponteiro para char significando o endereço de memória de um buffer.&lt;br /&gt;&lt;br /&gt;É claro que isso provoca uma confusão com outro sigficado de ponteiro para char, a string de bytes terminada por NULL, ou NTBS. Por esse motivo, alguns programas e bibliotecas usam ponteiro para unsigned char para representar segmentos opacos de memória, como buffers de I/O.&lt;br /&gt;&lt;br /&gt;Em C99, qualquer ponteiro é conversível para um ponteiro para algum char. Em C++ isso não é permitido. Em ambas as linguagens, qualquer ponteiro é conversível para um ponteiro para void.&lt;br /&gt;&lt;br /&gt;Aritmética de ponteiro não é permitia para um ponteiro para void, infelizmente; programas que desejam atravessar a memória por qualquer razão devem usar ponteiros para char. Isso exige o uso de conversões por reinterpretação, como a notação de cast com parênteses, ou reinterpret_cast.&lt;br /&gt;&lt;br /&gt;Existem aqui diversas necessidades diferentes. Uma delas é endereçar memória opaca, sem interpretação, e endereçá-la completamente. Outra é representar o menor valor inteiro possível na plataforma. Outra é representar um caractere. Outra é representar um segmento de texto.&lt;br /&gt;&lt;br /&gt;Representar um caractere como o menor inteiro da plataforma é, hoje sabemos, uma ingenuidade, e existem diversas representações de caracteres que usam um número variado dessas unidades para caracteres, ou usam um número fixo de duas ou mais dessas unidades.&lt;br /&gt;&lt;br /&gt;Assim, quando ocorre em um programa um caractere literalmente, como &lt;span style="font-style: italic;"&gt;f&lt;/span&gt;, qual é a quantidade de armazenagem que o valor correspondente ocupa na memória? Depende da representação de caracteres usada no sistema alvo -- e naturalmente na unidade de memória da arquitetura alvo.&lt;br /&gt;&lt;br /&gt;Eu não gosto dessa notação de signed e unsigned. Parece ter havido um problema original em que os ints tiveram de ser subitamente diferenciados entre inteiros e inteiros positivos. Não entendo como isso pode ter sido súbito, mas ainda não conheço bem a história da computação para saber como eram as máquinas quando C foi projetada. Me parece apenas que é um sistema de tipos obsoleto. As máquinas conhecem os naturais, ou inteiros positivos, representados em base 2 e conhece os inteiros representados em base 2 com complemento de dois.&lt;br /&gt;&lt;br /&gt;Caracteres são um outro tipo de informação, distinto de números, apesar de logicamente relacionáveis -- a representação de um caractere é um índice em uma tabela.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-9125880897422327369?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/9125880897422327369/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=9125880897422327369' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/9125880897422327369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/9125880897422327369'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/08/tipos-de-dados-primitivos-2.html' title='Tipos de dados primitivos 2'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-1888911903431537837</id><published>2009-08-18T11:06:00.002-03:00</published><updated>2009-08-18T12:03:29.070-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Declarações, nomes e objetos</title><content type='html'>Uma linguagem como C++ é chamada declarativa porque o elemento central de sua sintaxe é a declaração.&lt;br /&gt;&lt;br /&gt;Uma declaração é uma construção sintática que associa um nome a um sujeito -- ou um identificador e um objeto. O caso simples é a declaração de uma variável.&lt;br /&gt;&lt;br /&gt;Creio que um objeto é um ente totalmente abstrato do discurso, ao contrário do que a literatura sugere. Certamente podemos falar sobre o objeto e descrever suas propriedades; mas na máquina concreta, o significado de um objeto transita entre seus três aspectos fundamentais: seu valor, sua armazenagem e sua localização.&lt;br /&gt;&lt;br /&gt;O tipo de um objeto, por princípio, corresponde ao domínio de seus valores. Assim, podemos considerar os dois tipos primitivos fundamentais que sugeri anteriormente, byte e address&lt;t&gt;. byte é um pseudo-tipo para "o que quer que seja, armazenável na memória". address&lt;t&gt; é o tipo do valor "localização na memória de um valor do tipo T". address&lt;byte&gt; é o tipo do valor "localização na memória do que quer que seja".&lt;br /&gt;&lt;br /&gt;Em C++, a função de "o que quer que seja" é cumprida por char; char é a unidade de memória na máquina abstrata C++. A função de "localização na memória do que quer que seja" é cumprida em parte por void*, para o qual podemos converter qualquer T*, e em parte por char*, que garantidamente pode endereçar qualquer localização válida na memória.&lt;br /&gt;&lt;br /&gt;Valores do tipo byte são apenas copiáveis; é possível, no mínimo, reproduzir o padrão de bits de uma armazenagem para a outra.&lt;br /&gt;Valores do tipo address&lt;t&gt; são copiáveis; além disso, o domínio de address&lt;t&gt; é equivalente ao domínio dos naturais, e suporta a mesma aritmética; por fim, existe a operação de-referência, que transforma um valor address&lt;t&gt; em um valor T.&lt;br /&gt;&lt;br /&gt;Com esses dois tipos podemos fazer muito pouco, mas podemos fazer algo; é possível escrever um programa capaz de copiar dados de um dispositivo para o outro apenas com byte e address&lt;t&gt;. Seria também possível escrever programas capazes de rearranjos e outras operações similares.&lt;br /&gt;&lt;br /&gt;Esses programas não poderiam ser muito sofisticados porque os únicos julgamentos possíveis seriam sobre localizações de objetos, e não seus valores. Seria possível, por exemplo, escrever um programa que inverte uma sequência de bytes, etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-1888911903431537837?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/1888911903431537837/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=1888911903431537837' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/1888911903431537837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/1888911903431537837'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/08/declaracoes-nomes-e-objetos.html' title='Declarações, nomes e objetos'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3006142001944566780.post-6260156903107536611</id><published>2009-08-17T14:12:00.003-03:00</published><updated>2009-08-17T14:44:29.531-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Tipos de dados primitivos</title><content type='html'>Após uma longa considerção sobre o assunto, e bastante tempo livre durante as férias, cheguei a uma opinião sobre que conjunto de tipos de dados primitivos eu gostaria de ver em Pedro C++.&lt;br /&gt;&lt;br /&gt;A idéia de que há signed e unsigned como qualificadores distintos do tipo de dados não me parece muito coerente; um signed integer e um unsigned integer são valores em domínios completamente distintos. De fato, um unsigned integer é um natural, e foi essa intuição que me levou eventualmente a compilar a seguinte lista:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;byte&lt;/li&gt;&lt;li&gt;address&lt;/li&gt;&lt;li&gt;natural&lt;/li&gt;&lt;li&gt;integer&lt;/li&gt;&lt;li&gt;rational&lt;/li&gt;&lt;li&gt;real&lt;/li&gt;&lt;li&gt;complex&lt;/li&gt;&lt;/ul&gt;Com os tipos primitivos byte a address seria possível escrever um sistema capaz de transportar dados entre dispositivos. Um tal sistema, ou sub-sistema, não tem interesse na representação de um dado; isso percebe-se claramente nas APIs de I/O do Unix, cujo tipo de dado é void*. Este tipo, em Pedro C++, seria um address&lt;byte&gt;.&lt;br /&gt;&lt;br /&gt;Para a computação matemática pura temos a seleção completa de domínios algébricos. natural, integer e real são verdadeiramente primitivos, enquanto rational e complex são derivados destes. Em uma máquina convencional, natural é representado diretamente em base 2, integer é representado em base 2 por complemento de dois, e real é representado na forma dada em IEEE 754. Uma linguagem rica permitira que esses tipos sejam genéricos no tamanho; natural&lt;16&gt; é um natural ocupando dois bytes, integer&lt;64&gt; é um inteiro ocupando 8 bytes.&lt;br /&gt;&lt;br /&gt;Deve ser possível, com base em natural, implementar qualquer domínio homomórfico com os naturais, como por exemplo caracteres em um mapa de caracteres.&lt;br /&gt;&lt;br /&gt;É claro que nada disso é remotamente suficiente para uma linguagem na prática; é preciso ainda falar sobre muitas coisas muito simples, como a representação e o tipo de valores representados literalmente no programa etc.&lt;br /&gt;&lt;br /&gt;NOTA: não tenho certeza se "homomórfico" foi a palavra certa ali em cima.&lt;br /&gt;&lt;/byte&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3006142001944566780-6260156903107536611?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/6260156903107536611/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=3006142001944566780&amp;postID=6260156903107536611' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/6260156903107536611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3006142001944566780/posts/default/6260156903107536611'/><link rel='alternate' type='text/html' href='http://blog.pedro.lamarao.nom.br/2009/08/tipos-de-dados-primitivos.html' title='Tipos de dados primitivos'/><author><name>P.</name><uri>http://www.blogger.com/profile/17225059287120136369</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05731774647395903785'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry></feed>