Skip to content
HARA
>_

Talo Foundation .hal Port

This ledger tracks semantic decisions while porting foundation-base/src/hara to the talo.* transpiler library. An entry marked pending must not be implemented with changed behavior until it has been reviewed.

Slice status

Slice Status Notes
Project and namespace loader complete Self-contained examples live under lib/bench/<NUM>-<GROUP>
Common grammar foundation complete Grammar specification, macros, xtalk profiles/system, and aggregate grammar have translated facts
talo.typed pending Does not include hara.model
Common preprocess and emit in progress preprocess-base is complete; emit-rewrite follows the typed slice
talo.common.book* in progress book-entry and book-meta are dependency-complete record slices
Remaining talo.lang pending Split by library, rewrite, compiler, and runtime layers

Source convention

Talo is a self-contained Hara project under lib/. Production namespaces live under lib/src/talo; translated tests live under lib/test/talo. Namespace roots are mapped predictably:

Foundation Talo
hara.common.* talo.common.*
hara.typed.* talo.typed.*
hara.lang.book* talo.common.book*
transpiler-focused hara.lang.* talo.lang.*

Benchmarks consume these packaged namespaces and do not contain substitute implementations.

Pending semantic decisions

Area Original behavior Missing or different facility Proposed direction Decision
Typed records Five Clojure records represent typed declarations Native Hara record declaration was missing Native defstruct, ->Record, and map->Record constructors implemented
Namespace analysis Uses ns-publics, ns-aliases, ns-name, and requiring-resolve Hara exposed only part of this introspection Narrow deterministic namespace primitives; publics exclude referred Vars implemented
Source analysis Uses tools.reader with file, line, and column metadata Hara parser did not expose a multi-form analysis API Capability-checked read-forms preserving file and source spans implemented
Parallel work Some later language/runtime paths use futures and parallel task processing Hara promises differ from Clojure futures No sequential fallback until separately approved pending
Host integrations Later language paths use filesystem, process, network, and JVM APIs Hara uses explicit capabilities and runtime flavors Keep operations unavailable until a capability-safe mapping is reviewed pending

Intentional runtime adaptations

The following adaptations preserve observable Foundation behavior while using the portable Hara runtime:

Foundation construct Talo implementation Reason
Nested argument destructuring in helper definitions Explicit first, second, drop, and indexed access Hara does not yet support every nested Clojure binding pattern
list and syntax-quoted generated forms Persistent lists assembled with cons Hara does not expose Clojure's list, and syntax quote is not a runtime function
with-meta IObjType/with-meta through protocol-call Metadata mutation is intentionally protocol-based
Repeated traversal of lazy collection operations Materialize once with vec Hara lazy iterators are one-shot
Dynamic values consumed by lazy transforms Materialize inside the dynamic binding Deferred iteration must not escape the binding extent
Arbitrary eval in grammar mixins Qualified symbol resolution plus a narrow form evaluator Portable HAL code must not depend on host evaluation
Clojure seq? as a list/form predicate Dispatch after the supported symbol and map mixin cases Hara's seq? specifically identifies lazy HaraSeq values
Runtime macroexpand-1 for -> and ->> data Explicit thread-first/thread-last form transformation Hara expands these forms during analysis; quoted transpiler data is transformed portably in HAL
Macros imported by an ns declaration :refer-macros in the generated :require specification Hara runtime require supported macro references, but source namespace declarations did not
Nested macro argument destructuring Bind the vector as one macro argument and emit a runtime first Hara macro parameters are symbols, while the public call shape remains unchanged
Clojure integer? in index-offset folding Hara number? Target grammar offsets are numeric indices and Hara currently exposes the broader numeric predicate
std.lib.walk/prewalk plus volatile accumulators Explicit pending-node loop with persistent maps and sets Keeps xtalk scanning portable and prevents mutable host values from escaping
Clojure set union, subset, and membership helpers Small persistent reductions local to the xtalk system Hara deliberately does not expose the whole clojure.set surface
Symbol-valued code.test :id metadata Fact names and :refer metadata only Unquoted metadata symbols are resolved by Hara; the test registry already has stable names
Foundation Grammer record Persistent map tagged with :polis/type :polis/grammar Hara records are structs rather than map values; downstream grammar consumers require keyword lookup and map semantics
Metadata-based operator category ordering Explicit persistent +op-categories+ and +op-order+ vectors Hara Vars do not provide the Foundation compiler's source-line ordering contract
Recursive lookup over lazy path tails Materialize the remaining path in get-in and assoc-in Hara lazy iterators are one-shot; probing them with empty? must not consume the next lookup key
Keyword lookup against sets Hara keywords now query persistent and Java sets Foundation argument parsing uses keyword lookup on grammar allow-lists and expects missing members to return nil
Metadata-bearing symbol equality Symbol equality and hashing ignore metadata Matches Clojure/Foundation value semantics and allows copied metadata assertions to compare unchanged
Macro parameter destructuring Bind the vector parameter and select its first value inside with:macro-opts Hara macro parameters currently support symbols and &, so the public call shape remains unchanged while the implementation avoids nested parameter destructuring
std.lib.walk Lazy Java-backed static library over persistent Hara collections Supplies the Foundation traversal contract without mutable host collections escaping; map/set implementations and metadata are preserved
volatile! used as a local traversal flag Hara atom, reset!, and deref talo.common.preprocess-input needs local mutable state only while checking whether a template expression can be evaluated
Host form eval during preprocessing Core Hara eval evaluates the readable Hara form in the active namespace Preserves persisted template behavior while keeping evaluation inside the Hara runtime rather than invoking Clojure/JVM evaluation
Foundation std.lib.impl/defimpl for BookEntry Native Hara defstruct with the same fields and constructors Preserves lookup, construction, and type checks without introducing an implementation-only compatibility namespace; custom Foundation record printing remains unavailable
std.lib.template/$ in copied record-construction facts Explicit persistent target forms assembled with list Hara does not ship the Foundation template namespace; the test functions retain the same generated forms without adding a compatibility-only public namespace

Translated code.test files are copied from Foundation by default. Namespace ownership and unsupported dependency syntax may be translated, but fact grouping, inputs, expected values, and metadata remain unchanged. A failing copied fact is treated as a source or runtime gap before any test adaptation is considered.

Project convention

The nearest project.hal is discovered by walking upward from the working directory. Runnable project fixtures use lib/bench/<NUM>-<GROUP>/{project.hal,src,test}. A descriptor has this form:

(defproject project.name
  {:source-paths ["src"]
   :test-paths ["test"]})

Namespace paths replace dots with directories and hyphens with underscores. Project source wins over packaged classpath source. Test paths are considered only for namespaces ending in -test.