github.com/hawx/vodka

A functional, stack-based, concatenative programming language


License
MIT
Install
go get github.com/hawx/vodka

Documentation

Vodka

A functional, stack-based, concatenative programming language of little practical use. It is based on my earlier Catcon, but this is written in Go and features a few syntax changes.

Building

Install with go get,

$ go get hawx.me/code/vodka

Then to start a REPL simply run,

$ vodka
Vodka REPL, CTRL+C or type 'quit' to quit
>>

You can now type some commands, for example,

>> 1 2 +
[3] => nil
>> 5 *
[15] => nil
>> pop
[] => 15
>>

Quick Tutorial

Strings

Strings can be created using either single (') or double (") quote marks.

>> "Hello world!"
['Hello world!'"] => nil
>> " Yes." concat
['Hellow world! Yes.'] => nil

Integers

Integers are the only numeric types currently available.

>> 5 6 1000 -123
[5 6 1000 -123] => nil
>> + * -
[-5257] => nil

Boolean & Nil

The boolean values are true and false. There is also the nil value.

>> true false
[true false] => nil
>> and
[false] => nil
>> true
[false true] => nil
>> or
[true] => nil
>> nil
[true nil] => nil

Lists

Lists are created by enclosing a list of values between parentheses. Spaces or newlines are used to delimit values (you can use multiple if you wish).

>> ('a' 'b' 'c')
[('a' 'b' 'c')] => nil
>> 'd' cons
[('a' 'b' 'c' 'd')] => nil
>> head
['a'] => nil

Blocks

Blocks can contain any value or function. They are pushed to the stack unevaluated so can be used in a similar way to anonymous functions in other languages.

>> [ dup * ]
[[ dup * ]] => nil
>> 5 swap
[5 [ dup * ]] => nil
>> call
[25] => nil

Tests

'greet' [ 'Hello ' swap concat ] define

'greet' [
  'say hello' [
    'World' greet 'Hellow World' eq?
  ] can
] describe
$ vodka greet.vk

greet
  .

    1 pass / 0 fail

And we're done. So how about a slightly useful calculation showing some features off,

>> 'sq' [ dup * ] define
[] => nil
>> 4 sq
[16] => 16
>> sq sq
[65536] => 65536
>> drop
[] => nil
>> 'cb' [ dup sq * ] define
[] => nil
>> 4 cb
[64] => 64
>> pop
[] => 64
>> 'fib' [
..   ; first check whether 1 is less than top of the stack
..   dup 1 lt? [
..     ; F(n) = F(n-1) + F(n-2)
..     dup  1 - fib
..     swap 2 - fib
..     +
..     ] if
..   ] define
>> 1 fib
[1] => nil
>> 2 fib
[1 1] => nil
>> 3 fib
[1 1 2] => nil
>> 10 fib
[1 1 2 55] => nil
>> (1 1) [ dup2 + ] apply
[1 1 2 55 (1 1 2)] => nil
>> [[ dup2 + ] apply ] 5 times
[1 1 2 55 (1 1 2 3 5 8 13 21)] => nil
>> 'n-fib' [
..   ; check if the number at the top of the stack is less than 2
..   dup 2 lt?
..   ; if it is just return a list of 1s
..   [ () swap [ 1 cons ] swap times ]
..   ; otherwise calculate the fibonacci sequence
..   [
..     2 -
..     (1 1) swap
..     [[ dup2 + ] apply ] swap
..     times
..     ] if-else
..   ] define
>> drop 5 n-fib
[(1 1 2 3 5)] => nil
>> drop 20 n-fib
[(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765)] => nil
>> quit
$