Von Delphi / Object Pascal nach Lyx

Wer Object Pascal kennt, kennt drei Viertel von Lyx: Units, Create/Destroy, virtuelle Methoden, inherited (hier super), Records, begin-freie Blöcke mit geschweiften Klammern. Dieser Guide zeigt, was anders ist — und wo die Ähnlichkeit trügt.

Für Oberflächen gilt das doppelt: Vega VCL folgt der VCL in Aufbau und Benennung.

Sprachreferenz · Erste Schritte · Vega-Guides


Schreibweise auf einen Blick

Object Pascal Lyx
beginend {}
x := 1; Zuweisung, x = 1 Vergleich x := 1; Zuweisung, x == 1 Vergleich
const con
var x: Integer; var x: int64;
procedure P; / function F: Integer; fn P(): void / fn F(): int64
nil null
and / or / not && / || / ! (die Wortformen sind reserviert)
div / mod / / %
record struct
inherited Create(…) super.Create(…)
TFoo.Create(…) new TFoo(…)
Free / FreeAndNil dispose
ClassName ClassName() (seit lyxc 1.1.3C)
uses import
interface / implementation entfällt — pub entscheidet über Sichtbarkeit
property X: Integer read FX write SetX Feld plus GetX/SetX — Lyx kennt kein property
string pchar (Zeiger auf Zeichen), Verkettung mit +
array of T array<T> (dynamisch) bzw. [N]T (fest)
try … finally defer

Ein Programm, das beides zeigt

unit Main;

import std.io;
import std.string;

// Delphi: type TPunkt = record ... end;
type TPunkt = struct { X: int64; Y: int64; };

// Delphi: type TTier = class ... end;
pub type TTier = class {
  Name: pchar;
  fn Create(n: pchar): void { self.Name := n; }        // Konstruktor heisst Create
  virtual fn Laut(): pchar { return "..."; }
  fn Destroy(): void { }                                // Destruktor heisst Destroy
}

pub type THund = class extends TTier {
  fn Create(n: pchar): void { super.Create(n); }        // Delphi: inherited
  override fn Laut(): pchar { return "Wau"; }
}

fn main(): int64 {
  // Zuweisung mit :=, Vergleich mit ==   (Delphi: := und =)
  var i: int64 := 3;
  if (i == 3) { PrintLn("drei"); }

  // Strings sind pchar, Verkettung mit +
  var s: pchar := "Hallo" + " " + "Welt";
  PrintLn(s);

  // Records/Structs liegen auf dem Stapel
  var p: TPunkt;
  p.X := 10;
  p.Y := 20;
  PrintLn(IntToStr(p.X + p.Y));

  // Objekte: new statt TTier.Create, dispose statt Free
  var h: THund := new THund("Bello");
  PrintLn(h.Laut());
  var cn: pchar := h.ClassName();       // vor 1.1.4A nicht direkt in Print (#1683)
  PrintLn(cn);
  dispose h;

  // Nil heisst null
  var t: TTier := null;
  if (t == null) { PrintLn("nichts"); }

  return 0;
}

drei
Hallo Welt
30
Wau
THund
nichts

Übersetzt und ausgeführt mit lyxc 1.1.3I.


Was wirklich anders ist

Speicher gehört dir

Es gibt keinen Referenzzähler und keine Interfaces mit automatischer Freigabe. Was new anlegt, gibt dispose frei; was alloc holt, gibt free zurück. Dafür ist die Laufzeit vorhersagbar — dieselbe Rechnung wie in Delphi ohne ARC, nur ohne Ausnahme für Interfaces.

Strings sind Zeiger, keine verwalteten Werte

pchar ist ein Zeiger auf Zeichen. Es gibt keine Referenzzählung, kein Copy-on-Write und keine automatische Umwandlung zwischen Typen. Wer eine Zeichenkette in einem Puffer aufbaut und den Puffer freigibt, hat danach einen ungültigen Zeiger — in Delphi hätte der String das überlebt.

Für veränderliche Texte gibt es TTextBuffer (in Vega) und die Funktionen aus std.string.

Kein `property`, aber Setter mit Wirkung

Was Delphi als property schreibt, ist hier ein Paar aus Feld und Setter — genau das, was der Pascal-Compiler intern ohnehin daraus macht. Der Unterschied ist sichtbar: ctl.Left := 20; verschiebt, ohne neu zu zeichnen, ctl.SetLeft(20) zeichnet neu. Die Felder bleiben lesbar; für Schleifen und Berechnungen ist der direkte Zugriff richtig.

Handler sind freie Funktionen

TNotifyEvent ist fn(sender: TControl): void — kein Methodenzeiger mit of object. Zustand, den ein Handler braucht, steht in Modulvariablen. Das ist der sichtbarste Unterschied beim Umstieg auf Vega.

Keine Überladung

Zwei Funktionen gleichen Namens gibt es nicht — auch nicht mit unterschiedlichen Parametern. Seit lyxc 1.1.3G wird der Versuch gemeldet (#1668); vorher gewann still die erste. Stattdessen: sprechende Namen oder Vorgabewerte (fn F(a: int64, b: int64 = 5)).

Ein Übersetzungsschritt

Kein Projektfile, keine .dcu, kein Linker: lyxc app.lyx -o app erzeugt ein statisches Binary. Units können mit –compile-unit vorübersetzt werden (.lyu), müssen es aber nicht.

Sicherheit ist Sprachmittel

@capabilities beschreibt, was ein Programm darf, und erzeugt daraus einen seccomp-Filter. @flight_crit, @dal(A), @stack_limit und Range-Typen gehören zur Sprache, nicht zu einer Bibliothek — dafür gibt es in Delphi kein Gegenstück.


Fallen, die aus Pascal-Gewohnheit entstehen

  • = statt ==. Ein einzelnes = wird seit lyxc 1.1.2H als Anweisung abgewiesen (#1575).
  • Free statt disposeFree gibt es nicht.
  • nil heißt null.
  • Groß-/Kleinschreibung zählt. Print und print sind verschiedene Namen.
  • Set, to, layout, Map sind reserviert und taugen nicht als Bezeichner — die vollständige Liste steht in der Syntax-Referenz.
  • PrintLn(obj.ClassName()) druckte bis 1.1.3O die Adresse. Seit lyxc 1.1.4A stimmt es (#1683); mit älteren Compilern erst einer pchar-Variablen zuweisen.
  • Modulvariablen nach oben. Reihenfolge ist zwar seit 1.1.3D egal, aber der Zustand einer Unit an einer Stelle ist übersichtlicher.

Wo man weiterliest

Thema Seite
Syntax vollständig Syntax-Referenz
Klassen, Vererbung, Interfaces OOP
Units und Sichtbarkeit Module & Importe
Speicher Memory Management
Oberflächen Vega: erste Anwendung
Wenn etwas nicht läuft Fehlersuche

Letzte Aktualisierung: 2026-08-19 — Beispiel mit lyxc 1.1.3I übersetzt und ausgeführt; Gegenüberstellung gegen die Syntax-Referenz und ebnf.md 2.1 geprüft.