[Commit] nickle/doc/tutorial/advanced concurrency.sgml,NONE,1.1 continuations.sgml,NONE,1.1 copying.sgml,NONE,1.1 exceptions.sgml,NONE,1.1 namespaces.sgml,NONE,1.1

Bart Massey commit@keithp.com
Fri, 23 May 2003 16:49:01 -0700


Committed by: bart

Update of /local/src/CVS/nickle/doc/tutorial/advanced
In directory home.keithp.com:/tmp/cvs-serv15809/doc/tutorial/advanced

Added Files:
	concurrency.sgml continuations.sgml copying.sgml 
	exceptions.sgml namespaces.sgml 
Log Message:
docbook version of Nickle tutorial



--- NEW FILE: concurrency.sgml ---
<sect1><title>Threads and Mutual Exclusion in Nickle</title>

<sect2><title>Basic threading</title>
<para>
Threads provide concurrent processing of calculations.
They are created with the <literal>fork</literal> operator, which spawns a child thread to evaluate its argument and returns it as a variable of the first-class type <literal>thread</literal>:
</para>
<itemizedlist>
<listitem><para>fork <literal>expr</literal></para></listitem>
</itemizedlist>
<para>
The thread it returns is typically stored like this:
<informalexample><screen>
thread t = fork x!;
</screen></informalexample>
</para>
<para>
In the above example, <literal>fork</literal> immediately returns a thread, which is stored in <literal>t</literal>.
That thread will calculate the factorial of <literal>x</literal> in the background while the program continues; when the calculation is finished it will block and wait for the parent thread (the one that forked it) to kill, join, or otherwise recognize it.
</para>
<para>
<emphasis>Threads share names</emphasis>; if a thread changes the value of a variable, that change will occur in the other threads as well.
See Mutual exclusion below.
</para>
</sect2>

<sect2><title>Thread functions</title>
<para>
The builtin namespace Thread has functions for manipulating threads once they have been forked.
</para>

<sect3><title>Kill</title>
<itemizedlist>
<listitem><para>int kill ( thread t, ... )</para></listitem>
</itemizedlist>
<para>
Kills the threads it takes as arguments, regardless of whether or not they are finished, and returns the number of threads successfully killed. 
</para>
</sect3>

<sect3><title>Join</title>
<itemizedlist>
<listitem><para>poly join ( thread t )</para></listitem>
</itemizedlist>
<para>
Waits for thread <literal>t</literal> to finish and returns the value of its expression.
This is how to get the value back out of a thread.
Once joined, the thread will dissappear.
For example,
<informalexample><screen>
thread t = fork 1000!;
# something else...
printf("1000! = %d\n",Thread::join(t));
</screen></informalexample>
</para>
<para>
will execute 'something else' while <literal>t</literal> runs, then wait for it to complete and print out its value.
</para>
</sect3>

<sect3><title>Current</title>
<itemizedlist>
<listitem><para>thread current ( )</para></listitem>
</itemizedlist>
<para>
Returns the currently running thread. Note that things such as <literal>kill(current())</literal> and <literal>join(current())</literal> are allowed, although the former merely exits and the latter hangs forever; watch out for these errors.
</para>
</sect3>

<sect3><title>Priorities</title>
<itemizedlist>
<listitem><para>int set_priority ( thread t, int i )</para></listitem>
<listitem><para>int get_priority ( thread t )</para></listitem>
</itemizedlist>
<para>
Priorities determine how runtime is divided among threads; a thread with higher priority will always run before one with a lower priority.
<literal>set_priority</literal> sets the priority of <literal>t</literal> to <literal>i</literal> and returns the new priority.
<literal>get_priority</literal> returns the priority of thread <literal>t</literal>.
</para>
</sect3>

</sect2>

<sect2><title>Mutual exclusion</title>
<para>
Consider the following situation:
<informalexample><screen>
import Thread;

void function para() {
	printf("My next statement will be false.\n");
}

void function dox() {
	printf("My previous statement was true.\n");
}

thread t = fork para();
thread s = fork dox();
join(t);
join(s);
</screen></informalexample>
</para>
<para>
When run, this prints out the less than clear message
<informalexample><screen>
MMyy  nperxetv isotuast esmteantte mweinltl  wbaes  ftarlusee..
</screen></informalexample>
</para>
<para>
Why? Because the two threads are running simultaneously and take turns printing out their messages; the result is that they are interleaved unreadably.
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:
</para>

<sect3><title>New</title>
<itemizedlist>
<listitem><para>mutex new ( )</para></listitem>
</itemizedlist>
<para>
Creates a new mutex and returns it.
</para>
</sect3>

<sect3><title>Acquire</title>
<itemizedlist>
<listitem><para>bool acquire ( mutex m )</para></listitem>
</itemizedlist>
<para>
<literal>acquire</literal> blocks until <literal>m</literal> 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 <literal>try_acquire</literal> that returns false immediately rather than blocking if <literal>m</literal> is in use, but it is deprecated.
</para>
</sect3>

<sect3><title>Release</title>
<itemizedlist>
<listitem><para>void release ( mutex m )</para></listitem>
</itemizedlist>
<para>
When the thread which owns a mutex leaves the conflicting section of code, it should call release to free it for the next thread to acquire it.
</para>
</sect3>

<sect3><title>Owner</title>
<itemizedlist>
<listitem><para>mutex_owner owner ( mutex m )</para></listitem>
</itemizedlist>
<para>
Returns the owner of <literal>m</literal>: either the thread which currently owns it or null if it is free.
</para>
</sect3>

</sect2>

<sect2><title>An example</title>
<para>
This is how the example above might work with mutual exclusion:
<informalexample><screen>
import Mutex;
import Thread;

mutex m = new();

void function para() {
	acquire(m);
	printf("My next statement will be false.\n");
	release(m);
}

void function dox() {
	acquire(m);
	printf("My previous statement was true.\n");
	release(m);
}

thread t = fork para();
thread s = fork dox();
join(t);
	join(s);
</screen></informalexample>
</para>
<para>
This prints out, as expected,
<informalexample><screen>
My next statement will be false.
My previous statement was true.
</screen></informalexample>
</para>
</sect2>

<sect2><title>Semaphores</title>
<para>
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.
</para>

<sect3><title>New</title>
<para>
Semaphores are created with <literal>new</literal>, which is unlike <literal>Mutex::new</literal> in that it takes an argument: the number of threads it will run simultaneously.
</para>
<itemizedlist>
<listitem><para>semaphore new ( int c )</para></listitem>
</itemizedlist>
</sect3>

<sect3><title>Wait and Signal</title>
<para>
Just as Mutexes are <literal>acquire</literal>d and <literal>release</literal>d, threads <literal>wait</literal> on semaphores and <literal>signal</literal> them when finished.
</para>
<itemizedlist>
<listitem><para>void wait ( semaphore s )</para></listitem>
<listitem><para>void signal ( semaphore s )</para></listitem>
</itemizedlist>
<para>
<literal>wait</literal> merely decrements the count of <literal>s</literal>, which starts with the initial value specified by <literal>new</literal>.
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 <literal>signal</literal>, which increments the count of <literal>s</literal> and wakes up another thread if any are waiting.
</sect3>

<sect3><title>Negative initial counts</title>
<para>
If <literal>new</literal> 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 <literal>c</literal> threads will block, and the <literal>c</literal>+1th will execute.
</para>
</sect3>

<sect3><title>Why semaphores?</title>
<para>
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.
</para>
</sect3>

<sect3><title>Be careful</title>
<para>
Semaphores, unlike mutexes, are very error-prone.
They are not <literal>owned</literal>, 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:
<informalexample><screen>
> 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)
> 
</screen></informalexample>
</para>
<para>
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.
</para>
</sect3>

</sect2>

</sect1>

--- NEW FILE: continuations.sgml ---
<sect1><title>Nickle Continuations</title>
<para>
Arbitrary flow control is accomplished in Nickle with first-class continuations and the functions <literal>setjmp</literal> and <literal>longjmp</literal>.
These are similar to those in C, but without restrictions on the target.
</para>
<itemizedlist>
<listitem><para>poly setjmp ( continuation *c, poly retval )</para></listitem>
<listitem><para>void lomgjmp ( continuation c, poly retval )</para></listitem>
</itemizedlist>
<para>
Setjmp saves the state of the program, including program counter and names in scope, in <literal>c</literal> and returns <literal>retval</literal>.
</para>
<para>
Longjmp returns <literal>retval</literal> <emphasis>from the setjmp that set <literal>c</literal></emphasis>.
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.
</para>
<para>
Continuations are often used to implement control structures that do not exist in the language, interpreters, and escaping from recursive algorithms.
For example, the following is a simple binary tree search that uses continuations to jump directly to the top instead of returning up each branch once the result is found.
<informalexample><screen><![CDATA[
typedef tree;

typedef struct {
	int key;
	poly data;
	&poly left, right;
} tree;

void function search ( tree t, int i, &continuation c ) {
	if ( i < t.key && ! is_void ( t.left ) )
		search ( t.left, i, &c );
	else if ( i > t.key && ! is_void ( t.right ) )
		search ( t.right, i, &c );
	else if ( i == t.key )
		longjmp ( c, t.data );
}

tree t = { key = 2, data = "blah", left = reference ( <> ), right = reference ( <> ) };

continuation 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 );
	}
]]></screen></informalexample>
</para>
<para>
This is a pretty normal binary tree search, but notice how it is run: a continuation is set; if setjmp returns &lt;&gt; (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.
</para>
<para>
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.
</para>
<para>
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.
</para>
</sect1>

--- NEW FILE: copying.sgml ---
<sect1><title>Copy Semantics and Garbage Collection</title>

<sect2><title>Copy by value</title>
<para>
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:
<informalexample><screen>
> int[*] foo = { 1, 2, 3 };
> int[*] bar = foo;
> foo[2] = 4;
> foo
[3] {1, 2, 4}
</screen></informalexample>
</para>
<para>
What will <literal>bar[2]</literal> be?
<informalexample><screen>
> bar
[3] {1, 2, 3}
</screen></informalexample>
</para>
<para>
Since assignment is by-value, bar has its own values--it is unchanged.
Also consider function arguments:
<informalexample><screen>
> string s = "hello, world"; 
> (void func(string s) { s = "foobar"; printf("%s\n",s); })(s);
foobar
</screen></informalexample>
</para>
<para>
Does <literal>s</literal> still have its original value, or "foobar"?
Since the function was modifying a copy--which was passed by-value--<literal>s</literal> will be unchanged.
<informalexample><screen>
> s
"hello, world"
</screen></informalexample>
</para>
<para>
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:
<informalexample><screen><![CDATA[
> string s = "hello, world";
> (void func(&string s) { s = "foobar"; printf("%s\n",s); })(&s);
foobar
> s
"foobar"
]]></screen></informalexample>
</para>
<para>
Notice that <literal>s</literal> was changed; it was passed as a reference (&amp;string).
See the section on Variables for a discussion of references.
</para>
</sect2>

<sect2><title>Garbage collection</title>
<para>
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.
</para>
<para>
In short, everything is by-value, and Nickle takes care of allocation and deallocation.
</para>
</sect2>

<sect2><title>Type checking and subtyping</title>
<para>
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.
</para>
<para>
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:
<informalexample><screen><![CDATA[
> int i = 1;
> rational r = i;
> i = r/3;
Unhandled exception "invalid_argument" at <stdin>:8
        (1/3)
        0
        "Incompatible types in assignment"
]]></screen></informalexample>
</para>
<para>
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.
</para>
<para>
A similar check occurs with structs.
If one struct's elements are a subset of another's, it may take that value.
For example,
<informalexample><screen><![CDATA[
> 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"
]]></screen></informalexample>
</para>
<para>
Since <literal>just_i</literal> is a subtype of <literal>i_and_s</literal> (it has <literal>i</literal> but not <literal>s</literal>), the assignment to <literal>i</literal> from <literal>is</literal> worked.
However, attempting to assign to <literal>is</literal> from a <literal>just_i</literal> failed, because it did not have an <literal>s</literal> to copy over.
</para>
<para>
Finally, in assignments of one function to another, the following must be the case:
</para>
<itemizedlist>
<listitem><para>
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.
</para></listitem>
<listitem><para>
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.
</para></listitem>
</itemizedlist>
</sect2>

</sect1>

--- NEW FILE: exceptions.sgml ---
<sect1><title>Nickle Exceptions</title>
<para>
Nickle has first-class exceptions for error handling and quick escapes from recursive algorithms.
A number of exceptions are builtin to Nickle that it throws for various errors, including:
</para>
<itemizedlist>
<listitem><para>exception uninitialized_value(string msg) - Attempt to use an uninitialized value.</para></listitem>
<listitem><para>exception invalid_argument(string msg,int arg,poly val) - The <literal>arg</literal>th argument to a builtin function had invalid value <literal>val</literal>.</para></listitem>
<listitem><para>exception readonly_box(string msg,poly val) - Attempt to change the value of a read-only quantity to <literal>val</literal>.</para></listitem>
<listitem><para>exception invalid_array_bounds(string msg,poly a,poly i) - Attempt to access array <literal>a</literal> at index <literal>i</literal> is out of bounds.</para></listitem>
<listitem><para>exception divide_by_zero(string msg,real num,real den) - Attempt to divide <literal>num</literal> by <literal>den</literal> when <literal>den</literal> is zero.</para></listitem>
<listitem><para>exception invalid_struct_member(string msg,poly struct,string name) - Attempt to refer to member <literal>name</literal> of the object <literal>struct</literal>, which does not exist.</para></listitem>
<listitem><para>exception invalid_binop_values(string msg,poly arg1,poly arg2) - Attempt to evaluate a binary operator with arguments <literal>arg1</literal> and <literal>arg2</literal>, where at least one of these values is invalid.</para></listitem>
<listitem><para>exception invalid_unop_values(string msg,poly arg) - Attempt to evaluate a unary operator with invalid argument <literal>arg</literal>.</para></listitem>
</itemizedlist>
<para>
The following syntax may be used to declare a new exception:
</para>
<itemizedlist>
<listitem><para>exception <replaceable>name</replaceable> ( <replaceable>type</replaceable> <replaceable>name</replaceable>, ... )</para></listitem>
</itemizedlist>
<para>
For example,
<informalexample><screen>
exception my_exception ( string msg, int a, int b, int c );
</screen></informalexample>
</para>

<sect2><title>Raise</title>
<itemizedlist>
<listitem><para>raise <replaceable>name</replaceable> ( <replaceable>value</replaceable>, ... )</para></listitem>
</itemizedlist>
<para>
Raises the named exception with the given arguments, e.g.
<informalexample><screen>
raise my_exception ( "message", 0, 1, 2 );
</screen></informalexample>
</para>
<para>
Execution is broken and <literal>my_exception</literal> travels up the stack until it is caught by a try-catch block or it reaches the top level, where it prints an error message such as:
<informalexample><screen>
Unhandled exception "my_exception"
	3
	2
	1
	"message"
</screen></informalexample>
</para>
</sect2>

<sect2><title>Try - catch</title>
<itemizedlist>
<listitem><para>try <replaceable>statement</replaceable></para></listitem>
<listitem><para>catch <replaceable>name</replaceable> ( <replaceable>type</replaceable> <replaceable>name</replaceable>, ... ) { <replaceable>statement-list</replaceable> }</para></listitem>
</itemizedlist>
<para>
<literal>try</literal> executes <replaceable>statement</replaceable>; if it raises an exception whose name matches that of a succeeding <literal>catch</literal> block, the arguments are placed in the names specified and the associated <replaceable>statement-list</replaceable> is executed.
Control continues after the catch without continuing up the stack; if further propagation is desired, <replaceable>statement-list</replaceable> should re-raise the exception.
Any number of catch blocks may be associated with a try statement.
For example:
<informalexample><screen>
exception my_exception(string msg,int a,int b,int c);

try raise my_exception("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);
}
</screen></informalexample>
</para>
<para>
This example tries to execute a function that raises an exception; since that exception matches the catch block, "blah", 1, 2, and 3 (the arguments) are put into <literal>msg</literal>, <literal>a</literal>, <literal>b</literal>, and <literal>c</literal> and the statement list is executed, which in this case merely prints out the arguments received and continues:
<informalexample><screen>
blah: exception successfully caught (1,2,3).
</screen></informalexample>
</para>
</sect2>

<sect2><title>Twixt</title>
<para>
Nickle does not provide a <literal>finally</literal> clause to a <literal>try-catch</literal>.
In order to ensure the order of some expressions, it provides <literal>twixt</literal> (See the section on Statements).
For example,
<informalexample><screen>
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);
}
</screen></informalexample>
Will produce the output:
<informalexample><screen>
entering twixt...leaving twixt.
blah: exception successfully caught (1,2,3).
</screen></informalexample>
</para>
<para>
Notice the order of the printed messages: <literal>twixt</literal> finished up before the exception was handled by the <literal>catch</literal>.
This is an elegant way to accomplish something that should be done finally, in this case printing the message "leaving twixt" for demonstration.
</para>
</sect2>

</sect1>

--- NEW FILE: namespaces.sgml ---
<sect1><title>Nickle Namespaces</title>
<para>
Namespaces collect related variable and function names and allow control over visibility.
A number of Nickle builtins are gathered into builtin namespaces that may be used.
The following builtin namespaces have sections in this tutorial:
</para>
<itemizedlist>
<listitem><para>Math - Useful mathematical functions.</para></listitem>
<listitem><para>File - File input/output with the 'file' type.</para></listitem>
<listitem><para>Thread - Concurrent processing.</para></listitem>
<listitem><para>Semaphore and Mutex - Synchronization of threads.</para></listitem>
<listitem><para>String - Useful functions for strings.</para></listitem>
</itemizedlist>
<para>
An example namespace might be declared like this:
<informalexample><screen>
namespace Example {

	int blah = 1;
	public int a = 0;

	int function bar(int a) {
		...
	}
	
	protected int function foo(int a) {
		...
	}

}
</screen></informalexample>
</para>
<para>
The keyword <literal>namespace</literal> 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. <literal>public</literal> or <literal>protected</literal> defines how visible they will be outside the namespace.
The namespace itself may be preceeded by publication information, <emphasis>but this has no bearing on the names within the namespace</emphasis>; it defines the visibility of the name of the namespace.
If the example above had been declared
<informalexample><screen>
protected namespace Example {
	...
}
</screen></informalexample>
Then the names within <literal>Example</literal> would have the same visibility as always, but <literal>Example</literal> 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.
</para>

<sect2><title>Extend</title>
<itemizedlist>
<listitem><para>extend namespace <replaceable>name</replaceable> {
<replaceable>statement-list</replaceable> }</para></listitem>
</itemizedlist>
<para>
Names may be added to a namespace after it is initially defined with the <literal>extend</literal> command.
The namespace <literal>name</literal> is reopened and the new <literal>statement-list</literal> is added to the previous ones.
For example,
<informalexample><screen>
extend namespace Example {
	string[*] greeting = [2]{ "hello", "world" };
}
</screen></informalexample>
</para>
<para>
Adds <literal>greeting</literal> to the names already defined in <literal>Example</literal>.
</para>
</sect2>

<sect2><title>Peering inside</title>
<itemizedlist>
<listitem><para><replaceable>namespace</replaceable>::<replaceable>name</replaceable></para></listitem>
<listitem><para>import <replaceable>namespace</replaceable></para></listitem>
</itemizedlist>
<para>
The <literal>::</literal> operator refers to a <replaceable>name</replaceable>, which is in <replaceable>namespace</replaceable>, analogously to a structure dereference.
If <replaceable>name</replaceable> also refers to a namespace, its names too are visible this way.
Either <literal>protected</literal> or <literal>public</literal> names are visible in this way.
</para>
<para>
An <literal>import</literal> statement brings all the public names in <replaceable>namespace</replaceable> into scope, overshadowing conflicting names.
Thereafter, those names may be used normally.
</para>
<para>
A variable is declared with one of three visibilities that defines how it is visible outside its namespace:
</para>
<itemizedlist>
<listitem><para>"public" may be seen outside with <literal>::</literal> or imported</para></listitem>
<listitem><para>"protected" may be seen outside with <literal>::</literal> but not imported</para></listitem>
<listitem><para>if neither is specified, it may not be seen outside at all</para></listitem>
</itemizedlist>
<para>
Thus, in our example namespace <literal>Example</literal>:
</para>
<itemizedlist>
<listitem><para><literal>blah</literal>, <literal>bar</literal>, and <literal>greeting</literal> have no visibility specified and may only be used inside <literal>Example</literal>.</para></listitem>
<listitem><para>both <literal>a</literal> (which is public) and <literal>foo</literal> (which is protected) may be seen with <literal>::</literal>.</para></listitem>
<listitem><para>an <literal>import</literal> will only bring <literal>a</literal> into scope, as it is the only name that is public.</para></listitem>
</itemizedlist>
</sect2>

</sect1>