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 C Browse comparisons ↓

Choose your own path by reordering languages

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 behavior, 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
COBOL Pre-Alpha

Built for exact money math, not binary floating point. COBOL's PIC 9V9 fixed-point fields store decimal digits exactly — the opposite tradeoff from Pascal's binary Real, which is precisely why COBOL, not Pascal, runs the world's bank ledgers.

  • PIC 9V9 fixed-point decimal fields store money exactly — no IEEE 754 rounding error the way Pascal's Real always carries
  • Four mandatory DIVISIONS (IDENTIFICATION/ENVIRONMENT/DATA/PROCEDURE) replace Pascal's single program ... end. block
  • A plain PROCEDURE DIVISION paragraph takes no parameters at all — no var-parameter contract, just shared global WORKING-STORAGE fields
  • Group items with 01/05-level numbers are a genuinely close structural match to Pascal records — nesting depth encoded in the level number instead of record...end syntax
  • MOVE, not :=, is the assignment verb, and fixed-width PIC X(n) fields pad with trailing spaces where a Pascal string holds only its exact characters
  • Deliberately designed to read like an English specification document, where Pascal (a decade younger) optimizes for a programmer's clarity and brevity instead
Fortran Pre-Alpha

Unusually close cousins from the same structured-programming era — with one sharp, genuinely new capability. Fortran and Pascal share almost the same numeric-type vocabulary and a near-exact parameter-passing correspondence, but Fortran treats an array as a first-class value you operate on directly, something Pascal has no equivalent for at all.

  • Whole-array arithmetic — prices = prices * 0.9 scales every element in one statement, where Pascal always needs an explicit indexed loop
  • sum(), maxval()/minval(), and where operate on entire arrays at once — a numerical toolkit with no Pascal parallel whatsoever
  • intent(in)/intent(inout)/intent(out) map almost exactly onto Pascal's plain/var/out parameter modes — one of the closest one-to-one mappings on the whole site
  • A role reversal on strings: Fortran's character(len=n) is a genuinely fixed-width field that silently truncates, where Pascal's string grows and shrinks dynamically with no declared maximum at all
  • implicit none opts IN to what Pascal has always required by default — undeclared Fortran variables otherwise infer their type from their first letter, a historical quirk Pascal never had
  • Derived type with % field access is a close structural match to Pascal's record with . access
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 Meters 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
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
Drag cards to reorder · your order is saved locally