História (1978): Podemos nos Libertar do Estilo de von Neumann?

Anos 70, quando os mainframes e as linguagens procedurais FORTRAN e COBOL reinavam. A complexidade nos negócios aumentava e o mundo da computação parecia estar em um beco sem saída, quando o artigo abaixo foi publicado. Era preciso um novo paradigma e os questionamentos emergiam de todos os lados. Uma nova concepção de software surgiria em 1979, com a linguagem C e o paradigma de Orientação a Objetos. Mas nunca nos libertamos da Máquina de von Neumann. Isso virá um dia com a computação quântica, que ainda dá seus primeiros passos.

Uma máquina de von Neumann, projetada pelo físico e matemático John von Neumann (1903–1957) é um projeto teórico para um computador de uso geral. Uma máquina de von Neumann consiste em um processador central (dir.) com uma unidade lógica/aritmética (ULA), uma unidade de controle e uma memória (esq.).

* * *

A programação pode se libertar do estilo de von Neumann? Um estilo funcional e sua álgebra de programas

Resumo

As linguagens de programação convencionais estão ficando cada vez maiores, mas não mais fortes. Defeitos inerentes ao seu nível mais básico as tornam inchadas e fracas: seu estilo primitivo de programação ‘palavra-por-vez’ herdado de seu ancestral comum – o computador de von Neumann; seu acoplamento íntimo da semântica a transições de estado; sua divisão da programação em um mundo de expressões e um mundo de declarações; sua incapacidade de usar eficazmente formas combinantes poderosas para construir novos programas a partir dos existentes; e sua falta de propriedades matemáticas úteis para raciocinar sobre programas.

Um estilo funcional alternativo de programação baseia-se no uso de formas combinantes para a criação de programas. Os programas funcionais lidam com dados estruturados, são frequentemente não repetitivos e não recursivos, são construídos hierarquicamente, não nomeiam seus argumentos e não exigem que o mecanismo complexo de declarações de procedimento se torne aplicável de forma geral. Formas combinantes podem usar programas de alto nível para construir outros programas de nível ainda mais alto, em um estilo não possível em linguagens convencionais.

Uma álgebra de programas cujas variáveis ​​abarcam todo um programa e cujas operações são formas combinantes é relacionadas ao estilo funcional de programação. Essa álgebra pode ser usada para transformar programas e resolver equações cujas “incógnitas” são também programas como as transformações de equações na álgebra do ensino médio. Essas transformações são dadas por leis algébricas e são executadas na mesma linguagem em que os programas são escritos. As formas combinantes são escolhidas não apenas por seu poder de programação, mas também pelo poder das leis algébricas associadas a elas. Teoremas gerais dessa álgebra fornecem o comportamento detalhado e as condições de término [halting conditions] para grandes classes de programas.

Uma nova classe de sistemas de computação usa o estilo de programação funcional tanto em sua linguagem de programação quanto em suas regras de transição de estado. Ao contrário das linguagens de von Neumann, esses sistemas têm semântica fracamente acoplada a estados – apenas uma transição de estado ocorre por computação principal.

Ver transcrição do artigo original em Association for Computing Machinery.

Sexta de Leão: Aventuras no Jardim Murado

Poucos meses atrás, enquanto eu desenvolvia um pequeno aplicativo desktop [um trabalho acadêmico] para Windows, Mac e Linux, em algum momento do desenvolvimento tive que testá-lo em todas as três plataformas. Para tornar o teste mais fácil, decidi instalar todos os três sistemas operacionais no mesmo computador, por meio de uma máquina virtual. As coisas corriam bem, até que cheguei ao MacOs.

De acordo com a política da Apple, você não tem permissão para instalar MacOs em um hardware que não seja da própria Apple. Então, como faço para testar meu software se não sou proprietário de um Mac?

O que eu podia fazer:

  • Comprar um Mac (onde o mais barato no momento custa mais de US$ 1000)
  • Pegar um Mac emprestado de alguém
  • Instalar um Hackintosh em uma máquina virtual e violar a política da Apple.

Comprar um Mac. Se você está desenvolvendo um produto que pode trazer uma receita razoável dos usuários de Mac, então a necessidade de comprar um Mac é indiscutível. Se esse não é o caso, então despejar algumas centenas de dólares no negócio só “porque sim” é algo injustificável.

Sua segunda opção é pegar emprestado o Mac de alguém que você conhece. Considerando o quão pequenos são os discos rígidos do Macbook, o proprietário não ficará feliz por você instalar um ambiente de desenvolvimento completo na máquina dele – e possivelmente deixar gigabytes de material instalado para trás. Você também teria que se adaptar à rotina de uso e tempo do proprietário, o que poderia ser bastante irritante [como assim “sua filha precisa escrever um trabalho esta noite?”].

E, por último, você pode mandar a Lei às favas e instalar um MacOs em uma máquina virtual. Uma rápida pesquisa revela centenas de tutoriais e postagens de blog sobre a instalação de MacOs. Todos instalando imagens ISO piratas tiradas do Google Drive de alguém – e agindo como se tivessem acabado de descobrir o fogo.

Obviamente escolhi a terceira opção, pois parecia a melhor de todas as escolhas ruins possíveis. Depois de passar alguns dias remexendo na ISO “ilegal” do Mac e não conseguir passar da tela de boot, era hora de refletir sobre o que estava acontecendo.

Imagem: iStock

Escrever um aplicativo desktop multiplataforma é uma tarefa muito mais difícil do que escrever um aplicativo para a web, já que o conjunto de ferramentas para esta última não é tão polido. Isso explica por que os aplicativos para web estão em todo lugar e o software para desktop está lentamente desaparecendo.

Além dos problemas gerais que o desenvolvimento de aplicativos traz, também existem inúmeras tarefas que são específicos de certas plataformas, apesar de os frameworks serem multiplataforma. É preciso por exemplo:

  • Criar soluções alternativas para todos os bugs da plataforma específica da interface de usuário (IU) escolhida. A estrutura pode estar funcionando bem em uma plataforma e se comportando de maneira extremamente estranha em outra.
  • Configurar uma máquina/ambiente de compilação para cada plataforma que você está oferecendo. A compilação cruzada de aplicativos desktop infelizmente ainda não é uma opção disponível em 2021.
  • Criar um instalador para cada sistema operacional e descobrir – depois – as especificações de instalação de cada um.
  • Descobrir que certas plataformas gritam com seus usuários quando eles tentam instalar um software que não possui um instalador assinado.

Você logo percebe que assinar um instalador em cada plataforma existente não é barato [e de fato é um aborrecimento que não leva a nada]. No Windows, você tem o prazer adicional de lidar com ‘revendedores’ duvidosos de certificados. Dê uma olhada em um dos sites deles [ou melhor não – eles são fraudes e podem roubar suas informações de cartão de crédito].

Eu me senti sujo depois de visitá-los. Você poderia, como alternativa, usar lojas online credenciadas que supostamente não têm esses problemas, mas a esta altura você realmente tem ainda vontade de fazer isso? Você dá o melhor de si para uma empresa que pode um dia simplesmente decidir que o seu aplicativo não está mais de acordo com a nova política e removê-lo de sua loja sem a menor cerimônia. Você também tem que passar pelo complicado processo de verificação de “malware” no software que você criou, o que pode, em alguns casos, levar semanas e, no fim, rejeitar seu trabalho sem nenhuma explicação. Existem dezenas de histórias de horror sobre isso na Internet. Reserve um tempo para conhecê-las antes de decidir seguir por este caminho.

Como você pode ver, desenvolver um aplicativo para desktop não envolve apenas programar a IU. O resto da subida da montanha é lidar com problemas que nem deveriam estar presentes. E se, no final, testar o software em uma determinada plataforma for muito trabalhoso, essa plataforma simplesmente não terá suporte. Este parece ser o caso recentemente, já que nem me lembro da última vez que vi um aplicativo multiplataforma. Eles são sempre vinculados a uma plataforma específica ou baseados na web.

Imagem: iStock

No final, todo mundo perde com a política do jardim murado:

  • Os usuários vão perder seu software favorito, que só existe em uma determinada plataforma.
  • Os desenvolvedores vão perder as vendas que a outra plataforma pode trazer.
  • As lojas online vão perder o percentual de sua receita, pois o desenvolvedor muitas vezes simplesmente não tem interesse em lidar com processos complicados. As plataformas deveriam tornar sua vida mais simples; em vez disso, apenas adicionam camadas de burocracia.

Laissez faire!

A Microsoft tem ouvido um monte de merda sobre seu último Windows 10. Ele tem seu próprio conjunto de problemas, como a telemetria intrusiva e a grande quantidade de ‘crapware’ aleatório – que ninguém pediu – instalado por padrão. Mas pelo menos a Microsoft faz alguma média com os desenvolvedores. Você pode instalar o Windows como quiser – seja no metal nú ou em uma máquina virtual [e ele ainda funciona em um computador com 10 anos de idade!].

A Apple, por outro lado, está erguendo muralhas cada vez maiores em torno de sua plataforma. Sua última manobra foi impedir os usuários de executar qualquer aplicativo que não tenha sido certificado. O que significa basicamente “se não tiver nossa benção a cada passo, você não vai poder usar sua máquina”. É como a mílícia que vai confiscar a sua casa se você não pagar a proteção.

Os usuários, que pagaram o dobro do que custaria um PC, agora também têm que lutar contra um ecossistema que absurdamente os impede de usar seu próprio computador. Quem diria que instalar um editor de texto é uma coisa tão perigosa? Isso vindo de uma empresa que afirma que o uso de seus produtos irá ajudá-lo a “liberar a criatividade” – e um monte de outras bobagens corporativas.

Então solução é a seguinte para os fãs da Apple: se quiserem ter programas em sua amada plataforma, vocês terão que torná-la amigável para os desenvolvedores. Nota: os desenvolvedores são aqueles que escrevem os aplicativos, publicando-os em suas ‘stores’. Se eles não puderem usar sua plataforma de trabalho preferida (que, surpresa-surpresa, pode não ser o Mac), isso significa que eles simplesmente não publicarão o software para sua plataforma.

Quanto à Apple, ela pode continuar com a muralha de pedra cercando o seu jardim, se assim quiser. Ela pode continuar cobrando a entrada, se há um número suficiente de pessoas dispostas a pagar. E se você gosta da Apple, seja feliz dizendo a todos como é lindo seu jardim.

Mas eu pessoalmente não gosto do jardim da Apple. Não gosto da maneira ‘Apple’ de fazer as coisas, dizendo às pessoas que elas estão usando seus produtos de maneira errada. Eu não gosto de como a Apple é arrogante e não joga com o resto do mundo. E, francamente, nunca gostei de Steve Jobs.

Existem jardins de mente mais aberta, onde você é responsável por administrar seu canto como quiser. Um jardim onde derrubar uma parede para dar mais espaço para as suas coisas é algo perfeitamente possível e não desaprovado. Enfim, que a Apple não rejeite aqueles que fazem valer a pena visitar seu jardim.

Catala: Uma Linguagem de Programação para o Mundo Jurídico

Um interessante trabalho com este nome foi pré-publicado no site ArXiv no dia 4 de março último [dia em que o blog nasceu], apresentando a linguagem de programação Catala. Segundo seus criadores “é uma linguagem adaptada para programação sócio-fiscal-legislativa; uma linguagem que imita a estrutura lógica da lei”. A estrutura lógica da linguagem foi formalizada pela Professora Sarah Lawsky em seu artigo “Uma Lógica para Estatutos”. Apresentamos o resumo do artigo do ArXiv e os comentários do blog a respeito.

Catala: A Programming Language for the Law
DENIS MERIGOUX, Inria, France
NICOLAS CHATAING, Inria ENS Paris, France
JONATHAN PROTZENKO, Microsoft Research, USA

Resumo

A lei em geral sustenta a sociedade moderna, codificando e governando muitos aspectos da vida diária dos cidadãos. Muitas vezes, a lei está sujeita a interpretação, debate e contestação em vários tribunais e jurisdições. Mas em algumas outras áreas, o direito deixa pouco espaço para interpretação e visa essencialmente descrever com rigor um cálculo, um procedimento de decisão ou, simplesmente, um algoritmo. Infelizmente, a prosa sempre foi uma ferramenta lamentavelmente inadequada para o trabalho. A falta de formalismo deixa espaço para ambiguidades; a estrutura dos estatutos legais, com muitos parágrafos e subseções espalhados por várias páginas, torna difícil calcular o resultado pretendido do algoritmo subjacente a um determinado texto; e, como acontece com um software crítico mal especificado, o uso de linguagem informal deixa os casos mais difíceis sem solução.

Apresentamos Catala, uma nova linguagem de programação que projetamos especificamente para permitir uma tradução direta e sistemática da lei estatutária em uma implementação executável. Catala tem como objetivo reunir advogados e programadores através de um meio compartilhado, onde juntos eles possam entender, editar e evoluir, preenchendo uma lacuna que muitas vezes resulta em implementações dramaticamente incorretas da lei.

Implementamos um compilador para Catala e provamos a exatidão de suas etapas principais de compilação usando o assistente de prova F *. Avaliamos Catala em vários textos legais – que são algoritmos disfarçados, notadamente a seção 121 do imposto de renda federal dos Estados Unidos e os benefícios familiares bizantinos da França; ao fazer isso, descobrimos um “bug” na implementação oficial da lei . Observamos, como consequência do processo de formalização da linguagem, que o uso da Catala permite ricas interações entre advogados e programadores, levando a uma maior compreensão da intenção legislativa original, enquanto produz uma especificação executável “correta-por-construção”, reutilizável por um ecossistema de software maior.

Link para o trabalho na íntegra

Minhas considerações

Sarah B. Lawski. Professor of Law
Associate Dean of Academic Programs – Northwestern-Pritzker School of Law
(autora do trabalho “Uma Lógica para Estatutos“).

Voltando aqui para o home office, eu diria, em minha modesta opinião, que o fato de uma lei ser internamente consistente e livre de lacunas não significa necessariamente que ela seja uma boa lei. Uma abordagem algorítmica para a criação de tais procedimentos corre o risco de se tornar muito cientificista e automática [daí autoritária], de modo que podemos acabar com um grande corpo de leis que não pode ser questionado “porque foi ‘provado’ que está correto”. Lembro-me de uma observação que [o cientista da computação e matemático] Donald Knuth fez a respeito de um certo trecho de código. Era mais ou menos assim: “Cuidado ao usar isto; eu apenas provei que está correto, mas não tentei executá-lo”.

Por outro lado, o resumo do trabalho menciona que eles já descobriram um “bug” em uma lei ativa ao reescrevê-la em sua linguagem computacional. Portanto, essa pode ser uma ferramenta extremamente útil para encontrar casos extremos e brechas na legislação. E novamente, como o resumo menciona, para minha tranquilidade, o projeto se destina a leis que devem ser interpretadas 100% literalmente como um algoritmo. Essas leis existem e são exatamente aquelas que deveriam ser absolutamente consistentes.

Vou dar um exemplo de um campo em que, imagino, a lei e os contratos devem ser interpretados 100% literalmente como um algoritmo: finanças estruturadas. O prospecto de um título estruturado, por exemplo um título hipotecário, consiste normalmente de cem ou mais páginas de um texto jurídico muito denso, que foi trabalhado intensamente por advogados e banqueiros altamente especializados durante meses. Sua intenção é criar, digamos, uma empresa, de propósito específico, com regras rígidas sobre como operar até o último centavo, e discrição zero. Isso permite que os investidores (em teoria) entendam como será o desempenho do título.

Na literatura introdutória à análise de crédito estruturado, que tenho estudado, um dos autores diz que nunca leu um prospecto para um título estruturado que não contivesse erros de redação. Esse é um tipo de erro que não pode ser encontrado por um sistema formal determinístico, como a máquina de Turing de nossos computadores.

Eu concordo com o sentimento, no que se refere aos erros. De fato, os engenheiros têm a capacidade de automatizar alguns problemas muito complexos, mas sempre haverá uma classe de problemas além da automação, simulação, análise, etc. Temos apenas que aceitar que a única maneira de resolvê-los é com trabalho lento, difícil e sujeito a erros. Algumas coisas são simplesmente complexas demais para se fazer [note que estamos falando de computação clássica].

Essa é uma novidade sofisticada da qual se espera que ajude a evitar erros, reduzir custos do sistema jurídico, aumentar a consistência, etc. Tenho a impressão, porém, que ela será aplicada às leis existentes de forma mais geral do que o resumo parece sugerir.

Novas leis serão feitas com esse novo fator em mente, aumentando a aplicação da ideia, independentemente de as novas leis serem ou não interpretáveis ​​literalmente. Catala provavelmente não causará uma revolução jurídica amanhã, mas espero que possa ser o início de uma lenta reforma em direção à precisão linguística e à compatibilidade com as máquinas na legislação do futuro.

Post Scriptum

Um texto sobre linguagem de programação não poderia estar completo sem um exemplo da sintaxe. Pensei em dar uma mostra interessante e bastante genérica de como a Catala poderia ser implementada. Isso motivou uma visita ao wiki para pesquisar algum exemplo histórico de dispositivo legal. O que descobri não podia ser mais a propósito: o código de Ur-Nammu [ver DuckDulckGo ou Google], a mais antiga peça de legislação que se conhece. Escolhi como exemplo o artigo 14, que me parece bem em linha com os mores de nosso tempo, e que dispõe basicamente:

Se um homem acusou a esposa de um homem de adultério, e a provação do rio provar sua inocência, então o homem que a acusou deve pagar um terço de uma mina de prata.

Código de Ur-Nammu, art. 14

Eis a justiça em ação. Se ela se afogar, ela é culpada. Se ela sobreviver, alguém receberá 1/3 de uma mina de prata. O rei Ur-Nammu é vago aqui quanto a quem fica com o dinheiro. Provavelmente o marido.

Como poderíamos codificar isso em Catala? Vou começar, e quem quiser pode contribuir nos comentários:

declaration structure Pessoa:
    data id content integer

  declaration structure Periodo:
    data inicio content date
    data fim content date

  declaration structure CasalCasado:
    data adulterio_data content date
    data marido content Pessoa
    data mulher content Pessoa
   
  declaration structure AcusacaoDeAdulterio:
    data casal1 content CasalCasado
    data acusador content Pessoa
    data adulterio_data content Periodo
   
  declaration structure Rio
    data id content integer
 
  declaration structure ProvacaoPelaAgua:
    data acusado content Pessoa
    data rio1 content Rio
    data data_da_provacao content Periodo

  declaration scope LeiDeUrNammu:
    context requisitos_atendem condicao
    context casados_atendem condicao
    context acusado_enquanto_casado_atende condicao
    context provado_pela_água_atende condicao

Conceito da Linguagem (Segundo os criadores, no GitHub)

Catala é uma linguagem adaptada para a programação sócio-fiscal ancorada na legislação. Ao anotar cada linha do texto legislativo com seu significado em termos de código, pode-se derivar uma implementação dos complexos mecanismos sócio-fiscais que apresentam um alto nível de segurança quanto à fidelidade do código-lei.

Concretamente, primeiro você deve reunir todas as leis, ordens executivas, casos anteriores, etc. que contenham informações sobre o mecanismo sócio-fiscal que você deseja implementar. Em seguida, você pode prosseguir para anotar o texto artigo por artigo, em seu editor de texto favorito:

Depois que seu código estiver completo e testado, você pode usar o compilador Catala para produzir uma versão PDF de sua implementação legível por advogado. A linguagem Catala foi especialmente desenvolvida em colaboração com profissionais do direito para garantir que o código possa ser revisado e certificado como correto pelos especialistas de domínio, que neste caso são advogados e não programadores.

Captura de uma tela com uma rotina em Catala

Código: O Que Há em Um Nome

Este post registra em português o recém lançado pre-print de um estudo que avalia a maneira como os nomes de funções e variáveis são normalmente usados na composição de um programa de computador, e qual seu impacto na facilidade de compreensão e manutenção do código. O trabalho sugere que sejam usados nomes menos obfuscados e mais expressivos na nomenclatura desses elementos de código, como no exemplo:

// Este fragmento mostra os nomes, obfuscados e
// inexpressivos, para a função exibeNum() e suas variáveis
// internas n1 e n2

void exibeNum(int n1, float n2) {
    cout << "O número int é: " << n1;
    cout << "O número float é: " << n2;
}

// Este fragmento mostra uma nomenclatura mais clara e
// expressiva para as mesmas funções e variáves, 
// agora renomeadas

void funcao_que_exibe_numero(int numero_1, float numero_2) {
    cout << "O número int é: " << numero_1;
    cout << "O número float é: " << numero_2;
}

Este é um daqueles assuntos que nunca são citados nominalmente, mas que estão logo abaixo da superfície, e são fundamentais para produtividade de uma equipe de programação. Ao trabalho:

Resumo

Os nomes de variáveis ​​e funções servem como documentação implícita e são instrumentais para a compreensão de um programa. Mas escolher nomes bons e significativos é difícil. Realizamos uma sequência de experimentos em que um total de 334 sujeitos são obrigados a escolher nomes em determinados cenários de programação. O primeiro experimento mostrou que a probabilidade de que dois desenvolvedores selecionassem o mesmo nome era baixa: Nas 47 instâncias de nossos experimentos, a mediana de probabilidade foi de apenas 6,9%. Ao mesmo tempo, depois que um nome específico é escolhido, ele geralmente é entendido pela maioria dos desenvolvedores. A análise dos nomes fornecidos no experimento sugere um modelo em que a nomeação é um processo (não necessariamente consciente ou serial) de três etapas: (1) Selecionar os conceitos a serem incluidos no nome, (2) Escolher as palavras para representar cada conceito, e (3) construir um nome usando essas palavras. Um experimento de acompanhamento, usando a mesma configuração, então verificou se o uso explícito desse modelo pode melhorar a qualidade dos nomes. Os resultados foram que os nomes selecionados por assuntos utilizados pelo modelo foram julgados, por dois juízes independentes, superiores aos nomes escolhidos no experimento original, em uma proporção de dois para um. O uso do modelo parece incentivar o uso de mais conceitos e nomes mais longos (grifos nossos).

Link para o trabalho integral em ArXiv