[Commit] nickle-www/tutorial copying.html,NONE,1.1 io.html,NONE,1.1 tour.html,NONE,1.1 basics.html,1.9,1.10 continuations.html,1.5,1.6 control.html,1.8,1.9 exceptions.html,1.7,1.8 expr.html,1.9,1.10 funcs.html,1.1,1.2 index.html,1.13,1.14 math.html,1.3,1.4 namespaces.html,1.7,1.8 string.html,1.3,1.4 threads.html,1.9,1.10 types.html,1.12,1.13 builtins.html,1.5,NONE file.html,1.4,NONE

commit@keithp.com commit@keithp.com
Fri, 23 May 2003 16:26:19 -0700


Committed by: p186

Update of /local/src/CVS/nickle-www/tutorial
In directory home.keithp.com:/tmp/cvs-serv15408

Modified Files:
	basics.html continuations.html control.html exceptions.html 
	expr.html funcs.html index.html math.html namespaces.html 
	string.html threads.html types.html 
Added Files:
	copying.html io.html tour.html 
Removed Files:
	builtins.html file.html 
Log Message:
Restructured builtins. Major edits to other sections.


--- NEW FILE: copying.html ---
<html>
<head>
<title>Copy Semantics and Garbage Collection</title>
</head>
<body>

<h2 align="center">
<img align="middle" src="../buffalo_nickel_1913s_t1_obv_small.jpg" hspace=5>
Copy Semantics and Garbage Collection
<img align="middle" src="../buffalo_nickel_1913s_t1_rev_small.jpg" hspace=5>
</h2>

<p>
<h2>Copy by value</h2>
In Nickle, assignment, argument passing, and definitions--in short everything
involving the values of variables--are all by-value. Nickle avoids the weird
C-isms, like being by-value except for arrays and strings. Everything is
copied. Consider the following example:
<pre>
> int[*] foo = { 1, 2, 3 };
> int[*] bar = foo;
> foo[2] = 4;
> foo
[3] {1, 2, 4}
</pre>
What will <i>bar[2]</i> be?
<pre>
> bar
[3] {1, 2, 3}
</pre>
Since assignment is by-value, bar has its own values--it is unchanged.
Also consider function arguments:
<pre>
> string s = "hello, world"; 
> (void func(string s) { s = "foobar"; printf("%s\n",s); })(s);
foobar
</pre>
Does <i>s</i> still have its original value, or "foobar"? Since the function was
modifying a copy--which was passed by-value--<i>s</i> will be unchanged.
<pre>
> s
"hello, world"
</pre>

<p>
What if you want to pass something by reference? Nickle has a reference type to
accomplish just that. (You could also use pointers, but references are The Right
Way. Anyway, pointers may eventually be removed from the language in preference
to references.) For example, to reimplement the example above using references:
<pre>
> string s = "hello, world";
> (void func(&amp;string s) { s = "foobar"; printf("%s\n",s); })(&amp;s);
foobar
> s
"foobar"
</pre>
Notice that <i>s</i> was changed; it was passed as a reference (&amp;string). See
the section on Variables for a discussion of references.

<p>
<h2>Garbage collection</h2>
But if all those strings and arrays are copied entirely every time a function is
called or an assignment made, won't there be a lot of unused, unreferenceable
memory lying around? No. Nickle is fully garbage-collected; when a value no
longer has any names, it is freed. This is invisible to the user/programmer, who
need not worry about allocation, deallocation, or any other aspects of their
assignments and argument passing.

<p>
In short, everything is by-value, and Nickle takes care of allocation and
deallocation.

<p>
<h2>Type checking and subtyping</h2>
Type checking in Nickle is a combination of compile-time and runtime checking.
At compile-time, Nickle will ensure that all assignments, argument passing, and
other copying situations are sane, for instance that no strings are being
assigned to integers. It will let some errors through if it cannot be sure they
are errors. For instance, variables of type 'poly' can hold any type; at
compile-time, nothing is ruled out, but this does not mean you can't break
typing at run-time.

<p>
At runtime, Nickle makes sure all assignments are actually valid. It does so by
determining if one type is a subtype of the other, i.e. if the set of all values
that can fit in it also fit into the other. As a concrete example:
<pre>
> int i = 1;
> rational r = i;
> i = r/3;
Unhandled exception "invalid_argument" at <stdin>:8
        (1/3)
        0
        "Incompatible types in assignment"
</pre>
The int can hold the integer value 1 without difficulty, because they are the
same type. The rational can accept the same value because integers are a subset
of rationals. However, attempting to assign a rational (1/3) to the integer
raises an exception. This demonstrates that int is a subtype of rational;
conversely, rational is the supertype of int. A variable can take on a value
from any of its subtypes, but not from its supertypes--and if the two values do
not share a sub/supertype relationship, they will not get pass the compile-time
checker.

<p>
A similar check occurs with structs. If one struct's elements are a subset of
another's, it may take that value. For example,
<pre>
> typedef struct { int i; string s; } i_and_s;
> typedef struct { int i; } just_i;
> i_and_s is = { i=2, s="hello" };
> just_i i = is;   
> just_i ji = { i=2 };
> is = ji;
Unhandled exception "invalid_argument" at <stdin>:17
        {i = 2}
        0
        "Incompatible types in assignment"
</pre>
Since 'just_i' is a subtype of 'i_and_s' (it has <i>i</i> but not <i>s</i>), the
assignment to <i>i</i> from <i>is</i> worked. However, attempting to assign to
<i>is</i> from a 'just_i' failed, because it did not have an <i>s</i> to copy
over.

<p>
Finally, in assignments of one function to another, the following must be the
case:
<ul>
<li>The arguments of the right-side function must be able to be assigned to
those of the left-side function. In other words, that on the left must accept a
subset of the arguments of that on the right.
<li>The return type of the left-side function must be able to be assigned to
that of the right-side function. In other words, its value should be usable
anywhere that of the one on the right could be used.
</ul>

</body>
</html>

--- NEW FILE: io.html ---
<html>
<head>
<title>Input and Output</title>
</head>
<body>

<h2 align="center">
<img align="middle" src="../1866_nickel_obv_small.jpg" hspace=5>
Input and Output
<img align="middle" src="../1866_nickel_rev_small.jpg" hspace=5>
</h2>

<p>
Input and output in Nickle are mostly accomplished through the File builtin
namespace; some top-level builtins refer to those functions. Nickle's input and
output are modeled, as much of the language is, on C, but many changes have been
made.

<p>
<h2>Opening and closing files</h2>
The functions in the File namespace use the 'file' primitive type to describe
filehandles. Three are predefined, with their usual meanings: stdin, stdout, and
stderr. For many functions in File, there is a top-level builtin which assumes
one of these standard streams. Other files may be read and written by opening
them:
<ul>
<li>file open(string path, string mode)
</ul>
The first string gives the path to the file to be opened; the second is one of:
<ul>
<li>"r" to open read-only, starting at the beginning of the file.
<li>"r+" to open read-write, starting at the beginning of the file.
<li>"w" to create or truncate the file and open write-only.
<li>"w+" to create or truncate the file and open read-write.
<li>"a" to open write-only, appending to the end of the file.
<li>"a+" to open read-write, appending to the end of the file.
</ul>
If successful, a filehandle will be returned that can then be used.

<p>
Nickle can also open pipes to other programs, reading or writing to their
stdouts or stdins; these are also treated as 'file's, and the difference is
transparent to the functions that manipulate them. Pipes are opened with 'pipe'
rather than 'open'; otherwise they are identical.
<ul>
<li>file pipe(string path, string[*] argv, string mode)
</ul>
The first string refers to the program to be run; <i>argv</i> is an array of the
arguments to pass to it. By convention, <i>argv[0]</i> should be the name of the
program. Finally, <i>mode</i> is one of those for 'open'; reading from the pipe
reads from the program's stdout, and writing to the pipe writes to the program's
stdin. For example,
<pre>
$ nickle
> string[*] args = {"-a"};
> file ls = File::pipe ( "ls", args, "r" );
> do printf ( "%s\n", File::fgets ( ls ) );
+ while ( ! File::end ( ls ) );
bin
man
nickle
share
</pre>

<p>
When a file is no longer needed, it should be closed.
<ul>
<li>void close(file f)
</ul>
<pre>
> File::close ( ls );
</pre>

<p>
<h2>Flush</h2>
Output written to a file is not immediately written, but buffered until an
appropriate time. Ordinarily, this is not noticed; if, however, it is important
to know that all buffers have been written to a file, they can be flushed:
<ul>
<li>void flush (file f)
</ul>


<p>
<h2>End</h2>
Returns true if the file is at end-of-file, otherwise returns false.
<ul>
<li>bool end (file f)
</ul>


<p>
<h2>Characters and strings</h2>
Individual characters can be read and written using 'getc, 'getchar', 'putc'
and 'putchar'.
<ul>
<li>int getc(file f)
<li>int getchar()
<li>int putc(int c,file f)
<li>void putchar(int c)
</ul>

<p>
A character can be pushed back onto the stream with 'ungetc' or 'ungetchar'.
<ul>
<li>int ungetc(int c, file f)
<li>int ungetchar(int c)
</ul>

<p>
Strings can be read, a line at a time, using 'fgets' and 'gets'.
<ul>
<li>string fgets(file f)
<li>string gets()
</ul>

<p>
All of these are like their C counterparts, with the exception noted in the
following section.

<p>
<h2>Unicode and characters vs. bytes</h2>
Unicode is a standard for representing characters, like ASCII. However, Unicode
is designed to be able to support a much larger range of characters; in fact,
every character in every alphabet worldwide. It is optimized so standard ASCII
characters retain their ASCII codes, and characters are not larger than they
have to be. Because of its advantages, and the possibility that it may become
more standard than ASCII, and because there is no reason not to, Nickle reads
and writes Unicode. This is entirely transparent to the user/programmer.

<p>
However, there is one situation in which the programmer will notice
(disregarding the case where the programmer finds himself typing on a Sanskrit
keyboard): extended characters that do not stand for themselves the same in
ASCII and Unicode are <b>not</b> one byte long; they can be as many as four for
the really obscure characters. Therefore, unlike in C, <b>characters cannot be
counted on to be the same as bytes</b>. For this reason, Nickle provides the
following functions:
<ul>
<li>int putb(int c,file f)
<li>int getb(file f)
<li>int ungetb(file f)
</ul>
These operate the same as 'putc', 'getc', and 'ungetc', but will always read
or write one byte at a time, regardless of character representation.

<p>
<h2>Formatted I/O</h2>
Nickle provides functions such as 'printf', 'sprintf', and 'scanf' to perform
formatted input and output. These functions perform like their C counterparts,
with the following exceptions:
<ul>
<li>The precision of a field in the format string may be specified to be '-',
which means infinite precision.
<li>The %g format specifier requires a number, and prints it in the best way
possible. For example:
<pre>
> printf("%g %g %g\n", 1, 1/3, sqrt(2));
1 0.{3} 1.414213562373095
</pre>
<li>The %v format specifier will attempt to find the best way to print whatever
value it is given. This is a great way to print polys whose types will not be
known ahead of time.
<pre>
> printf("%v %v %v\n", 1/3, "hello", fork 4!);
(1/3) "hello" %38
</pre>
Notice that it can even figure out difficult things like the thread returned by
'fork'.
</ul>

<p>
<h2>At the top level</h2>
Many functions in the File namespace have counterparts builtin at the top level;
these do not need to be imported from File because they are automatically
present.
<ul>
<li>int printf(string fmt, poly args...) is the same as 'File::printf'.
<li>string printf(string fmt, poly args...) is the same as 'File::sprintf'.
<li>void putchar(int c) is the same as 'File::putchar'.
</ul>

<p>
File also contains a namespace called FileGlobals, which is automatically
imported. It contains the following definitions:
<pre>
public int scanf (string format, *poly args...)
{
	return File::vfscanf (stdin, format, args);
}

public int vscanf (string format, (*poly)[*] args)
{
	return File::vfscanf (stdin, format, args);
}    

public string gets ()
{
	return File::fgets (stdin);
}

public int getchar ()
{
	return File::getc (stdin);
}

public void ungetchar (int ch)
{
	File::ungetc (ch, stdin);
}
</pre>
Thus, 'scanf', 'vscanf', 'gets', 'getchar', and 'ungetchar' call the appropriate
functions in File and return their results. The other functions in File must be
imported as normal.

</body>
</html>

--- NEW FILE: tour.html ---
<html>
<head>
<title>Nickle Tour</title>
</head>
<body>

<h2 align="center">
<img align="middle" src="../1909_nickel_obverse_small.JPG" hspace=5>
Nickle Tour
<img align="middle" src="../1909_nickel_reverse_small.JPG" hspace=5>
</h2>

<p>
The following is an example Nickle session, interspersed with comments in
<i>italics</i>.

<p>
<pre>
$ nickle
</pre>

<p>
<i>
Arithmetic works as expected, with a rich set of operators.
</i>

<p>
<pre>
> 1+1
2
> 2 ** (2+2)
16
> 5!
120
</pre>

<p>
<i>
Rationals are represented exactly, but printed in decimal. Math is done with
infinite precision. Notice that integer division (//) is different from
rational division (/). Nickle provides some conveniences, such as '.' denoting
the last value printed.
</i>

<p>
<pre>
> 1/3
0.{3}
> . * 3
1
> 1 // 3
0
</pre>

<p>
<i>
Variables can be declared implicitly at the top level, as well as explicitly
with type. The results of statements are not printed; terminating an expression
with a semicolon makes it a simple statement. C-like control structures may
also be used at the top level; the '+' prompt indicates an incomplete line to
be continued.
</i>

<p>
<pre>
> x = .
0
> int y = x;
> ++y;
> for(int i=0; i<25; ++i)
+   x+=0;
> x
0
> for(int i=1; i<9; i+=2)
+   x+=i;
> x
16
</pre>

<p>
<i>
When performing square roots, Nickle will stay exact when possible. If the
result is irrational, however, it will be stored as an inexact real.
Imprecision is contagious; if a rational operator combines an imprecise
variable with a precise one, the result will be imprecise.
</i>

<p>
<pre>
> sqrt(x)
4
> sqrt(2)
1.414213562373095
> .**2
2
> sqrt(5)
2.236067977499789
> .**2
4.999999999999999
> ./5
0.999999999999999
</pre>

<p>
<i>
Functions can also be typed at the top level. Since functions, as most things,
are first-class in Nickle, they may be declared and assigned as below.
</i>

<p>
<pre>
> real foo(real x,real y) {
+   return x*y;
+ }
> foo(2,3)
6
> foo(4,2)
8
> real(real,real) bar = foo;
> bar(4,2)
8
> 
</pre>

<p>
<i>
Nickle is gauranteed never to dump core; it has a simple yet powerful
exception system it uses to handle all errors. An unhandled exception leads to
the debugger, which uses a '-' prompt. The debugger can be used to trace the
stack, move up and down on it, and check values of variables.
</i>

<p>
<pre>
> (-1) ** (1/2) 
Unhandled exception "invalid_argument" at /u/p186/share/nickle/math.5c:13
        "sqrt of negative number"
        0
        -1
- trace
    raise invalid_argument ("sqrt of negative number", 0, v);
sqrt (-1)
    result = sqrt (a);
pow (-1, (1/2))
    -1 ** (1 / 2)
- done
> quit
$
</pre>

<p>
<i>
Large chunks of code can be placed in a seperate text file and loaded when
needed. The 'print' command can be used to inspect variables, functions,
namespaces, and other names; 'import' brings the names in a namespace into
scope. The '::' operator can be used to view those names without importing
them. (These can also be used with several namespaces built in to Nickle,
such as Math and File.)
</i>

<p>
<pre>
$ nickle
> load "cribbage.5c"
> print Cribbage
namespace Cribbage {
    public void handprint (int[*] hand);
    public int scorehand (int[*] hand);
}
> print Cribbage::handprint
public void handprint (int[*] hand)
{
    printf ("hand { ");
    for (int i = 0; i < dim (hand); ++i)
        switch (hand[i]) {
        case 1:
            printf ("A ");
            break;
        case 11:
            printf ("J ");
            break;
        case 12:
            printf ("Q ");
            break;
        case 13:
            printf ("K ");
            break;
        default:
            printf ("%d ", hand[i]);
        }
    printf ("} ");
}
> import Cribbage;
> int[5] hand = { 7, 8, 12, 10, 5 };
> handprint(hand); printf(" has %d points.\n", scorehand(hand));
hand { 7 8 Q 10 5 }  has 6 points.
> quit
$ 
</pre>

</body>
</html>

Index: basics.html
===================================================================
RCS file: /local/src/CVS/nickle-www/tutorial/basics.html,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- basics.html	11 Apr 2003 23:25:42 -0000	1.9
+++ basics.html	23 May 2003 23:26:16 -0000	1.10
@@ -16,9 +16,8 @@
 	nickle [-f FILE] [-l FILE] [-e ...] [SCRIPT ...]
 </pre>
 <ul>
-<li>With -f, Nickle evaluates <i>file</i> on startup. Nickle always loads a
-.nicklerc if it exists in the directory specified by NICKLERC or in your home
-directory.
+<li>With -f, Nickle evaluates <i>file</i> on startup. Nickle usually loads a
+.nicklerc in addition.
 <li>-l is similar to -f, but Nickle will search for <i>file</i> in the
 directories in NICKLEPATH.
 <li>With -e, Nickle evaluates the remainder of the line as an expression.

Index: continuations.html
===================================================================
RCS file: /local/src/CVS/nickle-www/tutorial/continuations.html,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- continuations.html	18 Apr 2003 22:08:58 -0000	1.5
+++ continuations.html	23 May 2003 23:26:16 -0000	1.6
@@ -26,9 +26,10 @@
 scope, in <i>c</i> and returns <i>retval</i>.
 
 <p>
-Longjmp returns <i>retval</i> from the setjmp which set <i>c</i>. There are two
-distinctions from this jump and the initial call to setjmp: the return value may
-differ, and variables which have changed are not reset to old values.
+Longjmp returns <i>retval</i> <b>from the setjmp that set <i>c</i></b>. There
+can be two distinctions from this jump and the initial call to setjmp: the
+return value may differ, and variables that have changed retain their new
+values.
 
 <p>
 Continuations are often used to implement control structures that do not exist
@@ -57,13 +58,42 @@
 	tree t = { key = 2, data = "blah", left = reference ( <> ), right = reference ( <> ) };
 
 	continuation c;
-	poly p = setjmp ( &c, <> );
+	int i = 0;
+	{
+		poly p = setjmp ( &c, <> );
+		++i;
+		printf ( "I have been here %d times.\n", i );
 
-	if ( is_void ( p ) )
-		search ( t, 2, &c );
-	else
-		printf ( "value = %g\n", p );
+		if ( is_void ( p ) )
+			search ( t, 2, &c );
+		else
+			printf ( "value = %g\n", p );
+	}
 </pre>
+
+<p>
+This is a pretty normal binary tree search, but notice how it is run: a
+continuation is set; if setjmp returns <> (which it will the first time), a
+value is searched for (this is a pretty degenerate example with only one node).
+If an actual value is returned, it must be from the longjmp in search, and the
+value is printed; a message is printed to emphasize that setjmp returns twice.
+This optimizes the return from what can be a very deeply nested search.
+
+<p>
+Notice that the last part of the code is inside curly braces. This is legal, of
+course, but ordinarily not very useful. It is used in this case to get around a
+slight flaw in Nickle: currently, each top-level command is executed in its own
+thread. Thus when longjmp tries to return from the setjmp, that thread has
+already finished and the program exits. By placing those statements in curly
+braces, they will all be executed in the same thread and setjmp will still exist
+for longjmp to find.
+
+<p>
+This sort of escape from a nested search is also commonly done with exceptions,
+raising one when the value is found and catching it at the top, passing the
+value as an argument to the exception. Actually, that method is more common
+because of its simplicity, but this example was done using continuations to
+demonstrate them.
 
 </body>
 </html>

Index: control.html
===================================================================
RCS file: /local/src/CVS/nickle-www/tutorial/control.html,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- control.html	11 Apr 2003 23:25:42 -0000	1.8
+++ control.html	23 May 2003 23:26:16 -0000	1.9
@@ -31,13 +31,11 @@
 <h2>Conditionals</h2>
 <ul>
 <li>if ( <i>expr</i> ) <i>statement</i>
-<li>twixt ( <i>expr</i>; <i>expr</i> ) <i>statement</i>
 <li>else <i>statement</i>
 </ul>
-
-'If' and 'twixt' can be used to execute a section of code only under some
-condition. If <i>expr</i> is true, <i>statement</i> is executed; otherwise
-control skips over it. For example:
+'If' and is used to execute a section of code only under some condition: If
+<i>expr</i> is true, <i>statement</i> is executed; otherwise control skips over
+it. For example:
 <pre>
 	if ( x == 0 )
 		printf ( "x is zero.\n" );
@@ -45,40 +43,17 @@
 In this case, the message will be printed only if x is zero.
 
 <p>
-'Twixt', similarly to 'if', executes <i>statement</i> only if the first
-<i>expr</i> is true. If <i>statement</i> is executed, the second <i>expr</i> is
-evaluated after it. That order is gauranteed - even if <i>statement</i> throws
-an exception or 'break's out of the 'twixt', the second <i>expr</i> will be
-evaluated.
-
-<p>
-'Twixt' is useful in locked operations where the statement should only be
-executed if a lock was successfully acquired and the lock must be released
-afterward:
-<pre>
-	twixt ( get_lock ( ); release_lock ( ) )
-		locked_operation ( );
-</pre>
-
-<p>
 'Else' allows for a choice if the condition fails. It executes its
-<i>statement</i> if the most recent 'if' or 'twixt' did not. Options might be
-added to the above examples with 'else':
+<i>statement</i> if the most recent 'if' or 'twixt' did not. For example,
 <pre>
 	if ( x == 0 )
 		printf ( "x is zero.\n" );
 	else
 		printf ( "x is not zero.\n" );
-
-
-	twixt ( get_lock ( ); release_lock ( ) )
-		locked_operation ( );
-	else
-		printf ( "failed to acquire lock.\n" );
 </pre>
 
 <p>
-More than one option may be present by nesting further 'if's in 'else'
+More than one option may be presented by nesting further 'if's in 'else'
 statements like this:
 <pre>
 	if ( x == 0 )
@@ -90,24 +65,43 @@
 </pre>
 
 <p>
-<h2>Switch</h2>
+<h2>Twixt</h2>
 <ul>
-<li>switch ( <i>expr</i> ) { case <i>expr</i>: <i>statement-list</i> ... default: <i>statement-list</i> }
+<li>twixt ( <i>expr</i>; <i>expr</i> ) <i>statement</i>
 </ul>
-
-'Switch' is an alternative to nesting 'if' and 'else' statements as above. It is
-simpler than 'if' statements and therefore not as flexible; however, it is
-better in many situations, if only for readability.
+'Twixt', like 'if', executes <i>statement</i> only if the first <i>expr</i> is
+true. If <i>statement</i> is executed, the second <i>expr</i> is evaluated
+after it. <b>That order is gauranteed</b> - even if <i>statement</i> throws
+an exception or 'long_jmp's out of the 'twixt', the second <i>expr</i> will be
+evaluated. 'Twixt' is useful in locked operations where the statement should
+only be executed if a lock was successfully acquired and the lock must be
+released afterward:
+<pre>
+	twixt ( get_lock ( ); release_lock ( ) )
+		locked_operation ( );
+</pre>
 
 <p>
-Control jumps to the first 'case' whose <i>expr</i> evaluates to the same value
-as the <i>expr</i> at the top (unlike in C, these values do not have to be
-integers). The optional case 'default' matches any value. If nothing is matched
-and there is no 'default', control skips the 'switch' entirely.
+'Else' statements may bind to 'twixt's as well as 'if's, providing choices
+such as:
+<pre>
+	twixt ( get_lock ( ); release_lock ( ) )
+		locked_operation ( );
+	else
+		printf ( "failed to acquire lock.\n" );
+</pre>
 
 <p>
-This example prints out a number to the screen, replacing it by a letter as
-though it were a poker card:
+<h2>Switch</h2>
+<ul>
+<li>switch ( <i>expr</i> ) { case <i>expr</i>: <i>statement-list</i> ... default: <i>statement-list</i> }
+</ul>
+Control jumps to the first 'case' whose <i>expr</i> evaluates to the same value
+as the <i>expr</i> at the top.Unlike in C, these values do not have to be
+integers, or even constant. The optional case 'default' matches any value. If
+nothing is matched and there is no 'default', control skips the 'switch'
+entirely. This example prints out a number to the screen, replacing it by a
+letter as though it were a poker card:
 <pre>
 	switch ( x ) {
 		case 1:
@@ -121,6 +115,7 @@
 			break;
 		case 13:
 			printf ( "K\n" );	/* king */
+			break;
 		default:
 			printf ( "%d\n", x );	/* numeric */
 			break;
@@ -178,13 +173,28 @@
 			printf ( "%d\n", u.a );
 			break;
 		case b:
-			printf( "%s\n", u.b );
+			printf ( "%s\n", u.b );
 			break;
 	}
 </pre>
 In this case, it prints 'hello'.
 
 <p>
+An additional name may follow that of a case; the union's value will be
+available inside the case by that name. The switch above could have been
+written:
+<pre>
+	union switch ( u ) {
+		case a num:
+			printf ( "%d\n", num );
+			break;
+		case b str:
+			printf ( "%s\n", str );
+			break;
+	}
+</pre>
+
+<p>
 <h2>Loops</h2>
 <ul>
 <li>while ( <i>expr</i> ) <i>statement</i>
@@ -246,10 +256,9 @@
 will be evaluated first.
 
 <p>
-'Break' leaves the nearest surrounding 'do-while', 'while', 'for', 'switch' or
-'twixt' statement by jumping to its end. The iterative statement of a for loop
-will not be evaluated, but the second <i>expr</i> of a 'twixt' statement will
-be.
+'Break' leaves the nearest surrounding 'do-while', 'while', 'for', or 'switch'
+statement by jumping to its end. The iterative statement of a for loop will
+not be evaluated.
 
 <p>
 'Return' returns from the nearest surrounding function with value <i>expr</i>.

Index: exceptions.html
===================================================================
RCS file: /local/src/CVS/nickle-www/tutorial/exceptions.html,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- exceptions.html	18 Apr 2003 22:06:10 -0000	1.7
+++ exceptions.html	23 May 2003 23:26:16 -0000	1.8
@@ -15,25 +15,24 @@
 recursive algorithms. A number of exceptions are builtin to Nickle that it
 throws for various errors, including:
 <ul>
-<li>exception uninitialized_value(string msg)
-<br>Attempt to use an uninitialized value.
-<li>exception invalid_argument(string msg,int arg,poly val)
-<br>The <i>arg</i>th argument to a builtin function had invalid value
-<i>val</i>.
-<li>exception readonly_box(string msg,poly val)
-<br>Attempt to change the value of a read-only quantity to <i>val</i>.
-<li>exception invalid_array_bounds(string msg,poly a,poly i)
-<br>Attempt to access array <i>a</i> at index <i>i</i> is out of bounds.
-<li>exception divide_by_zero(string msg,real num,real den)
-<br>Attempt to divide <i>num</i> by <i>den</i> when <i>den</i> is zero.
-<li>exception invalid_struct_member(string msg,poly struct,string name)
-<br>Attempt to refer to member <i>name</i> of the object <i>struct</i>, which
-does not exist.
-<li>exception invalid_binop_values(string msg,poly arg1,poly arg2)
-<br>Attempt to evaluate a binary operator with arguments <i>arg1</i> and
+<li>exception uninitialized_value(string msg) - Attempt to use an uninitialized
+value.
+<li>exception invalid_argument(string msg,int arg,poly val) - The <i>arg</i>th
+argument to a builtin function had invalid value <i>val</i>.
+<li>exception readonly_box(string msg,poly val) - Attempt to change the value of
+a read-only quantity to <i>val</i>.
+<li>exception invalid_array_bounds(string msg,poly a,poly i) - Attempt to access
+array <i>a</i> at index <i>i</i> is out of bounds.
+<li>exception divide_by_zero(string msg,real num,real den) - Attempt to divide
+<i>num</i> by <i>den</i> when <i>den</i> is zero.
+<li>exception invalid_struct_member(string msg,poly struct,string name) -
+Attempt to refer to member <i>name</i> of the object <i>struct</i>, which does
+not exist.
+<li>exception invalid_binop_values(string msg,poly arg1,poly arg2) - Attempt to
+evaluate a binary operator with arguments <i>arg1</i> and
 <i>arg2</i>, where at least one of these values is invalid.
-<li>exception invalid_unop_values(string msg,poly arg)
-<br>Attempt to evaluate a unary operator with invalid argument <i>arg</i>.
+<li>exception invalid_unop_values(string msg,poly arg) - Attempt to evaluate a
+unary operator with invalid argument <i>arg</i>.
 </ul>
 
 <p>
@@ -78,8 +77,6 @@
 continues after the 'catch' without continuing up the stack; if further
 propagation is desired, <i>statement-list</i> should re-raise the exception.
 Any number of 'catch' blocks may be associated with a 'try' statement.
-
-<p>
 For example:
 <pre>
 	exception my_exception(string msg,int a,int b,int c);
@@ -97,6 +94,34 @@
 <pre>
 	blah: exception successfully caught (1,2,3).
 </pre>
+
+<p>
+<h2>Twixt</h2>
+Nickle does not provide a 'finally' clause to a 'try-catch'. In order to ensure
+the order of some expressions, it provides 'twixt' (See the section on
+Statements). For example,
+<pre>
+	exception my_exception(string msg, int a, int b, int c);
+
+	void foo(string msg, int a, int b, int c) {
+		twixt(printf("entering twixt..."); printf("leaving twixt.\n"))
+			raise my_exception(msg, a, b, c);
+	}
+
+	try foo("blah", 1, 2, 3);
+	catch my_exception(string msg,int a,int b,int c) {
+		printf("%s: exception successfully caught (%d,%d,%d).\n",msg,a,b,c);
+	}
+</pre>
+Will produce the output:
+<pre>
+	entering twixt...leaving twixt.
+	blah: exception successfully caught (1,2,3).
+</pre>
+Notice the order of the printed messages: 'twixt' finished up before the
+exception was handled by the 'catch'. This is an elegant way to accomplish
+something that should be done finally, in this case printing the message
+"leaving twixt" for demonstration.
 
 </body>
 </html>

Index: expr.html
===================================================================
RCS file: /local/src/CVS/nickle-www/tutorial/expr.html,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- expr.html	11 Apr 2003 23:25:42 -0000	1.9
+++ expr.html	23 May 2003 23:26:16 -0000	1.10
@@ -15,15 +15,24 @@
 
 <p>
 <h2>Variable declarations</h2>
+Variable declarations are expressions in Nickle; the value of a declaration is
+the value of the last variable with an initialization expression. For example,
 <pre>
-	<i>declaration</i> <i>name</i> [ = <i>expr</i> ] { , <i>name</i> = <i>value</i> ... }
+	> int val;
+	> val = (int i=2, j=3);
+	> print val
+	global int val = 3;
+</pre>
+If no initialization expressions are present, it is an error to use the value
+of the expression.
+<pre>
+	> val = (int i,j);
+	Unhandled exception "uninitialized_value" at <stdin>:73
+	        "Uninitialized value"
 </pre>
-Variable declarations are expressions in Nickle; the value of a declaration is the
-value of the last variable with an initialization expression.  If no initialization
-expressions are present, it is an error to use the value of the expression.
 
 <p>
-Because they are expressions, declarations can be used in contructs like:
+Because they are expressions, declarations can be used in contructs such as:
 <pre>
 	for (int i = 0; i < 10; i++)
 	{
@@ -33,14 +42,13 @@
 
 <p>
 <h2>Anonymous function declarations</h2>
+Functions may be declared anonymously and used immediately, e.g.
 <pre>
-	[<i>type</i>] func ( [<i>type</i>] <i>name</i> { , [<i>type</i>] <i>name</i> ... } [ "..." ] ) {
-		<i>statement</i>; { <i>statement</i> ... }
-	}
+	> (int func ( int a, int b ) { return a + b; })(2,3)
+	5
 </pre>
-This function may be used immediately, or stored for later use.  Any context
-available to the function at definition time will be available whenever it
-is executed.  See Storage classes in the section on Variables.
+Any context available to the function at definition time will be available
+whenever it is executed.  See Storage classes in the section on Variables.
 
 <p>
 <h2>Binary operators</h2>
@@ -148,13 +156,25 @@
 
 <p>
 <h3>Rational constants</h3>
-Rational numbers are the combination of four parts:
+Rational constants are the combination of an integer part, a mantissa with an
+initial and repeating part, and an exponent. All of these pieces are optional,
+but at least one of the parts (other than the exponent) must be present. If no
+fractional part is given, the resulting type of the value is int rather than
+rational. Some examples:
 <pre>
-	<i>integer-part</i> . <i>initial-part</i> { <i>repeating-part</i> } e <i>exponent-part</i>
+	> 12
+	12
+	> 12.5
+	12.5
+	> .34
+	0.34
+	> .{56}
+	0.{56}
+	> .34e3
+	340
+	> .{56}e12
+	565656565656.{56}
 </pre>
-All of these pieces are optional, but at least one of the parts (other than
-the exponent) must be present.  If no fractional part is given, the resulting
-type of the value is int rather than rational.
 
 <p>
 <h3>String constants</h3>
@@ -212,10 +232,12 @@
 <pre>
 	expr, expr
 </pre>
-
-<p>
 Evaluates each expression in turn, the resulting value is that of
-the right hand expression.
+the right hand expression. For example,
+<pre>
+	> 1+2, 5!, 3**4, 27/3
+	9
+</pre>
 
 </body>
 </html>

Index: funcs.html
===================================================================
RCS file: /local/src/CVS/nickle-www/tutorial/funcs.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- funcs.html	11 Apr 2003 23:25:42 -0000	1.1
+++ funcs.html	23 May 2003 23:26:16 -0000	1.2
@@ -11,14 +11,9 @@
 </h2>
 
 <p>
-Functions in Nickle are first-class. They can be declared and used anonymously,
-or by name. A function can be declared thus:
-<pre>
-	[type] func [name] ( [type] name [, ...] [...] ) { statement [, ...] }
-</pre>
-For example,
+An example function might be declared like this:
 <pre>
-	int func gcf ( int a, int b ) {
+	int gcf ( int a, int b ) {
 		int f = 1;
 		for ( int i = 2; i <= abs ( a ) && i <= abs ( b ); ++i )
 			while ( ( a // f ) % i == 0 && ( b // f ) % i == 0 )
@@ -26,44 +21,54 @@
 		return f;
 	}
 </pre>
+First comes the return type of the function, then the function name, then the
+list of arguments (with types), and finally the statement list in curly braces.
+If any types are left off, Nickle assumes 'poly'. In any case, all typechecking
+is done at runtime.
 
 <p>
-If any types are left off, Nickle assumes poly and performs run-time type
-checking. A function can take any number of arguments. The final argument
-may be succeeded by an ellipses (...) to indicate an arbitrary, variable
-number of succeeding arguments, each of the type of the final argument.
-
-<p>
-Functions can be assigned like function pointers in C, although not pointers:
+A function can take any number of arguments. The final argument may be
+succeeded by an ellipses (...) to indicate an arbitrary, variable number of
+succeeding arguments, each of the type of the final argument; the last
+argument takes on a list value to store them.
 <pre>
-	int(int,int) a = gcf;
+	...
+	> print sum
+	int sum (int a, int b ...)
+	{
+	    for (int i = 0; i < dim (b); ++i)
+		a += b[i];
+	    return a;
+	}
+	> sum(1,2)
+	3
+	> sum(4)
+	4
+	> sum(1,2,4,6)
+	13
 </pre>
 
 <p>
 Functions are called as in C, with their name followed by argument values in
-parenthesis:
+parentheses:
 <pre>
-	a ( 21, 7 );	/* 3 */
+	foo ( "hello", 7.2 );
 </pre>
 
 <p>
-The use a function anonymously, you may either declare it and store it in
-a function variable:
+Since they are first class, functions can be assigned:
 <pre>
-	int(int,int) a = int func ( int a, int b ) {
-		int f = 1;
-		for ( int i = 2; i <= abs ( a ) && i <= abs ( b ); ++i )
-			while ( ( a // f ) % i == 0 && ( b // f ) % i == 0 )
-				f *= i;
-		return f;
-	}
-
-	a ( 21, 7 );	/* 3 */
+	int(int,int) a = gcf;
 </pre>
-or use it immediately:
+See the section on Copy semantics for details on what functions may be assigned
+to each other.
+
+<p>
+Functions may also be declared and used anonymously:
 <pre>
 	(int func ( int a, int b ) { return a + b; })(2,3);	/* 5 */
 </pre>
+Replacing the function name with the keyword 'func' indicates its anonymity.
 
 </body>
 </html>

Index: index.html
===================================================================
RCS file: /local/src/CVS/nickle-www/tutorial/index.html,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- index.html	18 Apr 2003 22:06:10 -0000	1.13
+++ index.html	23 May 2003 23:26:16 -0000	1.14
@@ -11,15 +11,18 @@
 </h2>
 
 <p>
-<h3><center>by Robert Burgess</center></h3>
+<center><h3>by Robert Burgess<br>and Keith Packard</h3></center>
 
 <p>
 <h2>Tutorial Sections</h2>
 
 <p>
+<h3><a href='tour.html'>The Nickle Tour</a></h3>
+
+<p>
 <h3>Introduction</h3>
 <ul>
-<li><a href='basics.html'>Basics.</a> Invoking Nickle, etc.
+<li><a href='basics.html'>Basics.</a> Invoking Nickle, and top-level commands.
 <li><a href='types.html'>Variables.</a> Datatypes, variables, and values in Nickle.
 <li><a href='expr.html'>Expressions.</a> Operators and expressions in Nickle.
 <li><a href='control.html'>Statements.</a> Control statements in Nickle.
@@ -29,15 +32,15 @@
 <p>
 <h3>Builtins</h3>
 <ul>
-<li><a href='builtins.html'>Builtins.</a> A very incomplete list of useful builtin functions and names.
-<li><a href='math.html'>Math.</a> A very incomplete list of useful names and functions in the builtin Math namespace.
-<li><a href='file.html'>File.</a> A very incomplete list of useful functions in the builtin File namespace.
-<li><a href='string.html'>String.</a> An incomplete list of useful functions in the builtin String namespace.
+<li><a href='io.html'>I/O.</a> Input and output.
+<li><a href='math.html'>Math.</a> Math in Nickle.
+<li><a href='string.html'>Strings.</a> Some useful information about strings.
 </ul>
 
 <p>
 <h3>Advanced topics</h3>
 <ul>
+<li><a href='copying.html'>Copying.</a> Copy semantics and garbage collection.
 <li><a href='exceptions.html'>Exceptions.</a> Error handling with exceptions.
 <li><a href='namespaces.html'>Namespaces.</a> Grouping and visibility control with namespaces.
 <li><a href='threads.html'>Concurrency.</a> Concurrency with threads and semaphores.

Index: math.html
===================================================================
RCS file: /local/src/CVS/nickle-www/tutorial/math.html,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- math.html	11 Apr 2003 23:25:43 -0000	1.3
+++ math.html	23 May 2003 23:26:16 -0000	1.4
@@ -11,35 +11,40 @@
 </h2>
 
 <p>
-<h3>Constants</h3>
-<ul>
-<li>protected real e
-<li>real pi
-<li>real pi_value ( int prec )
-</ul>
-'Pi' and 'e' define the usual constants (3.14..., 2.72...); 'e' is protected
-and must be called 'Math::e' to allow ordinary use of the name 'e'. Arbitrary
-precision in pi may be found with 'pi_value'. For example,
+<h2>Numbers</h2>
+The three numeric types in Nickle--int, rational, and real--have a hierarchical
+relationship. Specifically, int is a subset of rational, which is a subset of
+real. Ints and rationals are stored internally in infinite precision, and
+printed as precisely as possible (rationals with repeating portions are
+represented with curly braces to allow more precision in printing; see the
+section on Expressions for a discussion of rational constants). Reals are
+stored in finite, floating-point representations. The mantissa defaults to 256
+bits long, but this number can be changed.
 
 <p>
-<h3>Radicals</h3>
-<ul>
-<li>real sqrt ( real v )
-<li>real cbrt ( real v )
-</ul>
-The square or cube root of <i>v</i>, respectively.
-<pre>
-	$ nickle
-	> sqrt ( 4 )
-	2
-	> sqrt ( 2 )
-	1.414213562373095
-	> cbrt ( -27 )
-	-3
-	> cbrt ( 81 )
-	4.326748710922225
-	> 
-</pre>
+Whenever performing calculations, Nickle will keep numbers in their most
+specific format. For example, the result of '4/2' is an int, because although
+the result (2) is a rational, it is also an int, and int is more specific.
+Similarly, reals are not always in imprecise floating representation; if they
+are known exactly, they will be represented as rationals or ints. Nickle will
+only produce imprecise reals when it has to, as in square roots and logarithms.
+
+<p>
+<h2>Operators</h2>
+In order to do the Right Thing for a desk calculator, Nickle provides several
+operators that are not present in C; these are extremely useful. To force
+division to produce an integer, even if the result would be a rational, use the
+'//' integer divide operator, which always rounds its results to ints. Nickle
+also has an exponentiation operator '**', which behaves correctly for all
+exponents, including negative and fractional. Therefore, sqrt(x) is the same as
+x**.5, and 1/x is the same as x**-1. Finally, it provides a factorial operator
+'!'.
+
+<p>
+<h2>The Math namespace</h2>
+Nickle provides the builtin namespace Math for useful functions such as
+trigonometric functions, logarithms, as well as useful constants such as pi and
+e.
 
 <p>
 <h3>Logarithms</h3>
@@ -48,7 +53,7 @@
 <li>real log10 ( real a )
 <li>real log2 ( real a )
 </ul>
-The logarithm of <i>v</i> in base e, ten, and two, respectively.
+The logarithm of <i>a</i> in base e, ten, and two, respectively.
 <pre>
 	$ nickle
 	> log ( Math::e )
@@ -79,6 +84,15 @@
 	3.141592653589793
 	> 
 </pre>
+
+<p>
+<h3>Constants</h3>
+<ul>
+<li>protected real e
+<li>real pi
+</ul>
+'Pi' and 'e' define the usual constants (3.14..., 2.72...); 'e' is protected
+and must be called 'Math::e' to allow ordinary use of the name 'e'.
 
 </body>
 </html>

Index: namespaces.html
===================================================================
RCS file: /local/src/CVS/nickle-www/tutorial/namespaces.html,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- namespaces.html	18 Apr 2003 22:06:10 -0000	1.7
+++ namespaces.html	23 May 2003 23:26:16 -0000	1.8
@@ -24,16 +24,7 @@
 </ul>
 
 <p>
-The following syntax can be used to declare a new namespace:
-<ul>
-<li><i>desc</i> namespace <i>name</i> { <i>statement-list</i> }
-</ul>
-The names in the namespace are declared and defined in <i>statement-list</i>.
-<i>Desc</i> is the visibility of the namespace's own <i>name</i>, and has no
-affect on the names within the namespace.
-
-<p>
-For example:
+An example namespace might be declared like this:
 <pre>
 	namespace Example {
 	
@@ -50,6 +41,22 @@
 
 	}
 </pre>
+The keyword 'namespace' is followed by the name of the namespace and a list of
+statements that declare names in the namespace. The publication of those
+declarations, e.g. 'public' or 'protected', defines how visible they will be
+outside the namespace. The namespace itself may be preceeded by publication
+information, <b>but this has no bearing on the names within the namespace</b>;
+it defines the visibility of the name of the namespace. If the example above
+had been declared
+<pre>
+	protected namespace Example {
+		...
+	}
+</pre>
+Then the names within 'Example' would have the same visibility as always, but
+'Example' itself would be protected in whatever namespace it belongs to. In
+this case, it belongs to the top-level namespace, but namespaces can be nested
+within each other, which makes the visibility of their own names important.
 
 <p>
 <h2>Extend</h2>

Index: string.html
===================================================================
RCS file: /local/src/CVS/nickle-www/tutorial/string.html,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- string.html	11 Apr 2003 23:25:43 -0000	1.3
+++ string.html	23 May 2003 23:26:16 -0000	1.4
@@ -1,17 +1,83 @@
 <html>
 <head>
-<title>String Functions</title>
+<title>Strings</title>
 </head>
 <body>
 
 <h2 align="center">
 <img align="middle" src="../1866_nickel_obv_small.jpg" hspace=5>
-String Functions
+Strings
 <img align="middle" src="../1866_nickel_rev_small.jpg" hspace=5>
 </h2>
 
 <p>
-<h2>Length</h2>
+Unlike in C, strings in Nickle are not arrays of or pointers to individual
+characters. Consistent with its pattern of providing primitive datatypes for
+types for things that make sense (e.g. 'file' instead of integer file handles),
+Nickle provides the 'string' type. This has several interesting differences from
+C-style strings:
+<ul>
+<li>In Nickle, strings are immutable--individual characters may not be changed.
+<li>Strings are, as with everything else, assigned and passed by-value. See the
+section on Copy semantics for details.
+</ul>
+
+<p>
+<h2>Operators</h2>
+Two useful operators have been overloaded to allow sane manipulation of strings:
+'+' and array subscript ('[]').
+
+<p>
+<h3>Subscripting</h3>
+Although they are not arrays of characters, it is often useful to access a
+string a character at a time; the array subscript operator allows this. For
+example:
+<pre>
+> string s = "hello, world";
+> s[0]
+104
+> s[1]
+101
+> s[2]
+108
+> s[3]
+108
+> s[4]
+111
+> 
+</pre>
+Those are the integer representations of each character; they are most likely
+in ASCII, but not necessarily--see the section on Unicode in the I/O section.
+The String namespace provides 'new' to recreate a string from these integer
+character representations, regardless of ASCII or Unicode:
+<ul>
+<li>string new(int c)
+<li>string new(int[*] cv)
+</ul>
+For instance,
+<pre>
+> String::new(s[0])
+"h"
+</pre>
+
+<p>
+<h3>Concatenation</h3>
+On strings, '+' is the concatenation operator. For example,
+<pre>
+> string s = "hello", t = "world"; 
+> s = s + ", ";
+> t += "!";
+> s+t
+"hello, world!"
+</pre>
+
+<p>
+<h2>String namespace</h2>
+In addition, the String namespace provides several useful functions that
+facilitate using strings, including the following.
+
+<p>
+<h3>Length</h3>
 <ul>
 <li>int length ( string s )
 </ul>
@@ -24,23 +90,26 @@
 </pre>
 
 <p>
-<h2>Index</h2>
+<h3>Index</h3>
 <ul>
 <li>int index ( string t, string p )
+<li>int rindex ( string t, string p )
 </ul>
 Returns the index of the first occurence of the substring <i>p</i> in
-<i>t</i>, or -1 if <i>p</i> is not in <i>t</i>. For example,
+<i>t</i>, or -1 if <i>p</i> is not in <i>t</i>; 'rindex' returns the last
+occurence instread. For example,
 <pre>
 	$ nickle
 	> String::index ( "hello, world", "or" ) 
 	8
 	> String::index ( "hello, world", "goodbye" )
 	-1
-	> 
+	> String::rindex ( "hello, world", "o" )
+	8
 </pre>
 
 <p>
-<h2>Substr</h2>
+<h3>Substr</h3>
 <ul>
 <li>string substr ( string s, int i, int l )
 </ul>

Index: threads.html
===================================================================
RCS file: /local/src/CVS/nickle-www/tutorial/threads.html,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- threads.html	18 Apr 2003 22:06:10 -0000	1.9
+++ threads.html	23 May 2003 23:26:16 -0000	1.10
@@ -114,8 +114,6 @@
 <p>
 Why? Because the two threads are running simultaneously and take turns printing
 out their messages; the result is that they are interleaved unreadably.
-
-<p>
 The solution is in the builtin namespace Mutex. A mutex is a first-class object
 which threads can use to coordinate conflicting sections of code. Mutex defines
 the following functions:
@@ -131,13 +129,12 @@
 <h3>Acquire</h3>
 <ul>
 <li>bool acquire ( mutex m )
-<li>bool try_acquire ( mutex m )
 </ul>
-'Acquire' blocks until <i>m</i> is free, then locks it and returns true.
-'Try_acquire' does the same, but always returns immediately; if <i>m</i> is
-busy it returns false rather than blocking. At the top of the conflicting
-code, each thread should acquire the mutex; since only one at a time can
-have it, they will take turns executing.
+'Acquire' blocks until <i>m</i> is free, then locks it and returns true. At the
+top of the conflicting code, each thread should acquire the mutex; since only
+one at a time can have it, they will take turns executing. There is also a
+'try_acquire' that returns false immediately rather than blocking if <i>m</i> is
+in use, but it is deprecated.
 
 <p>
 <h3>Release</h3>
@@ -186,6 +183,82 @@
 	My next statement will be false.
 	My previous statement was true.
 </pre>
+
+<p>
+<h2>Semaphores</h2>
+Nickle also has counting semaphores, implemented in the Semaphore namespace.
+Semaphores are similar to mutexes, but have some number of threads that may run
+that isn't necessarily one, as it is with mutexes. A semaphore with a count of
+one behaves just like a mutex.
+
+<p>
+<h3>New</h3>
+Semaphores are created with 'new', which is unlike Mutex::new in that it takes
+an argument: the number of threads it will run simultaneously.
+<ul>
+<li>semaphore new ( int c )
+</ul>
+
+<p>
+<h3>Wait and Signal</h3>
+Just as Mutexes are 'acquire'd and 'release'd, threads 'wait' on semaphores and
+'signal' them when finished.
+<ul>
+<li>void wait ( semaphore s )
+<li>void signal ( semaphore s )
+</ul>
+
+<p>
+'Wait' merely decrements the count of <i>s</i>, which starts with the initial
+value specified by 'new'. If the count, after the decrement, is positive, the
+thread continues to run; if it is negative, it blocks until the count becomes
+positive again. This will occur when one of the running threads calls 'signal',
+which increments the count of <i>s</i> and wakes up another thread if any are
+waiting.
+
+<p>
+<h3>Negative initial counts</h3>
+If 'new' is called with a negative initial count, much of the meaning of the
+semaphore is inverted. The count now refers to the number of threads that must
+wait until one can execute; that is, the first <i>c</i> threads will block, and
+the <i>c</i>+1th will execute.
+
+<p>
+<h3>Why semaphores?</h3>
+Semaphores are useful in situations where several threads can run
+simultaneously, but not more than a certain number. They would be great, for
+instance, to work in a licensing system, where each thread needs some command,
+but only a certain number may run at a given time.
+
+<p>
+<h3>Be careful</h3>
+Semaphores, unlike mutexes, are very error-prone. They are not 'owned', in the
+sense that mutexes are, and therefore do not check what threads are signalling
+or waiting on them. Thus, situations like this are possible:
+<pre>
+> import Semaphore;
+> semaphore s = new(3);
+> s  
+semaphore 1 (3);
+> wait(s);       
+> s
+semaphore 1 (2);
+> wait(s);
+> s
+semaphore 1 (1);
+> s
+semaphore 1 (1)
+> for(int i=0; i<100; ++i)
++   signal(s);
+> s
+semaphore 1 (101)
+> wait(s)
+> s
+semaphore 1 (100)
+> 
+</pre>
+Therefore, code must be written carefully so that threads do not signal the
+semaphore more than once, and only once they have waited on it.
 
 </body>
 </html>

Index: types.html
===================================================================
RCS file: /local/src/CVS/nickle-www/tutorial/types.html,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- types.html	11 Apr 2003 23:25:43 -0000	1.12
+++ types.html	23 May 2003 23:26:16 -0000	1.13
@@ -32,21 +32,51 @@
 <p>
 Int and rational values are represented exactly to arbitrary precision so
 that computations need not be concerned about values out of range or a loss
-of precision during computation.  For example, the value of (1/3 + 2/3) is
-precisely 1, and (10000! + 1 > 10000!) is true.  As rationals are a superset
-of the int, rational values with denominator of 1 are represented as ints.
-This is visible in the implementation through the 'is_int' primitive which
-will return true for such values.  
+of precision during computation. For example,
+<pre>
+	> 1/3 + 2/3 == 1
+	true
+	> 1000! + 1 > 1000!
+	true
+</pre>
+
+<p>
+As rationals are a superset of the int, rational values with denominator of 1
+are represented as ints. The builtin 'is_int' demonstrates this by recognizing
+such rationals as integers:
+<pre>
+	> rational r = 1/3;
+	> is_int(r)   
+	false
+	> is_int(r*3)
+	true
+</pre>
 
 <p>
 Real values are either represented as a precise int or rational value or as
 an imprecise value using a floating point representation with arbitrary
 precision mantissa and exponent values.  Imprecision is a contagious
 property; computation among precise and imprecise values yields an
-imprecise result.  <p> Upward type conversion is handled automatically;
+imprecise result.
+<pre>
+	> real i=3/4, j=sqrt(2);
+	> is_rational(i)
+	true
+	> is_rational(j)
+	false
+	> is_rational(i*j)
+	false
+</pre>
+
+<p> Upward type conversion is handled automatically;
 divide an int by and int and the result is rational.  Downward conversion
 only occurs through builtin functions which convert rational or real values
 to integers.
+<pre>
+	> int i=4, j=2;
+	> is_rational(i/j)
+	true
+</pre>
 
 <p>
 <h3>String datatype</h3>
@@ -57,6 +87,13 @@
 builtin functions accept and return this datatype. Elements of a string are
 accessible as integers by using the array index operators. See the section
 on the builtin namespace String.
+<pre>
+	string foo = "hello";
+	string bar = "world";
+	string msg = foo + ", " + bar;
+
+	printf("%s\n", msg);		/* hello, world */
+</pre>
 
 <p>
 <h3>File datatype</h3>
@@ -66,6 +103,11 @@
 This datatype provides access to the native file system.  Several builtin
 functions accept and return this datatype. See the section on the builtin
 namespace File.
+<pre>
+	file f = open("file", "w");
+	File::fprintf(f, "hello, world!\n");
+	close(f);
+</pre>
 
 <p>
 <h3>Concurrency and control flow datatypes</h3>
@@ -81,6 +123,11 @@
 Threads are created with the 'fork' expression, the result of which is a
 thread value. Mutexes and semaphores are synchronization datatypes. See
 the section on Concurrency and Continuations.
+<pre>
+	thread t = fork 5!;
+	# do stuf...
+	printf("5! = %d\n", join(t));	/* 5! = 120 */
+</pre>
 
 <p>
 Continuations capture the dynamic state of execution in much the same way as
@@ -97,6 +144,24 @@
 type can be used in any circumstance.  Nickle performs full run-time
 typechecking on poly datatypes to ensure that the program doesn't violate
 the type rules.
+<pre>
+	> poly i=3, s="hello\n";
+	> i+3
+	6
+	> s+3		/* can't add string and int */
+	Unhandled exception "invalid_binop_values" at <stdin>:45
+		3
+		"hello\n"
+		"invalid operands"
+	> printf(i)	/* printf expects a string */
+	Unhandled exception "invalid_argument" at <stdin>:47
+		3
+		0
+		"Incompatible argument"
+	> printf(s)
+	hello
+	> 
+</pre>
 
 <p>
 <h3>Void datatype</h3>
@@ -187,11 +252,8 @@
 By these declarations, <i>a</i> and <i>b</i> are of the same type
 (one-dimensional array). The specification of the size of <i>b</i> actually
 has no effect on its declaration but rather on its initialization. See
-Initialization below.
-
-<p>
-Declaring multidimensional arrays in Nickle is different than in C; C provides
-only arrays of arrays while Nickle allows either:
+Initialization below. Declaring multidimensional arrays in Nickle is different
+than in C; C provides only arrays of arrays while Nickle allows either:
 <pre>
 	int[3,3]	array_2d = {};
 	int[3][3]	array_of_arrays = { (int[3]) {} ... };
@@ -214,18 +276,15 @@
 Pointers hold a reference to a separate object; multiple pointers may point
 at the same object and changes to the referenced object are reflected both
 in the underlying object as well as in any other references to the same
-object.
-
-<p>
-While pointers can be used to point at existing storage locations, anonymous
-locations can be created with the reference built-in function; this allows
-for the creation of pointers to existing values without requiring that the
-value be stored in a named object.
+object. While pointers can be used to point at existing storage locations,
+anonymous locations can be created with the reference built-in function; this
+allows for the creation of pointers to existing values without requiring that
+the value be stored in a named object.
 <pre>
 	*int	pointer;
 	int	object;
 
-	pointer = &object;
+	pointer = &amp;object;
 	*pointer = 12;
 
 	printf ("%g\n", object);		/* 12 */
@@ -237,6 +296,43 @@
 </pre>
 
 <p>
+<h3>References</h3>
+References, like pointers, refer to objects. They are unlike pointers, however;
+they are designed to provide for calls by reference in a completely by-value
+language. They may eventually replace pointers altogether. They are declared and
+assigned similarly, but not identically, to pointers:
+<pre>
+	&amp;int ref;
+	int  i;
+
+	i = 3;
+	&amp;ref = &amp;i;
+</pre>
+<i>Ref</i> is declared as a reference to an integer, '&amp;int'. An integer,
+<i>i</i>, is declared and given the value 3. Finally, the assignment carries
+some interesting semantics: the address of the reference is set to the address
+of <i>i</i>. References may also be assigned otherwise anonymous values with
+'reference', e.g.
+<pre>
+	&amp;int foo;
+	&amp;foo = reference ( 3 );
+</pre>
+
+<p>
+References, unlike pointers, need not be dereferenced; they are used exactly as
+any other value. Changing either the value it refers to or the reference itself
+changes both.
+<pre>
+	printf("%g\n", i);	/* 3 */
+	printf("%g\n", ref);	/* 3 */
+
+	++ref;
+
+	printf("%g\n", i);	/* 4 */
+	printf("%g\n", ref);	/* 4 */
+</pre>
+
+<p>
 <h3>Functions</h3>
 Nickle has first-class functions.  These look a lot like function pointers
 in C, but important semantic differences separate the two.  Of course, if
@@ -274,18 +370,17 @@
 <pre>
 	type			/* primitive type */
 	*type			/* pointer to type */
+	&amp;type			/* reference to type */
 	type[*] 		/* array of type */
 	type[*,...]		/* multidimensional array of type */
 	type(type,...)		/* function with type arguments and return value */
 	struct { ... }		/* struct of types */
 	union { ... }		/* union of types */
 	type(type,...)[*]	/* array of functions */
-				/* etc. */
+	/* etc. */
 </pre>
 When <i>type</i> is missing, Nickle uses 'poly' which allows the variable to
-hold data of any type.  A future revision of the language is expected to
-implement parametric type inference which will allow automatic typing of
-such variables.
+hold data of any type. In any case, type is always checked at runtime.
 </ul>
 
 <p>
@@ -325,20 +420,13 @@
 <pre>
 	int[4,4]	a = { { 1, 2 ... }, { 3, 4 ... } ... };
 </pre>
-
-<p>
 This leaves 'a' initialized to an array who's first row is { 1, 2, 2, 2 } and
-subsequent rows are { 3, 4, 4, 4 }.
-
-<p>
-It is an error to use this elipsis notation when the associated type
-specification contains stars instead of expressions for the dimensions of
-the array.
-
-<p>
-Variables need not be completely initialized; arrays can be partially filled
-and structures may have only a subset of their elements initialized.
-Using an uninitialized variable causes a run time exception to be raised.
+subsequent rows are { 3, 4, 4, 4 }. It is an error to use this elipsis notation
+when the associated type specification contains stars instead of expressions
+for the dimensions of the array. Variables need not be completely initialized;
+arrays can be partially filled and structures may have only a subset of their
+elements initialized. Using an uninitialized variable causes a run time
+exception to be raised.
 
 <p>
 <h2>Identifier scope</h2>
@@ -389,7 +477,7 @@
 <pre>
 	*int function foo (int x)
 	{
-		return &x;
+		return &amp;x;
 	}
 
 	*int	a1 = foo (1);
@@ -417,19 +505,13 @@
 	int()	a = incrementer();
 	int()	b = incrementer();
 </pre>
-
-<p>
 A and b refer to functions with separate static state and so the values
 they return form independent sequences.
-
-<p>
 Because static variables are initialized as the function is evaluated and
 not during function execution, any auto variables declared within the
 enclosing function are not accessible.  This is the exception to the lexical
 scoping rules mentioned above.  It is an error to reference auto variables
 in this context.
-
-<p>
 Additionally, any auto variables declared within an initializer
 for a static variable exist in the frame for the static initializer, not for
 the function.
@@ -440,7 +522,7 @@
 		{
 			*z = (*z)!;
 		}
-		static x = ((int y = 7), bar (&y), y);
+		static x = ((int y = 7), bar (&amp;y), y);
 
 		return x;
 	}

--- builtins.html DELETED ---

--- file.html DELETED ---