Copyright ã 1994 by Sean Luke

COWS Language
Concepts
COWS Version 1.4
May 29, 1994

This document provides a general overview of the COWS language.  For a more formal description of the COWS language, see COWS Language Formal Specification.

Basic Format

COWS looks like LISP.  It uses the exact same overall syntax and parenthesis mess.  But to the the more awake programmer, COWS works more like HyperTalk in that it has no main loop, is event driven, and uses strings for its sole data structure (at least for the while).

Like LISP, COWS refers to symbols for its function and variable names.  To look up or store those symbols, COWS uses several dictionaries stored as hash tables.  The function dictionary stores your user-defined functions.  The library dictionary stores the standard library functions and any library functions defined by the application to which the COWS interpreter is attached.  The global dictionary stores global variables.  The current dictionaries of local variables within a function are stored on a stack along with evaluated values and unfinished symbols.

When COWS is in a function, it pushes a current dictionary onto the stack and stores function arguments and local variables there.  When it exits the function, COWS pops the dictionary off the stack.  Hence, COWS can handle recursion quite nicely.

Communicating with The Outside World

COWS functions are called by sending a method to the interpreter, along with a bunch of strings for the arguments to the method.  COWS functions return a single string.

But COWS can also call Objective-C methods as it runs.  These are stored in the function dictionary along with their selectors.  This enables COWS programs to act as macro facilities for NeXT programs.

COWS Data Types

COWS has only one data type:  The string.  All numbers are stored as floating-point numbers encoded in a string.  All truth values are stored in a string.

Strings		When referenced, strings must be written with quotes: "hello".
Numbers 	Numbers are stored with precision as such:  "1.231e43"
			When referenced in COWS, they can just be written 1.231e43.
Truths		Truth values are either non-empty or empty strings (for true and
			false), and can just be written t or f.  The canonical true string is 
			"t".

COWS Values

In COWS, a value is anything that returns a value, be it a special form, a function, a string constant, a number, a truth, or a variable.  All values are stored internally as strings.

COWS thrives on valuesÐthey are the embodiment of the COWS data type.  Values are passed as arguments to other functions or special forms.  Each function or special form returns a single value.

COWS Functions

Functions are declared globally, and can be declared in any order.  Function arguments follow the function-name, and are optional.  Local variables are declared using the optional variable keyword, and are initialized to an empty string.  You define a COWS function in the format:

(function function-name
	argument-name argument-name ...           	[optional]
	variable variable-name variable-name ...	[optional]
	do function-body)
	
An example:

Þ	(function print-x-to-y x y
	 	variable z 
		do (if (< x y) (for z x y 1 (print z))))	prints the numbers from x to y,
										given that x < y.

During the course of action, COWS functions may call any other COWS function, be it a user-supplied function or a library function.  This includes a function calling itself (recursion).  There is no specified limit to recusion depth.

COWS Libraries

Some COWS functions come grouped in libraries, which can be adopted by or ignored by COWS-compliant applications.  These functions are called COWS Library Functions, and are not written in COWS but in Objective-C for extra speed.  It is the COWS library function suite that provides the COWS interpreter (and you) the ability to do useful things with COWS.

There are six libraries in the standard COWS suite, but the only one that must generally be included is the COWS Standard Function Library, described in an accompanying file.  Other common libraries provide arrays, inter-process communication and control using NeXT's Distributed Objects system, string processing, math functions, and common system utilities.  Applications may provide their own custom library functions, and there are several experimental libraries that show up from time to time.

COWS Global Variables

Global variables are declared globally just like functions, and can be declared in any order.  Variables are initialized to an empty string.  Be careful not to declare a global variable twice!  You define a global variable in the format:

(variable variable-name variable-name ... )
	
An example:

Þ	(variable a hello junk)				allocates globals a, hello, and junk.

COWS Special Forms

COWS has four special forms.  Special forms look like functions, but they're not quite, in that they may take other functions or variables as arguments, not just values.  Special forms are complex to write interpreters for and add considerably to the syntax of a language, so COWS has just four of them:

set		Sets variables.  
		Returns: value
		
		Format:  (set variable value)
		
		Examples:
			Þ	(set a 100)			
				sets a to 100
			Þ	(set b "hello")		
				sets b to hello

if		Provides if-then-else control.  test-value must return a t or f.
		Returns:  result of either then-function or else-function.
		
		Format: (if test-value then-function)
		Format: (if test-value then-function else-function)
		
		Examples:
			Þ	(if (> 100 a) (print "okay"))
				if 100 > a, print okay, otherwise do nothing.
			Þ	(if (= 1 a) (print "yes!") (+ a 100))
				if a is 1, then print yes!, otherwise add 100 to a.

while	Provides while-do control.  test-value must return a t or f. Repeatedly 
			calls test-value and optionally function until test-value returns f.
		Returns:  result of test-value.
		
		Format: (while test-value)
		Format: (while test-value function)
		
		Examples
			Þ	(while (< 100 (set a (+ a 1))))
			adds 1 to a until it equals or is higher than 100
			Þ	(while (> 100 (set a (- a 10))) (print a))
			subtracts 10 from a and prints a until a is less than or equal to 100

for		Provides for-next looping.  
		Returns:  variable's value
		
		Format:  (for variable start-value stop-value step-value loop-function)
		
		Examples
			Þ	(for a 1 100 1 (print a))
			prints numbers 1 to 100.
			Þ	(for a 100 0 -2 (print a))
			prints even numbers from 100 down to 0