Releases: BrunoL28/mini-clojure-ts
v4.1.0: Mapas Imutáveis (HAMT), Macros & Destructuring
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,dissocegetsã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})retorna10.
✨ Funcionalidades da Linguagem
-
Map Destructuring: Suporte completo em
lete 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
nilnão quebra). -
Introspecção de Macros: Adicionados
macroexpand-1emacroexpandpara 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,getehash-mappara utilizar a nova API imutável.
⚠️ Breaking Changes
- API Interna de Mapas: A classe
ClojureMapnão estende mais oMapnativo do JS. Plugins ou códigos nativos que dependiam de.set()ou.get()direto no objetoClojureMapdevem 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
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); // 302. 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-historyna 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,compileSourceecompileFilevia 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.tspara formatação canônica de dados. - [Stdlib] Validação de tipos numéricos em
+,-,*,/,%,>,<. - [Stdlib] Melhoria na função
assocegetpara garantir equivalência de chaves (KeywordeSymbol) por valor, resolvendo duplicatas em Mapas.
🐛 Bug Fixes
- Correção no
destructuringde mapas: suporte adequado para as chaves especiais:keyse: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
🚀 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.cljgerascript.js. - Execute
node script.jse 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:
- Lexer & Parser: Regex avançado para tokenização de Lisp.
- Evaluator: Com suporte a Closures e Escopo Léxico.
- TCO: Otimização de cauda via Trampoline (Recursão Infinita).
- Data Structures: Vetores, Mapas, Listas e Átomos.
- Metaprogramação: Sistema completo de Macros.
- 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
💎 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
🛡️ 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
trycaptura 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
⚛️ 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.derefou@: 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çãoconj(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
🎉 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) eunquote(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
globalThisdo 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-chavecomo 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,EvaluatoreEnvironment. - 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
letefn. - 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