2 pontos por GN⁺ 6 시간 전 | 2 comentários | Compartilhar no WhatsApp
  • A sintaxe do JavaScript fica facilmente complexa com parênteses aninhados e callbacks, e até UIs pequenas acabam puxando muitas bibliotecas, causando inchaço
  • WebAssembly abre caminho para executar outras linguagens no navegador, mas, como no Pyodide, o custo da conexão assíncrona com o loop de eventos do JavaScript é alto
  • Como os recursos do navegador e a memória do WebAssembly são limitados, é preciso uma abordagem de negociação, em vez de tentar substituir o JavaScript
  • LispE reúne mais de 450 funções em um único binário WASM de 3.3MB, oferecendo juntos recursos de strings, cálculo, matrizes e expressões regulares
  • Com evaljs e asyncjs, ele aproveita funções JavaScript e o DOM, enquanto reduz o inchaço de código com um único binário auditável no lugar de várias bibliotecas externas

Inchaço do JavaScript e limitações do navegador

  • A sintaxe do JavaScript fica facilmente complexa porque parênteses, chaves e colchetes se sobrepõem e é preciso acertar a ordem de fechamento
    • É mostrado um exemplo de atualização de valores em vários objetos e de renovação condicional de cache dentro de um callback de forEach
newNames.forEach((name, i) => {
    allAgentContents[name] = contents[i];
    agentModes[name] = modes[i];
    if (compiled[i]) agentCompiledCache[name] = compiled[i];
    agentViewingCompiled[name] = viewing[i];
});
  • Para tarefas que uma linguagem de programação básica normalmente incluiria, no JavaScript muitas vezes é preciso baixar muitas bibliotecas
    • C ou C++ também exigem include para trabalhar, mas, no caso das bibliotecas JavaScript, muitas vezes é difícil saber quem implementou e quem faz a manutenção
    • Há páginas que parecem carregar “metade da internet” só para mostrar hello em uma janelinha
  • A internet depende de JavaScript e, mesmo que isso seja escondido com TypeScript, ele continua sendo o porteiro obrigatório toda vez que uma página é aberta no navegador
  • Existia o sonho de que o navegador se tornaria o sistema operacional definitivo, tornando Windows ou Mac OS desnecessários, e o JavaScript foi escolhido como a linguagem para concretizar esse sonho

Relação entre WebAssembly e JavaScript

  • WebAssembly é mais próximo de uma máquina virtual com sua própria linguagem de máquina, abrindo a possibilidade de programar de outra forma dentro do navegador
  • O Pyodide é uma conquista de engenharia impressionante para executar Python no navegador, mas também expõe o custo de operar dentro do domínio do JavaScript
    • O asyncio do Python e o loop de eventos do JavaScript são dois mundos assíncronos que precisam conversar entre si
    • A ponte entre esses dois mundos é frágil, e é preciso lembrar a qual deles cada await pertence
  • Os recursos do navegador são limitados, então é preciso uma forma de pensar parecida com a do início da ciência da computação, analisando cada instrução e estrutura no nível dos bits
    • É apresentado como referência o início da programação em 1981 em um computador com exatamente 15772 bytes livres
    • A memória de um navegador moderno não é tão limitada quanto a daquele primeiro computador, mas o WebAssembly não pode possuir memória livremente como um programa comum e precisa obter permissão prévia de forma restrita
  • A atitude central não é lutar contra o JavaScript, mas negociar com ele

A alternativa proposta pelo LispE

  • LispE oferece mais de 450 funções dentro de um único binário
    • O tamanho do binário WASM é de 3.3 MB
    • Recursos de strings, cálculo, matrizes e processamento de expressões regulares ficam reunidos em um só lugar
    • O binário WASM está em binaries/wasm
  • Embora seja um interpretador pequeno, ele pode lidar com strings, Float64Array, inteiros, números reais e arrays de strings como valores de retorno
  • O LispE é baseado em Lisp, então possui uma estrutura em que a AST permanece viva
  • Se a sintaxe Lisp não agradar, é possível usar uma sintaxe transpilada para uma linguagem difícil de distinguir de Python ou Basic
    • É possível modificar a grammar para criar uma linguagem no estilo desejado
    • Isso também pode ser feito em grego, e já existe um exemplo em grego
  • O LispE coopera com o JavaScript sem enfrentá-lo, aproveitando funções JavaScript e recursos do DOM

Chamadas de JavaScript: evaljs e asyncjs

  • Para executar código JavaScript dentro do LispE, é possível usar evaljs e asyncjs
    • evaljs executa código JavaScript e retorna um valor
    • asyncjs conecta funções JavaScript definidas pelo usuário na página e callbacks assíncronos
(setq a (evaljs "10 + 20 + 30")) ; execute some JS code

; call_llm is a user-defined JS function in the page
(asyncjs `call_llm("Implement a piece of code in Python to sort strings");` 'mycallback)

(defun mycallback(theresult) ...)
  • O asyncjs funciona com uma Promise de que retornará quando o trabalho terminar

Reduzindo o inchaço de código

  • A citação de Wirth de 1995 leva à conclusão de que computadores mais rápidos e modelos maiores não resolvem o problema, e que o código deve continuar enxuto
  • O LispE fornece 450 funções expostas ao navegador em um único binário auditável
    • Para implementar cada recurso separadamente, seria preciso carregar bibliotecas como mathjs para cálculo numérico, lodash para coleções, voca para manipulação de strings e simple-statistics para distribuições estatísticas
    • Essa abordagem pode crescer para centenas de MB de código com autores, bugs e cronogramas de manutenção diferentes
  • O LispE oferece esses recursos em um único código mantido, e, por ser open source, todo o código pode ser auditado
  • Considera-se que o Garbage Collector não destrói o desempenho do código no pior momento
  • Ele se comunica com o JavaScript de forma transparente por chamadas simples de API e pode retornar estruturas predefinidas
// floats here is a Float64Array
const floats = callEvalLispEToFloats(0, `(normal_distribution 100)`);

2 comentários

 
crawler 5 시간 전

O texto pareceu meio aleatório, então desconfiei da fonte, mas era do Naver mesmo, tipo "aff".
Mas, como era de se esperar, a reação não foi boa... Sinceramente, JavaScript já é algo exagerado, então querer usar Lisp chegando ao ponto de subir até um WASM de 3,3 MB é um overengineering difícil de entender mesmo kkk

Sobre o motivo de ser uma conta do Naver, um desenvolvedor do projeto chamado Claudius deixou um comentário dizendo que trabalha na Naver Labs Europe e que foi publicado porque o Naver aprovou como projeto open source.
Não parece ter muita relação com o Naver em si, acho que são só pessoas que realmente amam Lisp...

 
GN⁺ 6 시간 전
Opiniões no Lobste.rs
  • Fica parecendo que a proposta é “desinchar” o JavaScript adicionando um bloco opaco de WASM de 3,3 MB e mandando escrever o app em Lisp
    Só com JavaScript puro e zero dependências extras já dá para fazer bastante coisa antes de chegar sequer a um décimo desse tamanho

    • Espero que não descartem isso vendo só uma parte pequena da documentação
      Não concordo com esse caso de uso, mas é um projeto de paixão em Lisp interessante, com uma estranheza rara hoje em dia, e gosto do fato de toda a documentação ter frases únicas que claramente parecem escritas por uma pessoa
  • Sempre estão abertos a sugestões do que vale adicionar à biblioteca padrão
    Entre as adições recentes estão união/interseção de conjuntos, sum, base64 e outras
    Dito isso, quase nunca ouvi pedidos por funções de cálculo, e no caso de strings os pedidos recorrentes costumam ser .reverse ou .titleCase
    .reverse não tem tantos usos convincentes fora de problemas de brinquedo, e .titleCase é possível, mas precisa de dados de internacionalização, então a discussão ainda está em andamento
    Além disso, nenhuma das duas existe nesta biblioteca

    • Muita gente aparentemente não conhece ninguém do tc39 diretamente, nem percebe que eles estão por perto
      Acabam sentindo que não vale a pena propor algo porque levaria 3 anos para entrar de fato, e que uma pasta utils/ não é ideal, mas pelo menos dá para criar agora
    • A biblioteca padrão se moveu mais do que eu vinha acompanhando, então preciso ajustar um pouco o texto
      Meu argumento é menos sobre faltar funções no JavaScript e mais sobre o modelo de distribuição
      Mesmo com uma biblioteca padrão cheia, o app médio ainda continua carregando megabytes de dependências transitivas do npm
      LispE-as-WASM tem 3,3 MB, cerca de 450 funções documentadas, núcleo em C++, código-fonte público no GitHub, e é um experimento para ver como poderia ser um runtime auditável
      Na prática, já montei um harness de agentes em cima disso, e estou executando regras em LispE sob demanda dentro do navegador
      O event loop do JavaScript continua sendo excelente
  • Quando alguém diz que a sintaxe está inflada eu já fico em alerta
    Uma sintaxe mínima pode ser muito mais difícil de ler do que uma que usa caracteres diferentes para distinções visuais
    O que o LispE oferece como alternativa é isto:

    (defun gol8(⍵) ((λ(⍺) (| (& (== ⍺ 4) r) (== ⍺ 3))) (⌿ '+ (⌿  '+ (° (λ (x ⍺) (⊖ ⍺ x)) '(1 0 -1) (↑ (λ (x) (⌽ ⍵ x)) '(1 0 -1)))))))  
    

    ... !?
    https://github.com/naver/lispe/wiki/5.3-A-la-APL

  • O ponto de entrada deste projeto é meio estranho, e a página https://github.com/naver/lispe/wiki/1.-Introduction parece melhor
    É um projeto de Lisp nativo que também mira WASM, e tem elementos interessantes que devem agradar quem curte linguagens de programação

  • Minha primeira impressão foi que eram exemplos de JavaScript bem forçados
    Grande parte do ódio ao JavaScript parece vir das incompatibilidades dos navegadores antigos, APIs DOM dolorosas e armadilhas de sintaxe, e isso na prática quase não afeta meu dia a dia hoje
    O JavaScript moderno, especialmente com TypeScript e regras de lint razoáveis, é bom o suficiente como linguagem
    Ainda existem problemas como CJS vs ESM, risco na cadeia de suprimentos e volatilidade do ecossistema, mas a maior parte disso está fora da linguagem em si

  • Aquela mesma experiência de ter que ficar equilibrando parênteses, tão irritante que levou as pessoas a criarem extensões de editor, é que seria excelente?
    Se você quer esse estilo de programação — isto é, baixa densidade sintática e abordagem funcional — faz mais sentido inverter a direção e ir para uma linguagem concatenativa

  • Fico me perguntando como o resultado compilado de um interpretador Lisp consegue chegar a 3,3 MB
    Isso é o tal “desinchar”?

    • Provavelmente porque inclui uma biblioteca padrão grande
      Ainda assim, concordo que distribuir junto uma biblioteca padrão grande com código que não será usado está longe de ser “desinchar”
  • Choque! Horror!
    Que espanto, ter que fechar os parênteses na ordem correta

    • Se você quer uma linguagem em que não precisa fechá-los na ordem certa, existe o J
      Até gente que gosta de Lisp e detesta a verbosidade de linguagens como JavaScript costuma recuar diante de linguagens da família APL e passar a defender que clareza e legibilidade são muito mais importantes do que ser o mais curto possível
      O autor do LispE parece ter certa afeição pelos operadores básicos de APL, mas ainda assim é difícil entender por que, ao conhecer uma linguagem com notação tão concisa, ele preferiria uma versão do Life de Conway em s-expressões profundamente aninhadas, mais longa e mais espaçada do que as versões em APL, J, K ou até Q