3 pontos por GN⁺ 2025-08-29 | 1 comentários | Compartilhar no WhatsApp
  • Introdução ao conceito do tipo Uncertain<T>, uma nova abstração para lidar com incerteza no nível do código
  • Esse tipo aplica a metodologia de programação probabilística para modelar a confiabilidade ou possibilidade de valores no lugar da lógica booleana tradicional
  • Oferece recursos para tratar dados reais com muito ruído, como GPS e dados de sensores, por meio de distribuições de probabilidade matemáticas
  • Dá suporte ao equilíbrio entre eficiência computacional e confiabilidade dos resultados com técnicas de amostragem como SPRT e métodos de Monte Carlo
  • Permite integração gradual com código existente, o que o torna altamente aplicável na prática

Codificando a incerteza: a lacuna entre confiança e dados reais

  • Menciona o fenômeno de muitas pessoas dependerem excessivamente de certezas
  • Aponta que, com mais experiência em desenvolvimento de software, aumenta a frequência com que se diz “depende da situação”
  • No código, porém, continua se repetindo o padrão de depender apenas de julgamentos de verdadeiro/falso
  • Critica a realidade de, especialmente ao lidar com dados incertos como GPS, ainda se usarem apenas valores booleanos
  • O modelo de programação binariza cedo demais a ‘incerteza’ do mundo real e acaba escondendo sua complexidade

Escolhendo a abstração correta

  • Em 2014, a University of Washington e a Microsoft Research propuseram um conceito que reflete diretamente a incerteza no sistema de tipos
  • Pelo artigo "Uncertain<T>: A First-Order Type for Uncertain Data" demonstraram que a abordagem de programação probabilística é prática
  • O código que porta o conceito para Swift foi publicado no repositório do GitHub
  • Com Uncertain<T>, até o resultado de comparações é expresso como probabilidade relativa, retornando Uncertain<Bool> em vez de verdadeiro/falso
  • O erro de posição de GPS é modelado de acordo com características de dados reais, como a distribuição de Rayleigh

Como diferentes operações de incerteza funcionam na prática

  • Suporta vários operadores e modelos de distribuição probabilística, construindo um grafo de operações e executando amostragem apenas quando necessário
  • Usa SPRT (Sequential Probability Ratio Testing) para ajustar com eficiência o número de amostras
  • O código de exemplo explica a diferença no número de amostras necessárias entre comparações simples e comparações compostas
  • Com essa abstração, é possível não ignorar a incerteza e usá-la naturalmente no processo de cálculo, implementando um código mais “inteligente”

Aplicação da metodologia de Monte Carlo

  • Introduz amostragem de Monte Carlo para análise de distribuições de probabilidade e cálculo de valor esperado
  • Na prática, é possível obter o valor esperado com facilidade simulando repetidamente os resultados de uma máquina caça-níquel
  • Mesmo sem cálculos analíticos complexos, o computador pode produzir resultados realistas apenas com amostragem repetida

Modelagem rica de distribuições de probabilidade

  • Uncertain<T> inclui construtores para diversas distribuições de probabilidade, permitindo modelar com precisão dados do mundo real como ruído de sensores, comportamento do usuário e latência de rede
  • Suporta parametrização para vários cenários, como mixture, Bernoulli, exponential e normal
  • Para ajudar na compreensão intuitiva de cada distribuição, também é oferecido um projeto de visualização interativo separado

Funções estatísticas e de análise disponíveis

  • Oferece várias funções estatísticas, como valor esperado, desvio padrão, intervalo de confiança, skewness, kurtosis e entropia
  • O resultado das operações também permite ajustar o número de amostras, possibilitando um trade-off entre precisão e eficiência
  • Com a função de distribuição acumulada (CDF), também fica fácil calcular a probabilidade de um valor estar abaixo de um determinado limite

Guia de aplicação no mundo real

  • Explica problemas que podem surgir em apps quando a incerteza é ignorada (por exemplo, exibir uma velocidade de GPS absurda)
  • Enfatiza a transição gradual: recomenda integrar Uncertain<T> parcialmente, começando por caminhos críticos como medição de distância
  • É possível ajustar o equilíbrio entre precisão e desempenho por meio de configurações de custo computacional, como o número de amostras
  • No trabalho prático, recomenda usar ativamente ferramentas de profiling como Instruments.app
  • O objetivo não é eliminar a incerteza, mas reconhecer sua existência e estabelecer um padrão de desenvolvimento para tratá-la adequadamente

Conclusão e perspectivas

  • Desenvolvedores podem introduzir o tratamento de incerteza em áreas pequenas primeiro, esperando melhorias de usabilidade e redução de erros
  • Ao aceitar que a certeza completa não existe, é possível elevar a qualidade do software com ferramentas e abstrações adequadas
  • Na prática, a verdadeira melhoria profissional está em lidar corretamente com a incerteza que de fato existe

1 comentários

 
GN⁺ 2025-08-29
Opiniões do Hacker News
  • A incerteza do GPS geralmente só pode ser aproximada como circular em condições específicas, como posicionamento por longos períodos sob céu aberto; na prática, o modelo completo de erro é muito mais complexo e existem várias formas de medir esse erro. Isso se torna importante em muitas situações nas quais é difícil tratar a posição como um único ponto. No caso de carros autônomos, por exemplo, é comum encontrar cenários em que a incerteza da estimativa de posição é dominada por efeitos de multipercurso não circulares. Se você pensar profundamente nessas dificuldades, acaba chegando ao ponto de reinventar técnicas como filtros de partículas
    • O GPS automotivo normalmente é complementado com vários sensores e hipóteses adicionais, especialmente odômetro, bússola e o conhecimento de que o veículo provavelmente estará em uma das estradas do mapa. Além disso, a hipótese de que não houve mudança de posição entre o último desligamento e a reinicialização permite uma localização rápida
    • Os pontos de LiDAR, na verdade, não são pontos simples, mas existem como elipsoides centrados na posição mais provável
  • Na University of Cambridge, projetei uma microarquitetura de processador inspirada em Uncertain<T> (James Bornholt) e em pesquisas relacionadas. Ela foi projetada para carregar não apenas distribuições paramétricas (Gaussian, Rayleigh etc.), mas também conjuntos arbitrários de amostras em registradores/memória, de modo que os valores do programa se propaguem pelas operações aritméticas como distribuições não paramétricas. Com base nessa tecnologia, uma spin-off chamada Signaloid está entrando no mercado, e eu também estou pesquisando sua aplicação em estimação de estado (por exemplo, filtros de partículas) link para o artigo
  • Quando se entende a ideia de que uma variável em programação pode carregar a “especificação” de uma variável matemática, abrem-se possibilidades surpreendentes que estão na base da IA moderna. Pense na fórmula familiar y = m * x + b: quando todos esses termos são literais, ela é apenas uma função de renderização simples; mas, se as variáveis carregarem toda a estrutura do caminho de operações do qual foram derivadas, é possível prever valores conforme a direção da computação e renderizar (forward pass), ou então obter automaticamente gradientes/derivadas e até conectá-los ao treinamento de redes neurais. Ao amostrar matematicamente esses resultados computados, torna-se possível obter os pesos que formam o modelo. Cada camada de deep learning é projetada assim, e sistemas como PyTorch conseguem compilar código ótimo apenas com a especificação da composição das operações. Ou seja, Uncertain<T> é só o ponto de partida; imaginar que toda variável numérica pode, a qualquer momento, ser definida por metadados de valores candidatos, e que esses metadados podem ser manipulados com a mesma facilidade de um valor de variável, é um experimento muito interessante
    • Isso parece realmente fascinante. Gostaria de saber se alguém consegue explicar de forma que até alguém como eu, que não tem muito conhecimento de machine learning ou matemática, consiga entender facilmente
    • Fico curioso se existe algum caso real, entre linguagens PL (linguagens de programação), que ofereça esse tipo de conceito no nível da linguagem
    • Parece que este comentário está misturando variáveis, funções e sistemas lineares; não acho que haja necessidade de juntar tudo isso dessa forma
  • Fico curioso se a covariância entre várias variáveis também pode ser tratada dessa forma. Por exemplo, a própria posição do objeto medido pode ter erro, e esse erro pode ter correlação com o erro da minha posição também (ainda mais se ambos foram medidos pelo GPS no mesmo instante). Se o sistema de tipos tiver apenas um modelo univariado, isso já pode ser útil, mas se também lidar com covariância, o uso seria muito mais poderoso e preciso
    • Com uma abordagem baseada em amostragem, a modelagem de covariância fica incluída automaticamente. Basta amostrar uma única vez os valores folha usados várias vezes em um mesmo processo de avaliação, e dá para confirmar que a implementação realmente faz isso no código abaixo código do Uncertain.swift
    • Faz tempo que me pergunto se um programa poderia “aprender” a covariância durante o uso real. Se as variáveis forem modeladas de forma independente, parece que isso vai se desviar continuamente da realidade. E, em programas grandes, considerar manualmente a correlação entre todos os pares de variáveis é praticamente impossível. Talvez seja preciso criar uma forma de aprender isso automaticamente
    • Se você precisa de rastreamento de covariância, também recomendo explorar a biblioteca gvar para Python
    • Se quisermos modelar corretamente a mecânica quântica, seria necessário associar uma função de onda complexa a cada conjunto de variáveis emaranhadas
  • Em desenhos de engenharia mecânica e similares, usa-se o conceito de “tolerância” para se comunicar com o operador de usinagem; por exemplo: 10 cm +8 mm/-3 mm, deixando claro o intervalo permitido acima e abaixo. Também em perguntas baseadas em GPS como “já estamos quase chegando?”, parece importante entender a direcionalidade do erro e distinguir casos melhores ou piores conforme a “direção” da incerteza
    • O problema dessa notação é que, em alguns casos, ela pode significar “nunca ultrapassa o limite máximo/mínimo”, enquanto em outros pode ser interpretada como “só ultrapassa o limite em 10% dos casos”
    • Isso é parecido com a estimativa de três pontos (otimista, realista, pessimista), muito usada em planejamento. Mesmo uma distribuição de probabilidade muito simples oferece muito mais clareza em qualquer área onde a incerteza entra em cena
  • Esse conceito já foi implementado várias vezes no passado com o nome de “interval arithmetic”, e há suporte também em Boost e flint Boost Interval flint(arb). Apesar de ter sido redescoberto repetidamente, fico curioso por que isso nunca se tornou realmente mainstream. Se alguém já usou isso na prática e desistiu por não ter gostado, gostaria de ouvir a experiência
    • O texto explica que Uncertain<T> usa a distribuição de Rayleigh para a incerteza do GPS. A distribuição de Rayleigh não é uniforme, e modela melhor a distribuição de erro do mundo real. Por exemplo, se você calcular (-2,2)*(-2,2) na biblioteca Boost, o resultado será (-4,4), mas em termos probabilísticos a ocorrência simultânea dos extremos é muito menos provável, então algo como (-2.35,2.35) seria mais realista
    • Em física, aprendemos cedo sobre propagação de erro (error propagation). Se assumirmos que os erros seguem distribuição gaussiana, o cálculo fica muito elegante, mas, na prática, a maioria das medições não segue distribuição gaussiana, e erros não probabilísticos (sistemáticos) passam a ser o problema. Como isso é difícil de tratar corretamente, a propagação automática de erro muitas vezes quase não serve para nada. Na maioria dos casos, é necessária análise manual
    • Não entendo por que este texto está recebendo tanta atenção. Este projeto não oferece apenas interval arithmetic, mas suporta várias distribuições de incerteza
    • Tipos simples como Boolean permitem inferência fácil e têm restrições claras. Já a incerteza física é complexa, então o modelo precisa variar conforme o domínio. Uma vez que você decide lidar com incerteza complexa, provavelmente faz mais sentido usar um modelo especializado para o objetivo em questão do que apenas uma biblioteca elegantemente empacotada
    • A interval arithmetic é apenas um fator constante mais lenta do que operações numéricas simples, sem grande diferença, e para toda operação existe um resultado de intervalo intrinsecamente mais preciso. No entanto, isso não significa que a precisão seja sempre garantida. Já um grafo de operações com amostragem, como no texto, é mais lento, mas em compensação pode se aproximar com mais fidelidade do modelo de erro real. Tem a vantagem de não precisar de um domínio abstrato que sacrifique precisão
  • O tipo de dado que eu queria criar era algo que representasse o quanto um certo valor é conhecido dentro de uma distribuição de probabilidade dada (ou função densidade de probabilidade), e cada transformação acrescentaria seu próprio nível de incerteza. Eu imaginava um fluxo em que, à medida que aumentam as observações (ou muda a classificação condicional), esse conjunto de distribuições de probabilidade vai sendo refinado continuamente. No fim, o objetivo era simular casos de resultados aleatórios baseados nessas distribuições
  • Essa ideia também está intimamente relacionada ao antigo Functional Pearl “Probability Functional Programming” link para o PDF, muito legal. Eu começo a primeira aula de introdução a Haskell demonstrando o problema de Monty Hall com um mônada de probabilidade, calculando abertamente as probabilidades de vitória das duas estratégias como frações inteiras
  • Talvez fosse melhor se Uncertain fosse o tipo padrão, e só nos casos realmente certos a gente explicitasse separadamente certain T
    • Para medições físicas, isso faz sentido, mas objetos como dinheiro precisam ser exatos até as casas decimais. Aliás, essa abordagem já foi implementada em algumas bibliotecas modernas de Fortran
    • Pode funcionar como um complemento ao tipo Optional
  • Fico me perguntando se isso é, assintoticamente, uma versão de programação de fuzzy logic Wikipedia de Fuzzy Logic