Skip to content

Releases: BrunoL28/mini-clojure-ts

v4.1.0: Mapas Imutáveis (HAMT), Macros & Destructuring

12 Jan 23:00

Choose a tag to compare

Release Notes

Esta versão marca um ponto de inflexão na arquitetura do Mini-Clojure-TS. Substituímos a implementação ingênua de Mapas por Hash Array Mapped Tries (HAMT), garantindo imutabilidade real e performance logarítmica (). Além disso, a linguagem ganhou expressividade com suporte completo a Destructuring de mapas e ferramentas de introspecção de Macros.

🚀 Principais Novidades

🧠 Core & Performance (HAMT)

  • Mapas Persistentes: Implementação completa de HAMT. Mapas agora são imutáveis por padrão. Operações como assoc, dissoc e get são estruturalmente compartilhadas e eficientes.
  • Hashing Customizado: Novo sistema de hashing recursivo (src/core/Hash.ts) que suporta valores, coleções e igualdade independente de ordem para mapas.
  • Keyword como Função: Agora é possível usar keywords para buscar valores em mapas: (:chave {:chave 10}) retorna 10.

✨ Funcionalidades da Linguagem

  • Map Destructuring: Suporte completo em let e argumentos de função (fn/defn).

  • Suporta :keys [a b], :as m, :or {a 1} e renomeação {v :chave}.

  • Suporte a nil punning (destructuring em nil não quebra).

  • Introspecção de Macros: Adicionados macroexpand-1 e macroexpand para auxiliar no desenvolvimento e debug de macros complexas.

🛡️ Robustez & IO

  • IO Roundtrip: Garantia de que (= x (read-string (pr-str x))) funciona para todas as estruturas básicas.
  • Parser de Strings Seguro: O Tokenizer agora valida estritamente escapes (\n, \t, \", \\) e strings não terminadas, reportando erros com linha e coluna precisas.
  • Erros Ricos: Melhoria nas mensagens de erro de parse e runtime, apontando a localização exata no código fonte.

📚 Stdlib

  • Novas funções: read-string, pr-str, second.
  • Atualização de assoc, dissoc, get e hash-map para utilizar a nova API imutável.

⚠️ Breaking Changes

  • API Interna de Mapas: A classe ClojureMap não estende mais o Map nativo do JS. Plugins ou códigos nativos que dependiam de .set() ou .get() direto no objeto ClojureMap devem migrar para .assoc() e .get() da nova interface.
  • Estabilidade de Strings: Strings com escapes inválidos (ex: "\q") agora lançam erro de sintaxe imediato, em vez de serem processadas de forma imprevisível.

Exemplo de Uso das Novas Features

;; Destructuring com Defaults e :as
(defn config [{:keys [port host] :or {port 8080} :as full-config}]
  (println "Iniciando em" host ":" port)
  (println "Config completa:" full-config))

(config {:host "localhost"})
;; -> Iniciando em localhost : 8080
;; -> Config completa: {:host "localhost"}

;; Mapas Imutáveis & Keywords
(def m1 {:a 1})
(def m2 (assoc m1 :b 2))
(println (:a m2)) ;; -> 1
(println m1)      ;; -> {:a 1} (m1 não mudou!)

;; Macroexpand
(macroexpand '(unless (= 1 2) (print "ok")))
;; -> (if (not (= 1 2)) (print "ok") nil)

v3.0.0: Product Foundation & Developer Experience

30 Dec 03:30

Choose a tag to compare

Essa versão representa um marco significativo na maturidade do Mini-Clojure-TS. O foco principal foi transformar a arquitetura do projeto, separando claramente o motor de execução da interface de linha de comando, além de melhorar drasticamente a experiência de uso (DX) no REPL e a robustez da biblioteca padrão.

🌟 Destaques

1. Separação Engine vs. CLI (Embed API)

O núcleo do interpretador foi desacoplado da CLI. Agora, o Mini-Clojure-TS expõe uma API Pública Estável em src/index.ts, permitindo que ele seja importado e embutido em outras aplicações TypeScript/JavaScript sem efeitos colaterais.

import { runSource, createGlobalEnv } from "mini-clojure-ts";

const env = createGlobalEnv();
const result = runSource("(+ 10 20)", { env });
console.log(result); // 30

2. REPL 2.0 (Supercharged)

O ambiente interativo foi reescrito para se comportar como um REPL profissional:

  • Edição Multilinha: O REPL detecta automaticamente parênteses/chaves/colchetes desbalanceados e aguarda a conclusão da expressão.
  • Histórico Persistente: Seus comandos são salvos em .mini-clj-history na raiz do projeto (navegue com e ).
  • Novos Comandos: :load <arquivo>, :help, :quit/:exit.
  • Resiliência: Erros de sintaxe ou execução não derrubam mais a sessão.

3. Output "Pretty Print"

Implementação de um Printer dedicado (prStr). As saídas do terminal agora respeitam a sintaxe do Clojure em vez de exibir objetos internos do JavaScript/TypeScript.

  • Antes: ClojureMap(2) { ... }
  • Agora: {:id 1 :nome "Mini-Clojure"}

4. Robustez da Stdlib (Type Hardening)

Endurecimento das funções core. Operações matemáticas e lógicas agora validam tipos em tempo de execução, prevenindo comportamentos indefinidos herdados do JS (ex: impedir (+ 10 "a")).


🛠 Changelog Completo

🚀 Features & Melhorias

  • [API] Exposição de parse, runSource, runFile, compileSource e compileFile via entrypoint.
  • [CLI] Implementação de histórico persistente local.
  • [CLI] Suporte inteligente a input multilinha (ignora strings e comentários no balanço).
  • [Core] Implementação de Printer.ts para formatação canônica de dados.
  • [Stdlib] Validação de tipos numéricos em +, -, *, /, %, >, <.
  • [Stdlib] Melhoria na função assoc e get para garantir equivalência de chaves (Keyword e Symbol) por valor, resolvendo duplicatas em Mapas.

🐛 Bug Fixes

  • Correção no destructuring de mapas: suporte adequado para as chaves especiais :keys e :as.
  • Correção no parser de argumentos variádicos (&) quando combinados com destructuring de mapas.
  • Correção de vazamento de abstração JS em operações matemáticas.

📦 Infraestrutura

  • Configuração de CI/CD mínimo (Build & Test).
  • Padronização de erros com localização (Linha/Coluna) no Tokenizer/Parser.

Como Atualizar

git pull origin master
pnpm install
pnpm start

Mini-Clojure v2.0: The "Native Performance" Edition

26 Dec 03:42

Choose a tag to compare

🚀 Mini-Clojure v2.0.0

Nessa versão, implementamos a transição de um Interpretador para um Compilador (Transpilador).

Agora, o código em clojure não fica preso ao nosso ambiente de execução. Ele é traduzido para JavaScript Nativo, permitindo que os scripts rodem em qualquer lugar onde o JS rode (Browsers, Servidores, AWS Lambda, etc.) com a performance máxima do motor JS.

✨ Destaques da Versão

1. Transpilador (-t / --transpile)

Um novo módulo Transpiler.ts que percorre a AST e emite código JavaScript sintaticamente válido.

  • Compila variáveis (def -> var/global).
  • Compila funções (fn -> Arrow Functions).
  • Compila condicionais (if -> Ternários).
  • Compila operações matemáticas e lógicas.

2. Zero Runtime Dependency

O ficheiro .js gerado é "standalone". Ele não precisa de importar o mini-clojure-ts para funcionar.

  • Exemplo: pnpm start -transpile script.clj gera script.js.
  • Execute node script.js e veja a mágica acontecer.

3. Interoperabilidade Nativa

A sintaxe de interop agora traduz diretamente para chamadas de propriedade do JS.

  • Clojure: (. log js/console "Olá")
  • JS Gerado: console.log("Olá")

🏆 Resumo da Jornada (v1.0 -> v2.0)

Este projeto implementou do zero:

  1. Lexer & Parser: Regex avançado para tokenização de Lisp.
  2. Evaluator: Com suporte a Closures e Escopo Léxico.
  3. TCO: Otimização de cauda via Trampoline (Recursão Infinita).
  4. Data Structures: Vetores, Mapas, Listas e Átomos.
  5. Metaprogramação: Sistema completo de Macros.
  6. Compilador: Geração de código de máquina (JS).

Como usar o Compilador:

# 1. Escreve o teu código
echo '(print (+ 10 20))' > teste.clj

# 2. Compila
pnpm start -transpile teste.clj

# 3. Executa nativamente
node teste.js
# Output: 30

Mini-Clojure v1.3: The "Elegant Code" Edition

26 Dec 03:25
5b1b3bd

Choose a tag to compare

💎 Mini-Clojure v1.3.0

A versão 1.3.0 traz uma das funcionalidades mais amadas pelos programadores de Lisp e JavaScript modernos: Destructuring (Desestruturação).

Até agora, extrair dados de vetores ou listas exigia código verboso usando nth, first ou rest. Com esta atualização, introduzimos "Açúcar Sintático" ao núcleo do Avaliador, permitindo extrair valores diretamente na definição de variáveis e parâmetros de funções.

✨ Novidades

1. Vector Destructuring

Agora é possível "desempacotar" vetores diretamente em bindings.

  • Suportado em let: (let [[x y] ponto] ...)
  • Suportado em fn: (fn [[a b]] (+ a b))
  • Bindings Aninhados: Funciona recursivamente para estruturas complexas [x [y z]].

2. Argumentos Variádicos (Rest Operator &)

Inspirado no Clojure original, o símbolo & agora tem poderes especiais em definições de argumentos.

  • Captura "o resto" de uma lista ou vetor numa única variável.
  • Permite criar funções que aceitam número indefinido de argumentos (variadic functions).

3. Melhoria na Engenharia do Avaliador

Refatoração do mecanismo de binding no Evaluator.ts para suportar padrões de atribuição complexos, mantendo a compatibilidade com o sistema de escopo léxico existente.


💻 Antes vs. Depois

Extraindo Coordenadas

Antes (v1.2):

(let (ponto [10 20])
  (print (nth ponto 0))  ;; x
  (print (nth ponto 1))) ;; y

Agora (v1.3):

(let [[x y] [10 20]]
  (print x)
  (print y))

Funções com Cauda (Head/Tail)

Agora (v1.3):

(let [[head & tail] [1 2 3 4]]
  (print "Cabeça:" head) ;; 1
  (print "Cauda:" tail)) ;; [2 3 4]

Funções Variádicas

(def log-prefixado (fn [prefixo & mensagens]
  (print "Log:" prefixo)
  (print "Detalhes:" mensagens)))

(log-prefixado "ERRO" "Falha na conexão" "Timeout" 500)

🔮 Roadmap (Rumo à v2.0)

Com a sintaxe e a usabilidade maduras, o projeto vai para a sua maior evolução técnica:

  • v2.0.0 - O Transpilador: Deixar de apenas interpretar o código e passar a compilar clojure diretamente para JavaScript, permitindo que o código rode no Browser ou em qualquer runtime JS sem dependências.

Instalação e Atualização:

git pull origin master
pnpm install
pnpm start

Mini-Clojure v1.2: The "Safety Net" Edition

26 Dec 02:52

Choose a tag to compare

🛡️ Mini-Clojure v1.2.0

A versão 1.2.0 introduz Tratamento de Exceções ao Mini-Clojure-TS.
Até agora, qualquer erro (divisão por zero, variável não definida, erro lógico) encerrava abruptamente o processo do Node.js. Com esta atualização, a linguagem ganha a capacidade de recuperar de falhas, tornando-a adequada para scripts mais complexos e resilientes.

🚀 Novidades

1. Blocos try / catch

Implementação nativa de tratamento de erros inspirada no Clojure e Java.

  • Isolamento: O código dentro de try é executado num contexto seguro.
  • Captura: Se ocorrer um erro (seja do motor JS ou do utilizador), o controlo passa para a cláusula catch.
  • Binding de Erro: A mensagem de erro é automaticamente vinculada a uma variável no escopo do catch.

2. Lançamento de Erros (throw)

Nova função na biblioteca padrão para controlo de fluxo baseado em exceções.

  • Permite que o utilizador interrompa a execução e sinalize um estado inválido manualmente.

3. Integração com Erros do Host

  • O try captura não apenas erros lançados pelo (throw ...), mas também erros nativos do JavaScript/TypeScript (ex: falhas de interoperabilidade, erros de tipos internos), expondo-os de forma tratável na linguagem.

💻 Exemplos de Código

Tratamento Básico

(try
  (print "A tentar algo perigoso...")
  (throw "Falha crítica no sistema!")
  (print "Isto nunca será impresso.")
  
  (catch e
    (print (str "Erro recuperado: " e))))
;; Saída:
;; A tentar algo perigoso...
;; Erro recuperado: Falha crítica no sistema!

Protegendo Operações Matemáticas/Lógicas

(def dividir-seguro (fn (a b)
  (try
    (/ a b)
    (catch err
      (print "Ops, divisão falhou.")
      0)))) ;; Retorna 0 em caso de erro

(print (dividir-seguro 10 0)) ;; => Infinity (JS behavior) ou captura se lançarmos erro

🔮 Roadmap (Próximas Versões)

O interpretador agora é estável e seguro. O próximo passo foca-se na elegância e produtividade do código:

  • v1.3.0 - Destructuring: Sintaxe para extrair valores de listas/vetores diretamente na definição de argumentos (let [[x y] coords] ...).
  • v2.0.0 - Transpilação: Compilar Mini-Clojure diretamente para JavaScript para performance nativa.

Instalação e Atualização:

git pull origin master
pnpm install
pnpm start

Mini-Clojure v1.1: The "State & Safety" Edition

25 Dec 23:38

Choose a tag to compare

⚛️ Mini-Clojure v1.1.0

A versão 1.1.0 eleva o Mini-Clojure-TS de uma linguagem funcional para uma linguagem prática capaz de gerir Estado Mutável.

Esta atualização foca na robustez e na capacidade de construir aplicações que interagem com o mundo real (loops de eventos, contadores, caches) sem quebrar.

🚀 Novidades

1. ⚛️ Gestão de Estado com Átomos

Introduzimos o tipo Atom, a forma "Clojure-way" de gerir estado mutável num mundo imutável.

  • atom: Cria uma referência mutável segura.
  • deref ou @: Leitura de valores (ex: @contador).
  • swap!: Atualização atómica baseada numa função (ex: (swap! contador inc)).
  • reset!: Força um novo valor.

2. 🛠️ Melhorias na Stdlib

  • conj: A função conj (conjoin) foi adicionada. Ela insere elementos da forma mais eficiente para a estrutura de dados:
    • Em Listas: Adiciona no início.
    • Em Vetores: Adiciona no fim.
  • Reader Macro @: Sintaxe curta implementada no Tokenizer/Parser para desreferenciar átomos.

💻 Exemplos de Código

Estado Mutável (Átomos)

(def contador (atom 0))

(print "Valor inicial:" @contador) ;; => 0

(swap! contador + 1)
(print "Depois do swap:" @contador) ;; => 1

(reset! contador 100)
(print "Depois do reset:" @contador) ;; => 100

(print (conj '(1 2) 3)) ;; => (3 1 2)  [Lista: Início]
(print (conj [1 2] 3))  ;; => [1 2 3]  [Vetor: Fim]

🔮 Roadmap (v1.2+)
O próximo passo é melhorar a ergonomia da linguagem:

[ ] Blocos Try Catch para tratamento de erros e exceções.

[ ] Destructuring: Sintaxe para extrair valores de listas/vetores diretamente nos argumentos (let [[x y] ponto] ...).

[ ] Transpilação: Compilar Mini-Clojure diretamente para JavaScript.

Instalação e Atualização:

Bash

git pull origin master
pnpm install
pnpm start

Mini-Clojure v1.0: The "Metaprogramming & TCO" Edition

25 Dec 01:13

Choose a tag to compare

🎉 Mini-Clojure v1.0.0

Essa é a primeira versão estável ("Major Release") do Mini-Clojure TS.
Essa release marca a transição de um analisador sintático para uma Linguagem Funcional, capaz de lidar com recursão infinita, manipulação complexa de dados e metaprogramação.

🚀 Destaques da Versão

1. wd_speed: Performance & Otimização (TCO)

Implementação de Tail Call Optimization via técnica de Trampoline.

  • Adeus Stack Overflow: Recursões de milhões de iterações agora rodam suavemente em cima do engine do Node.js.
  • Otimização transparente para o utilizador final.

2. 🧠 Metaprogramação (Macros)

O poder do Lisp agora está desbloqueado.

  • Suporte a defmacro, quasiquote (backtick) e unquote (tilde).
  • Capacidade de criar novas estruturas sintáticas (como unless, infix, etc.) em tempo de compilação.

3. 🌐 Interoperabilidade com JavaScript

O Mini-Clojure não vive numa ilha.

  • Acesso total ao ambiente globalThis do host.
  • Sintaxe para instanciar classes (new js/Date), acessar métodos estáticos (js/Math) e encadeamento (.).

4. 📦 Estruturas de Dados Ricas

Além das listas encadeadas, agora suportamos:

  • Vetores: [1 2 3] para acesso rápido.
  • Mapas: {:chave "valor"} para dicionários hash.
  • Keywords: :minha-chave como primitivas de acesso rápido.

5. 🛠️ Arquitetura Modular

Refatoração completa do código fonte seguindo princípios SOLID:

  • Separação clara entre Tokenizer, Parser, Evaluator e Environment.
  • Sistema de erros semânticos tipados.
  • REPL interativo com syntax highlighting básico.

💻 Exemplos de Código Suportados

Recursão de Cauda (TCO)

(def somatorio (fn (n acc)
  (if (<= n 0)
      acc
      (somatorio (- n 1) (+ n acc)))))

(print (somatorio 1000000 0)) ;; Não explode a pilha!

Macros (Unless)

(defmacro unless (teste corpo)
  ` (if (not ~teste) ~corpo nil))

(unless (= 1 2) (print "A matemática ainda funciona!"))

JS Interop

(def data (new js/Date))
(print (. :getFullYear data))
(. :log js/console "Olá do Mini-Clojure!")

🔮 Roadmap (Próximas Versões)

O desenvolvimento continua! As próximas funcionalidades planeadas para a v1.1+ incluem:

  • Átomos: Gestão de estado e mutabilidade controlada (atom, swap!).
  • Tratamento de Erros: Blocos try / catch.
  • Destructuring: Extração elegante de dados em let e fn.
  • Compilador: Transpilação direta para JavaScript para performance nativa.

Instalação e Uso:

git clone [https://github.com/teu-usuario/mini-clojure-ts.git](https://github.com/teu-usuario/mini-clojure-ts.git)
pnpm install
pnpm start