Skip to main content

Aleph - 0.46.0

๐Ÿš€ Highlightsโ€‹

  • Numeric-heavy Aleph code is substantially faster. In benchmarks, range loops run about 59โ€“61% faster, sliced ranges run 83% faster, and common integer loop forms run 52โ€“84% faster, while eliminating almost all loop-temporary allocations.
  • Improvements to LSP type analysis.

โœจ New Featuresโ€‹

  • Added dmrg0s, a zero-site DMRG solver, to the tensor-network bindings for both real and complex scalars.
    • Optimizes the orthogonality center while it is on the bond between sites.
    • Supports chains with three or fewer sites, unlike the two-site dmrg.
    • Supports global enrichment heuristics ("none", "power", "lanczos") and local enrichment heuristics ("move_only", "memory").
      • Without an enrichment heuristic, the bond dimension of the input MPS cannot grow, only shrink.
    • In addition to all the options of the base dmrg function, dmrg0s also accepts global_enrichment, lanczos_iterations, local_enrichment, memory_depth, and memory_once_per_sweep to control the enrichment strategies.
    • Zero-site DMRG is still experimental and in need of better heuristics to achieve tangible advantages over the two-site update.
      • While significantly faster, it fails to converge to the same high precision as the two-site update.

๐Ÿ›  Improvementsโ€‹

  • Reduced overhead in numeric loops, range iteration, temporary values, and repeated function calls.
  • Expanded LSP type analysis:
    • Joins symbol and return types across control-flow paths, warns about possibly unassigned reads, and narrows recognized is_type branches without executing user code.
    • Composes type narrowing through negated and short-circuit predicates, and recognizes is_var_undef as a safe definite-assignment probe.
    • Infers source-declared and host-registered attributes, nominal dynamic-object constructors, collection literals, numeric ranges, and ranged-for bindings without executing constructors, getters, or iterator functions.
  • set_random now accepts a random number generator, allowing for controlled seeding.

๐Ÿ› Fixesโ€‹

  • JSON \uXXXX escapes now decode to UTF-8, including supplementary characters represented by surrogate pairs. Malformed, truncated, and unpaired surrogate escapes now produce a parse error.
  • Exceptions that do not match a typed catch now continue propagating after finally runs, instead of being silently replaced with void.
  • Excessive script recursion now stops with a controlled recursion-depth error instead of exhausting the native call stack.
  • %= with a zero divisor now reports an arithmetic error consistently with division and remainder operations.
  • Keys returned from temporary maps, such as keys(["a": 1]), now remain valid after the source map is destroyed.
  • Switch comparisons and mutating overload resolution now preserve converted values correctly and prefer an exact receiver over a converted temporary.
  • Shutting down an Aleph interpreter now waits for its outstanding async work, preventing queued or running tasks from accessing a destroyed interpreter.

โš ๏ธ Breaking Changesโ€‹

  • Consecutive declarations inside a class must now be separated by a newline or semicolon. Previously, malformed same-line declarations such as var x var y could be accepted.
  • Numeric range literals now always use Aleph's built-in range behavior. Redefining generate_range no longer changes [start..stop], and directly sliced range loops use Aleph's built-in slicing behavior.
  • Assignments between built-in numeric values now always use Aleph's standard assignment behavior instead of replacement operator functions. Operator overloads for user-defined types are unchanged.

๐Ÿงช Migration Notesโ€‹

  • Separate declarations in class bodies:

    # Invalid
    class Point { var x var y }

    # Valid
    class Point {
    var x
    var y
    }
  • Call a custom range-building function explicitly instead of expecting it to replace range-literal behavior:

    # Before: redefining generate_range could affect this literal.
    var built_in_values = [start..stop]

    # Now: use an explicit call when custom behavior is wanted.
    var custom_values = generate_range(start, stop)
  • Store a range before slicing it when the registered [] operator should be used:

    # Uses Aleph's built-in fused range slicing.
    for (value: [start..stop][::2]) {}

    # Uses the registered [] operator for values.
    var values = [start..stop]
    for (value: values[::2]) {}
  • Built-in numeric assignment always has its standard meaning. Put custom assignment behavior on a user-defined type:

    var total = 1
    total += 2 # Always produces 3.

    class Total {
    var value

    def Total(value) {
    this.value = value
    }

    def `+=`(amount) {
    this.value += amount
    this
    }
    }

    var wrapped_total = Total(1)
    wrapped_total += 2 # Calls Total.`+=`.