var'aq Preliminary Specification


Brian Connors
29 May 2000
last updated 02 January 2001

0 Introduction

This specification documents the programming language var'aq. var'aq is a programming language created as part of an exercise to imagine the hacker culture of Star Trek's Klingon race. The Klingon culture was chosen because it is probably the best-realized of all such cultures in the Science Fiction/Fantasy genres of literature, and the Klingon language is sufficiently different from English to make language design a significant challenge.

0.1 Language Levels

var'aq is divided into three implementation levels, each a subset of its successor. An implementation conforming to the current var'aq spec should be labeled with the level of conformance.

0.2 Legalese, Credit, Etc.

var'aq was concieved by Brian Connors and implemented by Brian with help from Chris Pressey and Mark Shoulson. It is an independent project and is not connected with the Star Trek people (i.e. Paramount/Viacom).

This document is (c)2000-2001 Brian Connors and may be distributed freely as long as this copyright notice is retained. You may freely implement for private use a var'aq implementation with no restriction; you must contact me for certification (i.e. I make sure you're following the spec) in order to distribute your implementation as freeware. This specification may not be used for commercial purposes without a separate licensing arrangement.

0.3 Apologies

You'll notice that I tend to drift in and out of character in this document. The only thing I can say to this is that character isn't a great concern in a specification document; I may do an extensive revision later on, but as I write this var'aq isn't even alpha-quality code, and the spec is subject to change anyway. Just enjoy and try to keep up; we'll worry about "realism" later. Thank you for your patience.

1 Language Overview

var'aq is a stack-based, RPN programming language with points of similarity to Lisp, Forth, and PostScript. It is more of a functional language than an imperative (Algol-like) language; most operations are dependent on the stack and bypass the local variable store altogether.

1.1 Notation Used In This Specification

All operator names will be given in English and Klingon. The notation and format of the operator entries are cribbed from Adobe's PostScript Language Specification.

1.2 Basic Concepts

var'aq is a fairly simple, RPN-based language where pretty much everything is an operator. It is fairly loosely typed and little distinction is made between code and data. Typechecking is not strictly required (and in fact does not exist in the current reference implementation) but is encouraged.

1.3 Data Types

var'aq recognizes only a few data types so as to keep the programming model as simple as possible.

1.3.1 number/mI'

var'aq numbers are a bit nonspecific as to representation; there is no support for complex numbers in a Level 0 implementation (Level 1 and above do include support). In general, integers (HabmI') and reals are considered interchangeable where possible, and the interpreter is expected to use whichever is more efficient. Note that integer operations such as Habwav and the bitwise operators will generally silently truncate the operands (optionally giving a runtime warning if so requested by the user).

1.3.2 function/jangwI'

A function in var'aq is understood to be much the same thing as a lambda closure, i.e. a procedure with a return value (thus the Klingon term jangwI', meaning "answerer"). Functions are defined using the { } operators, and may be assigned names using the pong operator.

1.3.3 list/ghomHom

var'aq lists (ghomHom, meaning "cluster" (sort of)) are in some ways very similar to those of Lisp.

1.3.4 string/tlhegh

Strings in var'aq (and Klingon programming in general) seem to be considered something of a black art; Klingon computer science appears to have no real concept of anything like regular expressions, and as a result decent string handling is the territory of those trusted to write things like language compilers (ngoq poSmoH? The idea would baffle a Klingon... so insecure, so random...). Brute-force string comparisons seem to be the order of the day in current practice. That said, var'aq strings also have a couple of important properties: a) white space is not significant; b) they can be decomposed into lists using the joq operator; and c) they can be used as literal names (though it's not a terribly good idea).

1.4 Basic Assumptions

1.4.1 Number Representations

All standard var'aq systems are assumed to be binary machines using eight or sixteen-bit bytes (word size is unimportant). Negative integer values are represented as two's-complement. A floating-point implementation is not specified, though the Klingon floating-point standard is not drastically different from IEEE floating point (differing bit positions, primarily). If a standard float must be chosen, go with IEEE double-precision.

1.4.2 Garbage Collection

All var'aq implementations are required to use garbage collection (woDHa', roughly meaning "retrieve" or "unwaste"). No standard algorithm is specified, and this requirement may be ignored if the implementor uses an environment where this is assumed (Perl, for example).

1.4.3 Filetypes

Klingon military computer systems use a sort of modular-database storage scheme in which the concept of "file" doesn't mean a whole lot. However, on systems where files are the common way of doing business, the following extensions and MIME types are standard:

Note that this is being specified here mainly as a matter of convenience. The var'aq resource file format has not yet been defined.

2 Language Basics

This section describes the fundamental var'aq language constructs and data types.

2.1 Stack Operations

These operations directly manipulate the var'aq operand stack. The operand stack can hold any of four kinds of data: numbers (real or integer), strings, functions, or arrays. It is best described as "translucent", similar to the transparent stack of Forth or PostScript but somewhat more restricted. The internal data representation of the stack is not available to the programmer.

2.1.1 pop/woD

obj woD -

Pops and discards the top item on the stack. The literal meaning is discard.

Errors: stackUnderflow

2.1.2 dup/latlh

obj latlh obj obj

Duplicates the top object on the stack.

Errors: stackUnderflow

2.1.3 exch/tam

obj1 obj2 tam obj2 obj1

Inverts the order of the top two objects on the stack.

Errors: stackUnderflow

2.1.4 clear/chImmoH

... obj chIm -

Empties the stack.

Errors: none

2.1.5 remember/qaw

- qaw flag

Puts a flag (like PostScript's mark) on the stack. The internal representation of the flag is not available to the programmer.

Errors: none

2.1.6 forget/qawHa'

... flag ... qawHa' ...

Clears the stack down to the flag and pops the flag. If there is no flag present, the stack is emptied completely.

Errors: none

2.1.7 dump/Hotlh (lit. scan)

... Hotlh ...

Prints the contents of the operand stack to STDOUT without changing them. Note: the Hotlh operator is a debugging operator and is not intended for use in programs; it is merely documented here because it might be useful to a var'aq developer. In particular, the output format of this operator is implementation-defined and will not be specified in this document. Hotlh may be redefined to take such arguments as the implementor feels appropriate.

Errors: implementation-defined.

2.2 Data/Code Operations

var'aq, like many similar languages, does not distinguish between code and data. These operations include operators to associate names with objects and executable procedures, as well as operators to define and manage data structures. Note that variables and procedures live in a common namespace, since the act of pushing the content of a variable is essentially the same as executing the variable's name.

2.2.1 ~ (quote/lI'moH)

- ~ obj obj

The ~ operator is a special form, as it is not a postfix operator. When the interpreter encounters a ~, it pushes the next token on the stack as is regardless of whether it is a defined name. (Attempting to push an undefined name without a ~ will generate an undefinedName error.)

The literal meaning of this operator's name is "make useful". Errors: none

2.2.2 {

Begins the creation of an anonymous procedure. The process is implementation-dependent.

2.2.3 }

- } proc

Completes procedure construction and pushes a reference to the completed procedure on the stack. Does not execute the procedure.

Errors: noDefinedProc

2.2.4 name/pong

obj id pong -

Associates obj with id and places it in the system lookup space. Conventionally used to associate new operator names with procedure objects.

Example: ~ add3 { chel chel cha' } pong

Pushes the name add3 and a procedure object on the stack, then binds the name to the procedure.

Errors: stackUnderflow, noDefinedProc

2.2.5 set/cher

obj id cher -

Reassigns the value of a value already in the system lookup space. Used primarily for variable assignments.

Errors: stackUnderflow, noSuchName

2.2.6 (* ... *) (comment)

Marks a comment in a program. All such comments are treated as single tokens and ignored.

2.2.7 //name

Causes the interpreter to import a file with the name name.vql and execute it as if it is part of the currently executing program. This can be handled by an external static linker if there is no shlib-like facility in the interpreter. Essentially equivalent to #include in C.

2.3 Control Flow

var'aq supports a small but sufficient supply of conditional and iterative operators.

2.3.1 ifyes/HIja'chugh

bool proc HIja'chugh -

Pops the proc object off the stack, then evaluates the boolean. If it's true, the proc object is evaluated; otherwise, it's thrown out.

Errors: stackUnderflow, noDefinedProc

2.3.2 ifno/ghobe'chugh

bool proc ghobe'chugh -

Similar to HIja'chugh above, but executes proc only if bool is false.

Errors: stackUnderFlow, noDefinedProc

2.3.3 choose/wIv

bool wIv bool bool

Duplicates a boolean value on top of the stack. Allows paired HI'ja'chugh/ghobe'chugh clauses.

Note: To the untrained eye, it may seem as though wIv and latlh are identical. This is true in the reference implementation, but may not be in any version that actually does some level of type checking. This bit of syntactic sugar should never be relied upon; always use wIv in this situation.

2.3.4 eval/chov

proc chov -

Pops a proc object off the stack and executes it.

Errors: stackUnderflow, noDefinedProc

2.3.5 escape/nargh

bool nargh -

Exit the current procedure. Useful for exit conditions on loops. Will terminate the current session if used top-level.

2.3.6 repeat/vangqa'

val proc vangqa' -

Pops val and proc off the stack and executes proc val times.

2.4 List Operations

var'aq supports a series of operators for management of lists (ghomHom, which seems to mean something like "cluster"). These primitives are the language's primary way of managing aggregate objects and work much like similar operators in LISP; a more sophisticated paradigm, such as OO extensions or the like, can be built with these operators.

Note that "objects" as they stand in var'aq are largely singletons as in JavaScript; there is no inherent concept of object-orientation or anything like it in standard var'aq.

2.4.1 (

Begins a list definition.

2.4.2 )

( item1 item2 ... ) list

Creates a list and pushes it onto the stack.

2.4.3 split/SIj

list SIj item1 list

Pops a list off the stack and returns the first item and the rest of the list.

2.4.4 cons/muv

list item1 ... muv list

Takes an object and adds it to the head of a list. Equivalent to the LISP cons operator.

2.4.5 shatter/ghorqu'

list ghorqu' item1 item2 ...

Reduces a list to its component elements and pushes them on the stack in order.

Note: The precise meaning of the construction ghorqu' is a bit obscure; the rendering shatter is idiomatic and may derive from a nonstandard dialect. Standard Klingon would generally prefer jor, meaning explode.)

2.4.6 empty?/chIm'a'

list chIm'a' bool

Examines a list on the stack and returns 1 if its value is null (pagh), a 0 if it contains anything. Note: some implementations also have an operator known as bite/chop, equivalent to the Lisp cdr. This is not required in any standard var'aq implementation and can easily be rendered by the function



~ chop { SIj woD } pong

2.5 String Operators
tlheghjangwI'mey

String handling in var'aq is generally thought to be somewhat deficient by Earth standards; all strings are handled as if whitespace is not significant, and string management is a bit primitive. Substrings are understood, as are very basic forms of pattern matching, but Klingon computer science seems to regard string-handling facilities such as regular expressions as something of a black art, left only to those responsible for writing compilers and that sort of thing.

2.5.1 strtie/tlheghrar

str1 str2 tlheghrar str3

Concatenates the top two strings on the stack into one.

2.5.2 compose/naQmoH

mark str1 str2 ... strn naQmoH strn'

Pops objects (executing proc objects if necessary) off the stack until a marker (placed by qaw) is hit and combines them into one string.

2.5.3 streq?/tlheghrap'a'

str1 str2 tlheghrap'a' bool

Pops the top two strings on the stack, compares them, and returns 1 if identical, 0 if not.

2.5.4 strcut/tlheghpe'

str startval endval tlheghpe' substr

Pops two values and a string and returns the section of the string between character startval and character endval.

2.5.5 strmeasure/tlheghjuv

str tlheghjuv val

Pops a string off the stack and returns its length in characters.

2.5.6 explode/jor

str jor list

Separates individual "words" in a string by whitespace.

3 Mathematical Operators
mI'jangwI'mey

Klingon mathematical study is somewhat less sophisticated than Federation standard, but it covers all the important concepts. A full set of arithmetic and basic trigonometric operations is available.

3.1 Arithmetic Operations
toghwI'mey

Arithmetic operators usually work with real numbers unless otherwise stated. The number operators (sec 3.3) can convert them to integers if necessary.

(note: verisimilitude would require that the Klingon understanding of math not necessarily coincide with ours. But I think it's safe to say that this basic set of operations is enough to at least get a Klingon battlecruiser out of spacedock.)

3.1.1 add/boq

a b boq sum

Pops the top two values on the stack and replaces them with their sum.

Note that the four basic operations are based around the term boq, which literally means "to ally with". The metaphor is a bit strained but is well-established enough that most Klingons do not think twice about it.

3.1.2 sub/boqHa'

a b boqHa' difference

Pops the top two values on the stack and replaces them with a - b.

3.1.3 mul/boq'egh

a b boq'egh product

Pops the top two values on the stack and replaces them with their product.

3.1.4 div/boqHa''egh

a b wav quotient

Pops the top two values on the stack and replaces them with a/b.

3.1.5 idiv/HabboqHa''egh (lit. full-divide)

a b HabboqHa''egh quotient

Pops the top two values on the stack and replaces them with the results of an integer division operation.

3.1.6 mod/chuv (lit. leftover)

a b chuv remainder

Pops the top two values and returns the remainder of a mod b.

3.1.7 pow/boqHa'qa' (lit. remultiply)

base exp boqHa'qa' real

Pops the top two values and returns base^exp.

3.1.8 sqrt/loS'ar (lit. fourth-howmuch)

angle loS'ar real

Returns the square root of val.

3.1.9 add1/wa'boq

a wa'boq a+1

Increments the top value on the stack by one.

3.1.10 sub1/wa'boqHa'

a wa'boqHa' a-1

Decrements the top value on the stack by one.

3.2 Trigonometric and Logarithmic Operators
SIHpojjangwI'mey 'ej ghurjangwI'mey

The standard Klingon unit of arc measure is the vatlhvI' (hundredth-part), which is the same term used for percentage. However, Klingon mathematicians are familiar with the concept of radians (botlhchuq, center-distance) and all known var'aq implementations work in radians for input and output.

3.2.1 sin/joq (lit. wave)

angle joq real

Returns the sine of val.

3.2.2 cos/joqHa' (lit. counter-wave)

angle joqHa' cos(val)

Returns the cosine of val.

3.2.3 tan/qojmI' (lit. cliffnumber)

angle qojmI' tan(val)

Returns the tangent of val.

3.2.4 atan/qojHa' (lit. anticliff)

num den qojHa' angle

Returns the arctangent of num / den.

3.2.5 ln/ghurtaH

num ghurtaH real

Returns the natural log of num.

3.2.6 log/maHghurtaH

num maHghurtaH real

Returns the base 10 log of num.

3.2.7 log3/wejghurtaH

num wejghurtaH real

Returns the base 3 log of num. (This function is actually considered a level 1 function, and is believed to exist only for historical purposes. Its use is very rare except among programmers whose native language is Standard High Klingon (which historically used a base 3 number system) and is unknown among other users.)

3.3 Numerical Operators and Constants

This section describes operators that operate on numbers themselves, as well as common system-level constants. (Note that some of these functions look like verbs in English and adjectives in Klingon; the idea is that where we might say 1.3 clip to get 1 a Klingon would be thinking the clipped 1.3.

3.3.1 clip/poD

real poD int

Removes the fractional portion of a real number (equivalent to floor(real).

3.3.2 smooth/Hab (lit. smooth)

real Hab int

Rounds a number to the nearest integer.

3.3.3 howmuch/'ar

num 'ar num2

Returns the absolute value of num.

3.3.4 setrand/mIScher

num mIScher -

Sets the random number generator seed value to num. Not common, since most var'aq implementations have a rather arcane formula for picking a pseudo-random seed value (security reasons, presumably).

3.3.5 rand/mIS

num mIS real

Returns a random real number in the range 0 to num. If there is no meaningful input on the stack,

3.3.6 pi/HeHmI'

Pushes the value pi (~3.14159...) onto the stack. The Klingon name literally means "edge-number".

3.3.7 e/ghurmI'

Pushes the value e onto the stack. The Klingon name literally means "growth-number".

3.3.8 int?/HabmI''a'

val HabmI''a' bool Pops the top value on the stack and returns 1 if it is an integer, 0 if not.

3.3.9 number?/mI''a'

val mI''a' bool

Pops the top value off the stack and returns 1 if it's a number, 0 if it's something else.

3.3.10 numberize/mI'moH

str mi'moH val

Pops a string off the stack, converts it into a numerical value, and returns it.

3.4 Bitwise operators

Though var'aq makes no clear distinction between integers and reals, it is nevertheless useful to be able to manipulate a number on the bit level. The following operators assume that their operands will always be treated as integers; effects on floating-point values are undefined, and may be disallowed at the implementor's discretion.

Note: The var'aq bitwise operators are quite controversial as of this writing (they are considered inappropriately low-level) and may be removed or altered in future versions of this specification.

It is to be noted that the Klingon coinages for the operation (especially tlhoch (contradict) for xor) are unusually obscure even for Klingon hackerspeak and probably reflect fairly profound differences in shades of meaning.

3.4.1 isolate/mobmoH

a b mobmoH result

Performs a bitwise AND on a and b.

3.4.2 mix/DuD

a b DuD result

Performs a bitwise OR on a and b.

3.4.3 contradict/tlhoch

a b tlhoch result

Performs a bitwise XOR on a and b.

3.4.4 compl/Qo'moH

val Qo'moH ~val

Returns the one's-complement of val. Note: The literal meaning is something like "make it say no".

3.4.5 shiftright/nIHghoS

a b nIHghoS result

Shifts a right b places, preserving the sign of the value.

3.4.6 shiftleft/poSghoS

a b poSghoS result

Shifts a left b places.

4 Relational and Logical Operators

4.1 Relational Operators and Predicate Functions
yu'jangwI'mey

The standard convention for anything that returns a boolean argument is to end the keyword in the interrogative suffix -'a', which in general is analogous to Lisp's well-established -p (plain old Lisp) or -? (Scheme and Dylan) predicate conventions; the English versions of the keywords follow the Scheme convention for consistency with the Klingon. The tlhIngan Hubbeq Say'ghun'ogh paq (KDF Programmer's Style Guide) requires this convention; see that document for further information.

4.1.1 gt?/law''a'

a b law''a' bool

Pops a and b off the stack, compares them, and returns a boolean value of true if a is larger.

4.1.2 lt?/puS'a'

a b puS'a' bool

Pops a and b off the stack, compares them, and returns a boolean value of true if a is smaller.

4.1.3 eq?/rap'a'

a b rap'a' bool

Pops a and b off the stack, compares them, and returns a boolean value of true if a is the same as b.

4.1.4 ge?/law'rap'a'

a b law'rap'a' bool

Pops a and b off the stack, compares them, and returns a boolean value of true if a is greater than or equal to b.

4.1.5 le?/puSrap'a'

a b puSrap'a' bool

Pops a and b off the stack, compares them, and returns a boolean value of true if a is less than or equal to b.

4.1.6 ne?/rapbe'a'

a b rapbe'a' bool

Pops a and b off the stack, compares them, and returns a boolean value of true if a is not equal to b.

4.1.7 null?/pagh'a'

obj pagh'a' bool

Examines the top object on the stack and returns a 1 if null, a 0 if not.

4.1.8 negative?/taH'a'

val taH'a' bool

Pops the top number on the stack and returns a 1 if less than 0, a 0 if not.

4.2 Logical Operators
vItjangwI'mey

Note that these are strictly logical operators, not bitwise.

4.2.1 and/je

a b je bool

Evaluates b and a and returns a 1 if both are true, a 0 if not.

4.2.2 or/joq

a b joq bool

Evaluates b and a and returns a 1 if one or both are true, a 0 if both are false.

4.2.3 xor/ghap

a b ghap bool

Evaluates b and a and returns a 1 if only one is true, a 0 otherwise.

5 Input/Output and File Operators

The var'aq Level 0 specification essentially handles console I/O and files in a manner very similar to the UNIX model.

5.1 Console I/O

The console I/O model at this point is very simple: write, read, error.

5.1.1 disp/cha'

obj cha' -

Pops the top object on the stack and writes it to STDOUT. Note that certain types of objects will generate meaningless output, particularly anonymous proc objects.

5.1.2 listen/'Ij

- 'Ij str

Reads one line of input and stores it as a string on top of the stack.

5.1.3 complain/bep

str bep -

Pops str and prints it to stderr.

6 System Variables
patSarwI'mey

This section describes var'aq keywords that do no more than put set values on the stack. Many of them are not precisely constants but more like environment variables.

6.1 I/O-related Constants

6.1.1 newline/chu'DonwI'

Prints a carriage return.

6.1.2 tab/chu'tut

Advances by one tab stop.

6.2 Environment Constants

6.2.1 whereami/nuqDaq_jIH

Represents the location of the current host device. On Earth implementations, usually returns the IP address of the machine the interpreter is running on.

6.2.2 version/pongmI'

Returns the current interpreter version number. The reference interpreter returns a date stamp.

6.2.3 argv/taghDe'

Pushes the command line arguments on the stack as a list.