Concatenative Language
Haskell Emacs Lisp
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



A Concatenative Programming Language

Dochi is strongly influenced by Factor, Lua and Clojure.
Its design goal is to be lightweight and embeddable, similar to Lua.
Its default data structures are immutable, like Clojure.
It has been designed to be a largely static language.


  • Code is a list of words, like Forth/Factor
  • They operate on a stack
  • Bindings can be introduced at any point:
    • Results in 4: 1 (a) a 2 + a +
    • Results in 11: 2 3 4 (a b c) a a + b + c +
  • Top level definitions use the ‘def’ keyword: def square (a) a a *
  • All word definitions are inside a module name
  • Use use module-name to import another module, or use module-name.word
  • Code quotations: number? ["yes" write] ["no" write] if
  • Lists: {1 2 3 4} is syntax sugar for f 4 ; 3 ; 2 ; 1 ; where ; is cons
  • Literal values:
    • Keywords: :hello
    • Strings: "hello"
    • Character: Ch{h}
    • List: L{1 2 3 4}
    • Table: T{:a 1 :b 2 :key value}
    • Cons: C{1 2}

Standard Library

core library

word stack effect description
pp (value → ) pretty prints a value
write (string → ) writes a string to output
→string (value → string) converts a value to a string
if (condition true-quot false-quot → ) branch based on condition
+ – * / (num num → num) operate on two numbers
< <= > >= = (value value → bool) compare two values

table library

<< (table value keyword → ) associate keyword with value in table
>> (table keyword → value) return association of keyword in table
keys (table → list) table keys
values (table → list) table values
union (table table → union) union of two tables

list library

; (value value → cons) cons two values
head (cons → value) head of cons
tail (cons → value) tail of cons
length (list → number) length of list
nth (list n → value) nth value of list

Embedding in Haskell Code

  • Parse.dochiParseFile Turns a string of code into a [ChiModuleAST].
  • Interpreter.emptyState an empty interpreter state.
  • Interpreter.injectAST compiles and injects a list of ChiModuleAST into the interpreter state.
  • Interpreter.injectLib injects a Haskell ChiModule into the interpreter state.
  • Interpreter.runWord runs a word in the given interpreter state.
  • Interpreter.runDochi runs a string of code in the given interpreter state.
  • Util.runFiles takes a list of filenames, parses and compiles them, and runs ‘main.main’
  • Util.runFilesWithState does the same with an initial state.