Worst is a simple, malleable programming language built for extensibility and creativity.
dynamically typed, dynamically scoped,
procedural, concatenative, stack-based,
and has a tiny but powerful syntax system.
Worst takes parts of Forth, Tcl and Lisp and gently presses them together into something small and easily digestible.
Worst is designed to be easy to learn, understand, and implement, with only a few core concepts to consider.
Worst allows you to override any and all functions and syntax
to change the language at will.
For example, the self-hosting compiler-to-Lua works by hijacking every function definition and flow control statement to output Lua code instead of actually executing, and it’s a pure-Worst library you can import like any other.
Adding new functionality and syntax to the language
is as easy as writing normal code.
Static type checking, custom error handlers, new loop styles, DSL blocks, use-once variables, debugging symbols, function decorators and attributes, here documents, user-defined data types, nasal demons — every feature you might think has to be baked in to a programming language is implementable in plain Worst.
Worst is not just a language for experimenting with programming;
it will also support a variety of creative applications such as
procedural music and graphics.
It will hopefully grow into a tool that anyone would be excited to pick up and make something cool with — programming experience optional.
; Define 'hello' as a function that shows you The Message. define hello [ "Hello, " swap string-append "!\n" string-append prints ] ; All hail The Message. "World" hello ; Use magic sigils to peek into the future of the program. define hello-forwards [ ^' hello ] ; It's actually not magic, sorry. ^' is a combination of 'quote' and 'uplevel'. true if [hello-forwards "World"] [hello-forwards "Brent"]
; A naive factorial function. ; factorial(n) = let n' = n - 1; if (n' = 0) then n else factorial(n') * n define factorial [ clone 1 negate add 0 equal?! if [drop] [factorial mul] ] 20 factorial ; => 2432902008176640000 ; '1 negate add' is cumbersome. Let's add an infix '-'. define - [ ^' negate add ] 4 - 1 ; => 3 ; '0 equal?!' is ugly too. define zero? [ 0 equal?! ] ; A little easier to read, but still not tail-recursive. define factorial [ clone - 1 zero? if [drop] [factorial mul] ] ; Make it tail-recursive by including an accumulator and a counter. define factorial [ ; acc n factorial -> int 1 equal?! if [ drop ] [ ; Take a copy of n and save it for later clone 2 negate dig ; let acc' = acc * n mul ; let n' = n - 1 swap - 1 ; This call won't take up more stack space ; since it's at the end of the function (TCO). factorial ] ] 1 20 factorial ; => 2432902008176640000 ; Hide the accumulator in a wrapper function define fact [ 1 swap factorial ] 20 fact ; => 2432902008176640000