Strongtalk
new Translate Strongtalk to TypeScript · installers for every OS

Smalltalk, with types that never get in the way<Self>

Strongtalk was the 1990s Smalltalk with an optional, sound type system and a virtual machine so fast that Sun turned it into Java HotSpot. This edition re-builds it in Rust and runs it right here in the page, with nothing to install.

Workspace VM sleeping
⌘/Ctrl + Enter Full environment →
Press “Print it”. The VM starts in your browser on first use.
65 classes in typed Strongtalk 100% runs in your browser TS Strongtalk → TypeScript Rust bytecode VM + type checker
The type system

Add types one method at a time. Remove them and nothing changes.

Types are written in angle brackets and checked separately from running the program. Untyped code is trusted, so a large program can be typed gradually, and the checker never alters what code does.

Plain Smalltalkruns
deposit: amount
    amount <= 0 ifTrue: [
        ^self error: 'must be positive'].
    balance := balance + amount.
    history add: amount

detect: aBlock
    self do: [:each |
        (aBlock value: each) ifTrue: [^each]].
    ^self error: 'not found'
Strongtalkruns the same, and type-checks
deposit: amount <Int> ^<Self>
    amount <= 0 ifTrue: [
        ^self error: 'must be positive'].
    balance := balance + amount.
    history add: amount

detect: aBlock <[E, ^Bool]> ^<E>
    self do: [:each <E> |
        (aBlock value: each) ifTrue: [^each]].
    ^self error: 'not found'

<Int> Protocols, not classes

A type names the messages an object understands, so unrelated classes that answer the same messages share a type.

<Self> Types that follow subclasses

Self and Instance types give subclasses the right result types without redeclaring a single method.

Array[E] Generics and blocks

Generic collections, union types and block types like <[Int, ^Bool]> cover real Smalltalk idioms.

New · Strongtalk → TypeScript

Your typed Smalltalk, as readable TypeScript

Strongtalk's annotations carry straight over: <Int> becomes number, <Self> becomes this, and control messages become plain if and for. Translate on the web, with strongtalk --to-ts in a terminal, or with one click in the environment.

StrongtalkBankAccount.dlt
deposit: amount <Int> ^<Self>
    "Add money; deposits must be positive."
    amount <= 0 ifTrue: [
        ^self error: 'deposits must be positive'].
    balance := balance + amount.
    history add: amount

total ^<Int>
    ^history inject: 0 into: [:a :b | a + b]
TypeScriptBankAccount.ts
/** Add money; deposits must be positive. */
deposit(amount: number): this {
  if (amount <= 0) {
    throw new Error('deposits must be positive');
  }
  this.balance = this.balance + amount;
  this.history.push(amount);
  return this;
}

total(): number {
  return this.history.reduce((a, b) => a + b, 0);
}
This edition

A complete Strongtalk, rebuilt in Rust

The original ran only on 32-bit Windows. This one compiles the same language to bytecode and runs it natively on a Mac, or as WebAssembly in any modern browser.

Typed parser and compiler

The full Strongtalk syntax, type annotations included, compiled to a compact bytecode.

Bytecode interpreter

Activations live on the heap, so recursion can go very deep. Blocks support non-local return.

The whole numeric tower

SmallInteger, LargeInteger, Float and Fraction arithmetic: 100 factorial just works.

Type checker

Check a class, a method or a do-it from the browser. Errors point at the expression that failed.

ANSI exceptions

on:do:, ensure:, retry, resume:, with primitives named after the original VM's.

File-in, file-out

Strongtalk's Delta define:as: chunk format, so classes travel as plain source files.

The environment

The classic Strongtalk desktop, in a tab

A windowed, image-style environment like the original, with the VM running in a Web Worker so an endless loop never freezes the page.

  • Launcher and Transcript, multiple workspaces with Do it, Print it and Inspect it
  • Class hierarchy and outliner class browsers that compile methods as you save
  • Inspectors, debugger-style error windows and picture windows for graphics
  • Your changes are kept between visits and can be filed out as source
Start Strongtalk →
Lineage

A small language with a long shadow

The people and ideas behind Strongtalk went on to shape the runtimes most of us use every day.

1987–91

Self

Optimizing compilers for a pure object language at Stanford and Sun.

1993

Strongtalk types

An optional, sound type system for Smalltalk, presented at OOPSLA.

1994–96

Animorphic

A small company builds the Strongtalk system and its adaptive VM.

1997–99

Java HotSpot

Sun acquires Animorphic; the VM becomes the heart of Java.

2006 →

Open source, V8, Dart

Strongtalk is released; its team goes on to V8 and Dart.

Read

Four short articles

A tour of where Strongtalk came from, how its types and VM work, and how this edition was made.

01History

From Self to HotSpot

A small company, a research VM and a type system for Smalltalk, and where their ideas ended up.

Read →
02Language

Typing Smalltalk without breaking it

Optional types, protocols instead of classes, generics, and a checker that never changes behaviour.

Read →
03Implementation

Why the VM was so fast

Tagged integers, inline caches, type feedback and adaptive optimization.

Read →
04This edition

Rebuilding it in Rust

How the original was studied and re-implemented, and what behaves exactly like it.

Read →
Download

Install it on your computer

One program with the terminal workspace, the type checker, the TypeScript translator and the full environment, which strongtalk web opens in your browser, offline.

One line

macOS and Linux:

$ curl -fsSL https://volland.github.io/strongtalk/install.sh | sh

Windows (PowerShell):

> irm https://volland.github.io/strongtalk/install.ps1 | iex

From source

With Rust installed; the website build also needs the wasm32-unknown-unknown target and wasm-bindgen 0.2.128.

$ git clone https://github.com/Volland/strongtalk
$ cd strongtalk && npm run build:native
$ vm/target/release/strongtalk web

Everything is an object. Try sending it a message.

The full environment opens in a second, with workspaces, class browsers and a type checker, all running locally in your browser.