PONY λ M2 Modula-2
for Pascal programmers

You already know Pascal.Now explore other languages.

Side-by-side, interactive cheatsheets for Pascal programmers
comparing Pascal to other languages. Every example runs live in your browser — no setup, no installation.

▶ Start with Ruby Browse comparisons ↓

Choose your own path by reordering languages

Ruby ⚡ Works Offline ⚡ Offline

Where a Pascal programmer goes to stop describing the machine and start describing the problem. Ruby trades Pascal's static types, ahead-of-time compilation, and manual New/Dispose for a dynamic, garbage-collected world where every value — even an integer or nil — is an object with methods.

  • No var block and no types — a variable springs into being on assignment and can hold any object
  • Garbage collection — no New/Dispose, no try…finally to balance a Free; the runtime reclaims memory
  • Blocks and Enumerable — map, select, each replace the index loops you write by hand in Pascal
  • Open classes and duck typing — reopen Integer at runtime, and any object that responds to a method just works, with no shared interface to declare
  • Strings, arrays, and hashes are first-class objects that resize themselves — no SetLength, no TDictionary to Create and Free
C Pre-Alpha

Pascal and C are contemporaries that made opposite bets — Pascal chose strong types and safe arrays; C chose flexibility and raw performance. C won the systems battle, but Pascal programmers will find the underlying model familiar: compiled, manual memory, no garbage collector, records that map directly to structs.

  • := becomes = and = becomes == — the most common Pascal-to-C mistake; C silently lets if (x = 5) compile as an assignment
  • C strings are char arrays terminated by '\0' — no length stored, no bounds checked; strcmp replaces = for comparisons
  • Arrays are 0-indexed with no bounds checking at all — array[10] on a 10-element array is undefined behaviour, not a range error
  • switch falls through by default — every case needs a break, unlike Pascal's case which exits automatically
  • var parameters become pointer parameters: procedure Swap(var a: integer) becomes void swap(int *a); callers pass &x
  • struct syntax mirrors record, but pointer field access uses -> instead of Pascal's ^.
Rust Pre-Alpha

The "catch it at compile time" philosophy, carried to its logical extreme. Pascal and Rust both reject runtime surprises — but Rust extends the guarantee to memory: ownership and borrowing make use-after-free and data races compile errors, not segfaults discovered at runtime.

  • No Dispose needed — ownership tracking drops heap allocations automatically when they go out of scope, with zero runtime overhead
  • Variant records become type-safe enums with data: match guarantees you handle every variant and the compiler prevents accessing radius on a Rectangle
  • Option<T> replaces nullable pointers — None is a safe nil whose variant the compiler makes you handle before use
  • Result<T, E> replaces exceptions — every error is an explicit return value; the ? operator propagates errors without hidden control flow
  • Closures capture scope variables — what Pascal nested functions cannot do; combined with iterator adapters, they replace most index-variable loops
  • Traits replace Pascal interfaces — implemented explicitly, verified statically, monomorphised at compile time with zero virtual dispatch overhead
TypeScript Alpha ⚡ Works Offline ⚡ Offline

TypeScript is Pascal's software great-grandchild — the same designer, Anders Hejlsberg, brought strong static typing back to the web the same way Pascal brought it to imperative programming in 1970. Union types, structural interfaces, optional parameters, and generics all trace back to Pascal-era ideas, now applied to the JavaScript runtime.

  • Type inference — TypeScript infers types from values like Free Pascal's compiler does, but everywhere, including function return types
  • Union types (string | number | null) replace Pascal's variant records — the type system tracks which variant is active through control flow
  • Template literals (`Hello, ${name}!`) replace Format('%s', [name]) — interpolation built into the string syntax itself
  • Structural typing: any object with the right shape satisfies an interface — no need to declare class Foo implements IBar
  • No memory management — no .Free, no SetLength; JavaScript's garbage collector and dynamic arrays handle it
  • Arrow functions and closures — inline anonymous functions that capture scope variables, unlike Pascal's named function pointers
C# Pre-Alpha

C# is Pascal's direct software descendant — same designer, Anders Hejlsberg, three languages apart. Everything you love about Pascal (strong typing, explicit declarations, structured control flow) is here, plus garbage collection, LINQ, async/await, records, and a type system powerful enough to rival TypeScript's.

  • No more uses SysUtils ceremony — string formatting, generics, and collections are built into the language and stdlib
  • LINQ: Where/Select/Aggregate replace manual loops for filtering, mapping, and reducing collections
  • Garbage collection — no more obj.Free calls; the runtime manages memory automatically
  • record types with structural equality and with expressions — Pascal records finally get == for free
  • Properties with { get; set; } replace Pascal's separate getter/setter procedure pairs
  • async/await and Task<T> — concurrency Pascal programs have always lacked a clean story for
Ada Pre-Alpha

Pascal's spiritual successor for high-stakes software — Ada adopted every good idea from Pascal and hardened it: subtypes with runtime enforcement, mandatory exception handling, and packages that enforce interface boundaries.

  • subtype Name is Base range Low..High; is Pascal subrange types, but with a better name and automatic runtime checking everywhere
  • in, out, and in out replace Pascal's var — the direction is explicit in the procedure signature
  • begin ... exception when E => ... end; gives every block structured exception handling
  • Packages split into a spec (.ads) and body (.adb) — a stricter version of Pascal's unit interface/implementation
  • Derived types (type Metres is new Float;) prevent accidental unit mixing at compile time
  • Record aggregates ((X => 0, Y => 0)) construct records without naming every field separately
Modula-2 Pre-Alpha

Pascal, cleaned up and modularised — Wirth wrote Modula-2 to fix Pascal's worst rough edges: proper separate compilation, explicit import control, and a cleaner separation of functions from procedures.

  • Modules split into a definition file (public) and implementation file (private) — stricter than Pascal units
  • FROM STextIO IMPORT WriteString, WriteLn; replaces Pascal's implicit writeln
  • Functions are procedures with a return type — no separate function keyword
  • REPEAT...UNTIL loops work identically to Pascal's
  • Set syntax is almost identical — SET OF Fruit, IN operator, union/intersection with +/*
  • No exception handling — the error-handling idiom is boolean return codes, like C and Go
Drag cards to reorder · your order is saved locally