V language 0.005

V language is a tiny concatenative language implemented for experimentation.

  Add it to your Download Basket!

 Add it to your Watch List!


Rate it!
send us
an update
Public Domain 
3.1/5 17
ROOT \ Programming \ Interpreters
V language is a tiny concatenative language implemented for experimentation.

The source is under Public Domain (un-copyrighted.)

The full featured language is on top of JVM, A native version (in alpha state) is also there in the codebase.

To run it, extract the distribution in any directory and do #gmake run.

gmake run


The language is a close relative of postscript, forth and joy. and is stack based. ie:

|2 3 *
|2 3 * 5 +

See status for a tutorial and more info.

The Functions available in V are available in this page: functions
(The releases are out of date and multiple fixes have gone in. Please check out and build rather than use them.)

Example functions in V. getting the roots (with out using the stack shuffling word 'view')

[a b c] let
[minisub 0 b -].
[radical b b * 4 a * c * - sqrt].
[divisor 2 a *].
[root1 minisub radical + divisor /].
[root2 minisub radical - divisor /].
root1 root2

|2 4 -30 quad-formula ??
=(-5.0 3.0)
using 'view'
[a b c : [0 b - b b * 4 a * c * - sqrt + 2 a * /]] view i

|2 4 -30 quad-root ??

contrast this with the definition in scheme here
(define quadratic-formula
(lambda (a b c)
(let ([minusb (- 0 b)]
[radical (sqrt (- (* b b) (* 4 ( * a c))))]
[divisor (* 2 a)] )
let ([root1 (/ (+ minusb radical) divisor)]
[root2 (/ (- minusb radical) divisor)])
(cons root1 root2)))))

Definition of Qsort.

[joinparts [pivot [*list1] [*list2] : [*list1 pivot *list2]] view].
[split_on_first_element uncons [>] split&].
#args starts for binrec. notice that 2 arguments (termination condition
#and its result) are on first line.
[small?] []
#binrec recurses on the result of split_on_first_element before applying joinparts.
Some explanations.
The first and second lines (terminated by '.') are internal function definitions
(Notice how qsort is also terminated by '.') '.' is the definition syntax in V.

The first function joinparts
The function joinpart contains just an application of the operator view.
'view' is list translator. It takes a list of the form [template : result]
then it tries to apply the template to the current stack. If it can be applied on the
stack, then the arguments named in the template are bound to values in stack. The result is then processed, and all the bound elements in result are replaced by their values.

[pivot [*list1] [*list2] : [*list1 pivot *list2]] view expects 3 arguments on the stack,
the first a single element pivot, then two lists list1 and list2.
It returns a list that is composed of elements of list1 followed by pivot
followed by elements of list2 (as defined in result - RHS of ':').

44 [1 2 3] [5 6 7] [pivot [*list1] [*list2] : [*list1 pivot *list2]] view ??
=> [1 2 3 44 5 6 7]
(The function ?? is used to print out the elements in the stack now.)

The second function split_on_first_element
The definition is [uncons [>] split&]

The uncons splits a list into the first element and the rest of the list.

[1 2 3 4 5] uncons ??
=1 [2 3 4 5]

split& takes two arguments, the first is the function F to split a list with,
and the second the list itself. All elements in the list that passes the function F
is put into the first list, and all that do not are put into the second list.

[1 2 3 4 5 6 7] [4 >] split& ??
=[5 6 7] [1 2 3 4]

The function F can also take an argument from the stack. so this also works.

4 [1 2 3 4 5 6 7] [>] split& ??
=[5 6 7] [1 2 3 4]

Thus the split_on_first_element takes the first element of a list, and split that
list based on that element as a filter.

binrec expects 4 arguments,

Arg1 is the terminating condition,
Arg2 is the result if the terminating condition is met.
Arg3 is an executable statement that returns two entities.
The entire binrec statement is performed on each of the
two entities until the terminating condition is met.
Arg4 is what to do with the result of the previous statement.
Here, the small? checks if the list is empty or contains just one element.
if it is, then the result is arg2 - []
[] small? ??

[1] small? ??

[1 2 3 4] small? ??

split_on_first_element takes is executed on all lists that are larger than size 1
and as explained above, splits them into two based on the first element.
on the resultent lists, the entire qsort is performed again due to binrec.

The last joinparts takes these elements (pivot list1 list2) which are present now
on the stack, and combines them to produce a single sorted list.

A slightly friendlier function (with out the binrec.)

[joinparts [pivot [*list1] [*list2] : [*list1 pivot *list2]] view].
[split_on_first_element uncons [>] split&].
[split_on_first_element [list1 list2 : [list1 qsort list2 qsort joinparts]] view i]

The binrec and friends are more powerful than the explicit recursion done above, but for people new to concatenative languages, this kind of recursion may look more intuitive.

What's New in This Release:

· A new native implementation with a simple instance counting GC is available.
· A few of the function signatures have changed.
· The exception handling is more robust now.
· A syntax file for V in Vim is available in the distribution.

Last updated on August 24th, 2007

#concatenative language #programming language #linux interpreter #interpreter #programming #concatenative #language

Add your review!