-----

### Projektplan: Atome und das "Builder/Snapshot"-Pattern

  * **Datum:** 09. Oktober 2025
  * **Uhrzeit:** 16:07

#### Motivation

Die bisherige Diskussion hat zwei grundlegende Anforderungen an die Zustandsverwaltung herausgearbeitet:

1.  **Allgemeine Sicherheit:** Für generische Datenstrukturen (Maps, Vektoren) bieten persistente Datenstrukturen durch ihre Immutabilität und lock-freie Lesbarkeit die höchste Sicherheit und Flexibilität bei konkurrierendem Zugriff.
2.  **Spezialisierte Performance:** Für bestimmte Anwendungsfälle (z.B. große, append-only Time-Series) ist die Performance einer In-Place-Mutation überlegen, aber das Teilen des Zustands zwischen Threads erfordert eine sichere Synchronisation.

Die Motivation ist daher, ein **standardisiertes, generisches Muster** zu definieren, das die rohe Performance einer mutierbaren "Arbeitskopie" mit der Sicherheit von unveränderlichen, lesbaren "Snapshots" für die konkurrierende Analyse kombiniert.

#### Ziel

1.  Etablierung des **"Builder/Snapshot"-Patterns** als idiomatisches Kernkonzept der Sprache für den Umgang mit hoch-performantem, geteiltem, mutablem Zustand.
2.  Definition von **generischen Basis-Interfaces** (`IBuilder`, `IImmutable`), die dieses Pattern im Typensystem verankern.
3.  Nahtlose Integration dieses Patterns mit den bestehenden `atom`- (für geteilten Zustand) und `var`- (für lokalen Zustand) Konstrukten.

#### Ergebnis

Das Ergebnis ist ein klares, zweigleisiges Modell für die Zustandsverwaltung, das auf dem generischen "Builder/Snapshot"-Pattern aufbaut.

**1. Das generische Pattern: `IBuilder` / `IImmutable`**

Wir definieren zwei konzeptionelle Basis-Interfaces, die den Vertrag des Patterns abbilden:

  * `IImmutable`: Ein **Marker-Interface**, das einen sicheren, unveränderlichen "Produkt"- oder Snapshot-Typ kennzeichnet.
  * `IBuilder`: Ein Interface, das einen "Builder" kennzeichnet. Es definiert die Fähigkeit, ein `IImmutable`-Produkt zu erzeugen.

**2. Die Spezialisierung (Beispiel: `Series`-Interfaces)**

Konkrete Datenstrukturen wie die `Series` spezialisieren diese generischen Rollen.

```delphi
// --- Generische Basis-Interfaces ---

// Kennzeichnet ein sicheres, unveränderliches Lese-Objekt (Snapshot).
IImmutable = interface(IInterface)
end;

// Kennzeichnet ein mutierbares Builder-Objekt, das Snapshots von sich erzeugen kann.
IBuilder = interface(IInterface)
    function CreateSnapshot: IImmutable;
end;

// --- Spezialisierte Interfaces für die 'Series' ---

// ISeries ist die spezialisierte, lesbare Form von IImmutable.
ISeries = interface(IImmutable)
    function GetCount: Int64;
    function GetItems(Idx: Integer): TScalar;
    property Count: Int64 read GetCount;
    property Items[Idx: Integer]: TScalar read GetItems; default;
end;

// IWriteableSeries ist der spezialisierte Builder.
// Wichtig: Er implementiert den IBuilder-Vertrag, indem er eine CreateSnapshot-Methode
// anbietet, die den spezialisierten Snapshot-Typ ISeries zurückgibt.
IWriteableSeries = interface(IBuilder)
    function GetCount: Int64;
    property Count: Int64 read GetCount;
    procedure Add(const Item: TScalar.TValue; Lookback: Int64 = -1);
    function CreateSnapshot: ISeries; // Covarianter Return-Type zum Basis-Interface
end;
```

**3. Die Anwendungsbeispiele in der Sprache**

Das Pattern wird auf zwei Arten verwendet, je nach Kontext (`atom` oder `var`). Die RTL-Funktionen arbeiten mit den generischen `IBuilder`- und `IImmutable`-Konzepten.

**Beispiel 1: Geteilter Zustand (via `atom`)**

Der `atom` schützt den `IBuilder` vor konkurrierenden Schreibzugriffen.

```lisp
(*
 * Szenario: Ein Ticker-Modul (Thread A) empfängt Live-Daten,
 * während eine UI (Thread B) die Daten zur Analyse anfordert.
 *)

; Ein globaler 'atom' wird erstellt. Er hält die einzige Instanz des Builders.
(atom live-ticker (create-series-builder))

; -- Thread A (Produzent) --
; Modifiziert den Builder sicher über eine generische, synchronisierte RTL-Funktion,
; die auf jedem IBuilder in einem Atom funktioniert.
(builder-update! live-ticker series-add new-tick-value)

; -- Thread B (Konsument) --
; Fordert einen sicheren, unveränderlichen Snapshot an.
; Die generische 'snapshot'-Funktion ruft intern 'CreateSnapshot' auf.
(let chart-data (snapshot live-ticker))

; 'chart-data' ist nun eine sichere ISeries (IImmutable), die ohne Locks gelesen werden kann.
(calculate-indicators chart-data)
```

**Beispiel 2: Lokaler Zustand (via `var`)**

Dies ist der "Maschinenraum"-Modus für maximale Single-Thread-Performance.

```lisp
(*
 * Szenario: Innerhalb einer Funktion wird eine komplexe Datenreihe
 * temporär aufgebaut, um ein einmaliges Ergebnis zu berechnen.
 *)
(do
  ; Erzeuge einen lokalen, unsynchronisierten Builder.
  (var local-builder (create-series-builder))

  ; Befülle den Builder direkt und ohne Lock-Overhead über typspezifische,
  ; unsynchronisierte RTL-Funktionen.
  (repeat 1000000
    (series-add! local-builder (get-next-value)))

  ; Erzeuge einen finalen Snapshot für die Weiterverarbeitung.
  (let final-data (series-create-snapshot local-builder))

  ; Gib das Ergebnis der Analyse zurück.
  (run-analysis-on final-data))
```

#### Todo

  * [ ] Generische `IBuilder`- und `IImmutable`-Interfaces in Delphi definieren.
  * [ ] Finale `ISeries`- und `IWriteableSeries`-Interfaces (als Spezialisierungen) implementieren.
  * [ ] Eine konkrete `TSeries`-Klasse implementieren, die `IWriteableSeries` implementiert.
  * [ ] Die generischen, synchronisierten RTL-Funktionen `(builder-update! ...)` und `(snapshot ...)` für `atom`s erstellen, die auf `IBuilder` operieren.
  * [ ] Die spezifischen, unsynchronisierten RTL-Funktionen `(series-add! ...)` und `(series-create-snapshot ...)` für die `TSeries`-Implementierung erstellen.
  * [ ] Unit-Tests für beide Anwendungsfälle schreiben.