Rune - flesh out type support
[rune.git] / docs / overview.html
1 <HTML>
2 <HEAD>
3 <TITLE>Rune Language Overview</TITLE>
4 </HEAD>
5 <BODY>
6 <CENTER><H2><B>Rune Language Overview</B></H2></CENTER>
7 <CENTER><H3><B>(c)Copyright 1996-2015, Matthew Dillon</B></H3></CENTER>
8 <P>
9 <H2><B>(I) History</B></H2>
10 <UL>
11     <P>
12     Well, the story of Rune is both short and long.  It's short because I've
13     rarely discussed the language in detail outside of a few friends, and long
14     because my desire to write a language began in the late 1980's after I
15     had learned C and started looking for something better.  Many years later
16     and people will note that I am still a hard-core C programmer, working
17     mainly on the DragonFly kernel code base.  You might think (if you
18     don't know me) that I'd be able to find *something* out there that
19     would satisfy me language-wise, other than C.  But I haven't.
20     <P>
21     For various reasons I have very little love for most of the programming
22     languages out in the world today.  I hate the design-by-committee mess
23     people call C++, I hate the kitchen-sink-control-the-programmer approach
24     taken by Eiffel, the cacophony that is perl, the limited Objective-C,
25     the ever-changing typeless lets-break-everyone-again TCL (though I will
26     admit that, of late, it seems to have settled down.  Still, TCL isn't
27     for me!).  I'm not interested in the politics associated with Java
28     that has destroyed it as a viable programming language, or the wordy
29     semantics and constructs.  (Java is a toy that should never have seen
30     the light of day IMHO).  I don't mind some of the newer mostly interpreted
31     languages but I feel that many are missing things.
32     I have been unenthused with nearly every language I've come across.
33     Languages like Scheme, Python, and Ruby are better, but still don't
34     have the level of flexibility of abstraction that I desire and don't
35     handle locking or threading the way I'd like to see either.
36     <P>
37     I'm a great believer in the concept of a class hierarchy and in
38     object-oriented (or at least object-centric) design, yet as you can
39     see I have done little but write in C in all the intervening time.
40     <P>
41     Of course, another reason I have not switched to a more object-oriented
42     language is simply because every time I try I find myself constantly
43     comparing it to my ideal.
44     <P>
45     Rune is culmination of almost everything I want in a language.
46     <P>
47     Throughout this period, I began thinking of my dream language
48     as "D" in my head, but I was ambivalent about trying to name it that
49     in public.  I finally came up with a great name, "Rune", after running
50     through literally a thousand different possibilities.  I don't care if
51     it's already being used for other things... so is virtually every other
52     interesting word in the dictionary.
53     <P>
54     So why has it taken so long to write Rune?   Well, there are many
55     reasons.  Some of you might remember the 'DICE' system I wrote for
56     the Amiga and sold as shareware in the early 90's.  DICE is a full
57     ANSI-C compiler.  And a preprocessor.  And an assembler.  And a linker.
58     And a full set of standard C libraries.  I wrote it all, for the 68000.
59     Unfortunately this points to a severe character
60     flaw of mine when it comes to me and writing programs... I am a bit of a
61     perfectionist when it comes to my own private work, and other people's
62     work rarely achieves the level of perfection I am comfortable with.
63     I was able to build DICE
64     quickly because the C language standard already existed, as well
65     as standards for all the other necessary pieces, so I just had to
66     start coding it up.  But Rune is a different matter.  With Rune I am 
67     designing the language as well as implementing it, and that amplifies
68     the problem when one has my particular character flaw.
69     <P>
70     Over these many years my language has evolved.  I have added many
71     features and removed many more.  I have written over two dozen drafts
72     of the grammer but it has only been the last five or so years that
73     it's settled down into something I consider to be reasonable.  Another
74     time factor is what I call the 'Dillon' factor.  When I set out to
75     design something I expect to be able to grasp and hold the entirety
76     of the project in my head without external references.  Rune is complex
77     enough that it has taken quite a while to achieve this state of mind.
78     I want to be able to scale simple concepts into extremely sophisticated
79     capabilities.  I hate special cases, so when I set out to write the
80     lexical scanner, the parser, the semantic search code, and the other
81     pieces that make up a language, I expected to get the core written
82     and proven out in a week or less or it was no good.  Needless to say I
83     have had many false starts.  A false start for me typically means wiping
84     the code (rm -rf) in disgust.  The only thing left after a false start is 
85     the memory of what went right and what went wrong, and I used that
86     to begin the next iteration.
87     <P>
88     The reason I do things like this is actually quite simple.
89     If I've done the low level pieces correctly
90     the sophisticated pieces wind up being trivial to implement.  I believe,
91     strongly, that getting the core right greatly increases the flexibility
92     of a project and I knew that flexibility would be key in further
93     development of the language once the initial release occured.
94     Whatever time I've apparently wasted getting this far is going to be
95     repaid ten fold over in the future.
96     <P>
97     <B>Well, I finally did it!  I got over the hump and now have something
98     I really like.</B>.
99     I knew I had hit the
100     mark when I looked up from the keyboard one day and realized that I
101     had just implemented variable arguments, constant procedure and operator
102     call optimizations, and default value aggregation for types all in one
103     day without realizing it.  A week later I could actually start
104     writing code in Rune, and a week after that I could actually start
105     writing *sophisticated* code in Rune.  And, as a bonus, the unoptimized
106     interpreter has wound up being pretty damn fast just on its own.
107     It's good enough now that I can simply not worry about it and focus
108     on other issues.  After spending a month coding I set it all aside to
109     catch up on other things, and now I've dusted it off again,
110     found that I still understand all the concepts and all the
111     code (which must mean the code must be pretty good in my view), and I'm
112     going to move forward with the work necessary for the first release.
113     <P>
114     So that's the history in a nutshell.  I've conveniently left out what
115     few discussions I've had with friends and my many attempts to kickstart
116     the process (multiple times, over the years).  In the end it's only the
117     final draft that matters, and this is it.  This is the end of the
118     beginning and the beginning of a new beginning.
119 </UL>
120 <H2><B>(II) Language Features and 'why I did it that way'</B></H2>
121 <UL>
122     <P>
123     Right off the bat I will say that I absolutely can't stand languages
124     that try to implement <I>everything</I>.  Kitchen sink languages tend
125     to be so complex that they wind up being unusable or unreadable or
126     unlearnable or unmaintainable.
127     When a programmer is able to implement some concept
128     ten thousand different ways, you will wind up with ten thousand different
129     implementations and you can shuck any efficient, collaborative
130     development right out the window.
131     I have thought long and hard in regards to which
132     concepts I should include.  Should I have inheritance,
133     multiple-inheritance, subclassing, organization of class hierarchies,
134     and so forth?
135     I've thrown out a lot of concepts as simply not meshing well with the
136     rest of Rune.
137     For example, you will not find traditional multiple-inheritance in Rune.
138     Why?  It's overkill to the point of confusion (kinda like C++ actually).
139     <P>
140     You will find relatively robust in-band exception handling with
141     return-value bypassing, but it is explicitly not supposed to be used
142     for nominal status returns as might be handled when doing non-blocking
143     I/O or EOF handling.
144     <P>
145     You will not find a formal single-root class hierarchy.
146     Been there, done that, stupid idea.
147     Nor will you find complex overloading features.  Rune is designed
148     in a manner that avoids most potential namespace conflicts without
149     over-burdening the programmer with long dotted identifier sequences
150     or complex specifications.  Since most conflicts are naturally avoided
151     in the first place, Rune doesn't need sophisticated overloading or 
152     conflict handling features.  What will you find in Rune?  Read on!
153     <P>
154     * Import mechanism.  Rune uses an import mechanism to collect project
155       files and libraries together into a program.  There is NO include
156       mechanism.  If you import a directory then Rune will locate
157       "$directory/main.d"
158       and import that.  "main.d" then typically imports whatever libraries are
159       required as well as the other project files and provides a <B>main()</B>
160       to start execution of the program.  library-library dependancies are 
161       typically resolved simply by having the library itself import whatever
162       other libraries it needs (and as a welcome side effect this makes 
163       libraries self contained).  Duplicate imports of self-contained entities
164       are allowed and do not result in any significant extra overhead unless 
165       you are really, really stupid.
166     <P>
167     * Semantic search is not class-hierarchical.  Rune locates an identifier
168       through a semantic search based on how you stack and name imports.
169       Within a procedure the semantic search begins in a manner similar to C,
170       where the search checks local declarations within the procedure
171       and then within the current file.  If the identifier cannot be found
172       the semantic search progresses upward through the import hierarchy
173       until it hits the root (of the import hierarchy) -- the original file
174       that kicked the whole thing off in the first place.  There is no object
175       root.  Identifiers are searched level-by-level and can be forward 
176       referenced (Rune makes no distinction between backward and forward
177       references except in one parse-time convenience case).  You can push down
178       into an import, type, or class, by using a dotted sequence of identifiers.
179       For example, if "main.d" imports
180       "File" (file support) and "a.d", "b.d", and "c.d", then code sitting
181       in "c.d" can access the file support library simply with a 
182       construct like <B>File.FILE *fi = ....;</B>.  Rune also includes
183       a mechanism which allows you to push into an import without
184       specifying the import's id, called the
185       <B>import ... as self</B> mechanism.
186       <P>
187       The <B>import ... as self</B> mechanism is typically used only to
188       collect tightly integrated source files together... for example,
189       source files in a subdirectory.  The main system library is typically
190       imported by a project <I>as self</I>, but library imports in general
191       are almost universally named entities rather then <I>self</I>
192       entities in order to avoid namespace conflicts.
193     <P>
194     * Typedefs.  Rune supports typedefs.  Typedefs are used to 'alias' 
195       classes, with or without modification, making them available
196       at mulitple semantic points.  A typedef can be placed anywhere
197       a declaration can be placed:  At the top level, in a <B>class</B>
198       definition, in a procedure... even inside a compound type if you
199       want (though I might call you crazy).  Typedefs are extremely
200       convenient constructs which allow you to short-cut common types
201       to avoid having to specify class paths with lots of dots.  For
202       example, if your project uses <B>File.FILE</B> a lot, you could
203       simply <B>typedef File.FILE FILE;</B> in your project's "main.d"
204       source file and just use <B>FILE</B> in all the project source
205       files it imports.
206       <P>
207       Typedefs can also be used to change default assignments.  For
208       example, <B>typedef myint int a = 4;</B> creates a new type
209       <B>myint</B>.  When you instantiate <B>myint</B> the object will
210       default to a contents of 4 unless you specifically give it another
211       default.
212     <P>
213     * Classes.  Rune supports a class mechanism.  All types except compound
214       types are based on a class somewhere.  This includes core Rune types
215       such as <B>int</B>.  What you know as an <B>int</B> in C serves the
216       same function in Rune but <B>int</B> is actually a class in Rune.
217       Classes contain declarations: typedefs, storage declarations,
218       operators, procedures, and constants.  <B>It is important to note
219       that Rune uses a C-like pass-by-value model.  Rune also supports bounded
220       pointers and so can pass objects by reference, and also suppors passing
221       and returning an object by <I>lvalue</I>.  An <I>lvalue</I> is effectively
222       an object which appears to be passed by value but is actually passed
223       by reference, allowing the procedure to modify it.  <I>lvalue</I> is
224       necessary to implement operators like "++" and "+=".
225       Rune makes no distinction between core classes and
226       user-defined classes.</B>
227     <P>
228     * Subclasses.  Rune supports a subclassing mechanism.  A subclass is 
229       basically a merge of its superclass plus additional declarations
230       and/or refinements of declarations inherited from the superclass.
231       Namespace overloading is explicit.. if you declare something using
232       an identifier that conflicts with a declaration in the superclass
233       and you do not explicitly say that you are refining the superclass
234       declaration, then your declaration will be used by anything you
235       define in your subclass but the 'hidden' declaration in the superclass
236       will be used by anything defined by the superclass.  Rune allows you
237       to refine methods, typedefs, and storage (changing the size of 
238       preexisting storage elements in an object).  However, because I have
239       no wish to force the entire language to be dynamically typed at run
240       time only subclasses which refine procedures and extend existing storage
241       are compatible with dynamically bound reference pointers (see later).
242     <P>
243     * Refinement.  When you subclass a class you can refine declarations
244       made in the superclass.  You can only refine declarations by making
245       them more specific.  For example, if the declaration in the
246       superclass is <B>Integer x = 4;</B> then you could refine it to
247       be <B>int8 x;</B> but you could not refine it to be <B>float x;</B>.
248       You can refine types and default values and you can partially
249       resolve procedure arguments (and/or refine argument and return types).
250       <B>Refinement is an extremely powerful mechanism.  The core library
251       uses refinement to declare all of Numeric's operators in the Numeric
252       superclass using a typedef'd type called 'T'.  The core library then
253       simply refines the typedef T in various subclasses in order to
254       automatically re-form the supeclass operators and procedures into
255       more specific operators -- without having to redeclare the operators
256       or procedures at all.</B>  This means, in effect, that you can write
257       generic procedures in the superclass that operate on declarations
258       defined by the superclass in the context of the subclass.
259       <FONT COLOR="darkgreen">Subclas refinement is one of the most 
260       sophisticated and important features of the Rune language</FONT>.
261       <P>
262       Refinement also works well with <B>method</B> procedures.  These are
263       procedures which execute with an object context called <B>this</B>.
264       If you create a subclass which refines a superclass declaration,
265       and then call an unrefined superclass method, the superclass method
266       will use your refined declaration(s).  Superclass procedures which
267       are overriden by subclass refinement are not automatically called.
268       Instead your refined procedure must use the
269       <B>super.<I>funcname(...)</I></B> mechanism to chain the
270       superclass method.
271     <P>
272     * Pass-by-value and embedded objects.  Rune uses the C pass-by-value
273       and embedded-type model.  In C you can embed one structure inside
274       another.  You can do the same with classes in Rune.  Rune also has what
275       we call an <I>lvalue</I> extension which allows a procedure to
276       enforce a pass-by-reference and/or return-by-reference for an object
277       that is passed to it literally, which Rune operators use to implement
278       variable-modifying behavior (such as <B>++x</B>) and which you will
279       be able to use to for the same purpose.
280     <P>
281     * Forward referenced identifiers.  Rune does not impose many requirements
282       on the ordering of declarations within a file or between files and
283       libraries.  The only thing you cannot do is directly embed classes
284       to form a loop (class A into class B and class B into class A).
285       You can, of course, embed mutual pointers.  Certain identifiers cannot
286       be forward referenced due to being handled at parse time or being used
287       before being initialized in a procedure, but most do not have that
288       restriction.
289     <P>
290     * Bounded pointers.  Rune's interpreter uses bounded pointers.  For
291       example, a pointer into an array can be manipulated with addition
292       and subtraction, just like C.  But Rune will not allow the pointer
293       to be accessed if it goes out of bounds.  Rune also does not allow you
294       to arbitrarily cast pointers from one type to another (XXX ok, it does
295       at the moment, but soon it wont).  You can think of this as
296       C with 'safe' pointers.  Pointers have been given a bad name by C,
297       but pointers are not inherently a bad concept.
298     <P>
299     * Dynamically bound pointers (known as reference types).  In Rune something
300       like 'Frame *x;' represents a pointer to a frame.  A dynamically bound
301       reference is something like 'Frame @x;'.  This creates a pointer object
302       that can be bound to the specified class or any compatible subclass of
303       the specified class at run-time.  You can only access the fields
304       defined by the superclass (Frame in this case) through a reference type,
305       but that's why we have refinement.  Your method calls will call into the
306       version of the procedures refined by the associated subclass, for
307       example.  <B>Reference types are most often used to allow a superclass
308       to define procedures to manage linked lists of the object which mix
309       various subclassed versions of the object.</B>
310     <P>
311     * Automatic zeroing.  Declarations are automatically initialized to zero
312       if not otherwise assigned.  Allocations are always zerod unless
313       explicitly told not to.
314     <P>
315     * There is no union.  Believe me, this is a feature.  I might still
316       wind up adding a union feature later but, so far, I have found that
317       the subclassing mechanism is sufficient to handle situations that
318       would normally use a union in C.  And if the subclassing mechanism
319       is not sufficient, I will <I>make</I> it sufficient.
320     <P>
321     * User-defined operators.  All operators in Rune are physically declared.
322       Even Rune's core operators on integers and other types are declared
323       in the core Rune "sys" library.  You can define your own unary and binary
324       operators and you can use almost any sequence of operatic characters
325       to do it.  Rune imposes one bit of sanity, however.  You cannot specify 
326       the precedence.  The precedence of an operator is fixed based on 
327       the characters making up the operator.  All C-like operators wind
328       up with C-like precedences.  Your own operators will wind up with
329       C-like precedences too, using simple rules defined in the Rune grammer.
330       <P>
331       <FONT COLOR="red">
332       User-defined operators can be emplaced in any class belonging to the
333       arguments you supply to the operator when you use it, and may also be
334       emplaced in your main semantic search path.  So, for example, you
335       cannot add a new operator to the core <B>Integer</B> class but you
336       can certainly add a new operator that operates on various kinds of
337       ints semantically, such as in your <B>main.d</B> module. </FONT>
338     <P>
339     * LValue operators and procedures (deserves separate mention).  An
340       LValue operator is capable of assigning the
341       left hand side as well as returning a result.  The left hand
342       side must be an lvalue.  For example, the C "+=" and "++" operators
343       are LValue operators, while "+" is a normal RValue operator which
344       returns a temporary result.  LValue operators allow Rune to implement
345       almost the full complement of C operators and additionally allows you to
346       build your own user operators with similar characteristics.
347     <P>
348     * User-defined casts.  All casts in Rune are physically declared, including
349       core castings such as int8->int16.  The Rune class library implements
350       the more common casts but does not implement all casts.  For example,
351       you cannot cast <B>int8</B> directly to <B>uint32</B>.  You would
352       have to do something like <B>(uint32)(uint8)int8_value</B>.
353     <P>
354     * Method calls.  A method call is something like <B>file->setMode(10)</B>.
355       That is, making a call through an object.  In Rune a method declarations
356       or call is similar to a procedure call passing the object as an lvalue
357       as the first argument to the procedure and, in fact, the Rune resolver
358       converts method declarations and calls to exactly that.  You can also
359       create <I>global</I> method calls.  These can be called through the 
360       object or through the object's type or class, but rather then passing
361       an object as the first argument the type is instead passed.  Something
362       like
363       <B>FILE *fi = FILE.fopen(...)</B> is an example of a global method
364       call.
365       <P>
366       Rune normally constructs the first argument for a method call silently and
367       automatically.  The argument is named <B>this</B> and will be the object
368       the method is acting upon as an lvalue.  However, there are cases where
369       you might want to declare this argument yourself.  Specifically
370       there are cases where you may wish to pass an lvalue pointer to an object
371       rather then the lvalue object itself. 
372       Constructors are typically used to initialize objects
373       in-place, while method calls are typically used to create new objects.
374       Having a method call create an object can get complex if the caller really
375       wants the method to create a subclass instance of the object.  While
376       the caller could certainly refine the creation method to allocate the
377       subclass, it is almost always easier to simply have the original method
378       procedure take a reference pointer lvalue as the <B>this</B> argument
379       and allocate the correct subclass object itself.  For example, 
380       the <B>createFrame</B> method in "classes/gfx/window.d" needs to be passed
381       a reference pointer as an lvalue so it can allocate a new Frame object
382       and then assign it to the pointer.   The reference pointer is typically
383       NULL to begin with.
384     <P>
385     * Rune does not implement multiple-inheritance, on purpose.  The main
386       reason is that implementations of multiple inheritance abstract what
387       is actually going on so much that they often make code unreadable
388       and unmaintainable.  In Runeland we would prefer that code be relatively
389       easy to understand and maintain.
390     <P>
391     * Declaration/Class merging.  You do not have to build all the declarations
392       making up a class in the <B>class</B> definition itself.  You can place
393       the declarations outside the class definition and even place them in
394       other source files as long as <B>library</B> scope is adhered to and
395       the declarations do not forward-reference the class (this is because
396       the merge occurs at parse time rather then resolve-time).  This allows
397       very large classes to be built without ruining the readability of the
398       source code.  You cannot merge a declaration into a class outside
399       of the library defining the class, but you can of course create a
400       subclass and add elements to the subclass (remember the part where I
401       said being able to do something a thousand different ways is not a good
402       idea?  Well, this is one of those).
403     <P>
404     * No magic type promotion.  It should be noted that Rune does
405       not automatically promote integer types for standard operators.  
406       If you add two <B>int8</B>'s together the result is going to be
407       another <B>int8</B>.  Rune will not allow you to compare an <B>int8</B>
408       against an <B>int32</B>, at least not unless you create a specific
409       operator to do it.  
410       My intent is to remove the single largest problem
411       C has when porting between architectures (including tiny 8-bit
412       architectures).  If you want something else you need to cast the
413       arguments beforehand or create your own operator (which you can do,
414       in fact).  This allows Rune to be used across the entire range
415       of platforms, from 8 bit cpu's to 128 bit cpu's, without having to
416       change the language specification or create special cases.
417       <P>
418       Automatic type promotion is not the convience you might think it is.
419       I have occassionally tried to compare or assign integers with characters 
420       while programming in Rune but it has not been a burden.  In fact I
421       believe requiring the use of a specific cast or integer constant suffix
422       in these cases has actually clarified the code in question.
423     <P>
424     * Inherent casts.  If Rune knows the type an expression needs to be,
425       for example an argument to a procedure, it will attempt to
426       cast your expression to that type. Rune can only cast based on 
427       cast operators in the class hierarchy, so Rune can automatically cast,
428       say, an <B>int8</B> to an <B>int32</B> but cannot automatically
429       cast an <B>int8</B> to a <B>uint32</B> without a little help from
430       the programmer.  <B>Keep in mind the such casting occurs after
431       the expression has been evaluated.  If you add two int8's together,
432       you will get an int8 result and that result might then be cast to
433       something larger.  The cast will not change the fact that the 
434       "+" operator in this case still returns an int8 result.</B>
435     <P>
436     * Object-oriented.  Everything is an object and eventually bases at
437       some class or compound type.  Oh wait, I said that.  Ok, I'll say
438       it again.  Even the lowly <B>int</B> is a class.
439     <P>
440     <FONT color="red">
441     * Partial procedure argument resolution.  This allows you to make a
442       more complex procedure compatible with a less complex call interface
443       by pre-evaluating and pre-supplying missing arguments.  For example,
444       a library that takes a procedure callback does not need to know about
445       additional information you supply with the procedure, such as
446       application-specific structures and pointers.  Partial resolution
447       looks like a procedure call in C but you take the address of the call.
448       For example, if you have a function that takes two arguments you can
449       turn it into a function taking one argument by partially resolving
450       the other, like '<B>&func(a:23)</B>'.  <B>alias</B> can also be used 
451       to partially resolve a procedure.
452       </FONT>
453     <P>
454     * Memory and code efficient.  I stick to a model that does not require 
455       structural or support bloat.  The run-time is separated from the
456       relatively static information (such as statement and expression
457       trees) in order to allow the relatively static info to be cached in
458       a file (e.g. so it can be shared across multiple instances of the
459       program and to avoid unnecessary copy-on-writes).   This will also
460       allow us to implement run-time threading fairly trivially.  I've
461       only written an interpreter so far but I fully intend to take advantage
462       of the compartmentalization I've built into the language to produce
463       an intermediate (pre-parsed) form as well as assembly/object code.
464     <P>
465     * Built-in Interpreter.  My intention with Rune is to be able to
466       interpret it, compile it, and even do an on-the-fly hybrid of the
467       two.  I also intend to eventually allow dynamic compilation...
468       loading and unloading source modules on the fly.  At the moment
469       I am concentrating on the interpreter.  I cannot really start work
470       on the compiler until the interpreter is nearly finished because the
471       compiler is going to rely on the interpreter's constant expression
472       resolution/optimization code.
473     <P>
474     * No #includes.  No preprocessor, but a few very simple preprocessor
475       directives to block-out debugging and testing code, or non-operational
476       musings.  Yes, this is a feature.
477       The language implements an import mechanism.  You pull everything.
478       There is no export mechanism but there are three levels of semantic
479       scope: <B>private</B>, <B>library</B>, and <B>public</B>.
480       <FONT color="red">My intention is to give the lexer a simple 
481       preprocessing capability, similar to what you might find in
482       <B>make</B>, but I have no intention of having a full
483       fledged C-like preprocessor (even though I could just borrow
484       the one from DICE) because I believe that preprocessing, and most
485       especially #include files, take what could be a nice modular
486       object-oriented application and library set and turns it into a
487       nightmare of semantic collisions.</FONT>.
488     <P>
489     <FONT color="red">
490     * Compartmentalized lexer, parser, interpreter, compiler, and library
491       manager.  At each stage the intention is to be able to save an image
492       to the file that can be mmap()'d and accessed directly in a later
493       stage, eventually allowing whole projects to be partially pre-parsed,
494       pre-compiled, etc.  The features will also be necessary when we
495       allow code modification on the fly.
496       </FONT>
497     <P>
498     * Threads.  Very cool threads.  The traditional problem one has 
499       with threading is that one must explicitly declare all sorts
500       of infrastructure to create and manage multiple threads and
501       related data structures.  Rune simplifies this greatly by introducing
502       the concept of a threaded procedure call.  If thread A calls the 
503       threaded procedure X, thread A will be suspended until the threaded
504       procedure X issues a <B>result(exp);</B> statement.  The value is
505       returned to A and A's thread resumes execution.  The threaded procedure
506       also continues to run.  <B>For example, a threaded procedure could
507       allocate and return an object representing the thread to the caller, then
508       continue running as the new thread.</B>
509       <P>
510       Rune threads are synchronous by default, meaning they share the same
511       machine context of their caller and are thus very low-overhead and very
512       fast-switching.  A Rune thread may be qualified <B>async</B> to
513       generate an actual new machine thread (similar to a posix thread).
514       A good example of the use of synchronous threads is for, say, a GUI
515       gadget library where each gadget is implemented as a Rune thread.
516       Since only one gadget is typically being manipulated at any given
517       moment it is a serious waste of resources to give each gadget a full
518       machine thread.  Instead you would run all the gadgets as synchronous
519       threads within a single async gadget-handling thread.
520     <P>
521     * Compound types and expressions.  Rune implements compound types and
522       expressions via a clever use of parenthesis and commas.  <B>There is
523       no comma-operator in Rune.  Also, note that the arguments you supply
524       to a procedure are, in fact, interpreted as one big compound type.</B>
525       Instead, there is the concept of the compound expression.  A compound
526       expression is something like this: <B>(1, 2, 3)</B>.  Additionally,
527       the elements of a compound type can be named in a manner similar
528       to the declaration of a procedure's arguments.  For example,
529       you can do this:
530       <UL><B>
531         <P>(int a = 2, int b, int c) x = (b:23, c:44);
532         <BR>x.c = x.a + x.b;
533       </B></UL>
534       <P>Now is that cool or what?  As with any declaration you can specify
535       default values.  When you make a call to a procedure which
536       returns a compound type you can either store the result into
537       a compatible compound type (throwing away elements you don't
538       request), or you can store the result into a normal type
539       in which case only the first element of the returned compound
540       type is retained.  When building a compound type any elements
541       which have defaults are optional, and since a procedure's 
542       argument set is a compound type you can extend a procedure in a
543       backwards compatible fashion by adding a new argument to it and
544       giving it a default.  'Older' users of the procedure who don't 
545       supply the argument are still ok.
546     <P>
547     * Multi-valued returns.  If you haven't guessed yet, a multi-valued
548       return is simply a compound type.  I've flip-flopped a number of
549       times on whether to implement critical error handling via a multi-valued
550       return mechanism or via exception handling, but ultimately came to the
551       conclusion that trying to implement it via the multi-valued return
552       mechanism would lead to code that is just too messy.
553     <P>
554     * Exception-handling.  Rune implements exception handling through a
555       <B>raise</B>/<B>catch</B> mechanism, but distinguishes between
556       nominal status returns such as a file EOF or non-blocking status
557       and more serious error conditions or aborts that warrant an exception.
558       The exception-handling mechanism gives subsystems a relatively painless
559       semi in-band way to back-out of situations without having to process
560       error codes from every single procedure call made.  The mechanism is
561       similar to what TCL uses in some respects.
562     <P>
563     * Constructors and Destructors.  Classes and compound types may 
564       have any number of constructors and a destructors.  A constructor
565       or destructor is a method procedure that takes no arguments.  
566       Constructors are called when an object is instantiated, after any
567       type and declarative defaults are set.  Destructors are called
568       when the last reference to an object goes away.  The constructors
569       and destructors associated with the superclass will be called
570       before the constructors and destructors associated with a subclass.
571       Constructors and destructors are called in order, first to last.
572       <P>
573       Destructors can resurrect an object.  When an object's ref count
574       reaches 0 Rune will set the ref count back to 1 and call the 
575       destructors.  Rune then checks the ref count.  If the ref count
576       is still 1 Rune blows the object away.  If the ref count is greater
577       then 1 then the object is considered to have been resurrected.
578     <P>
579     * Heap storage via pointers.  Heap storage is nothing more then a
580       bounded pointer that is always ref-counted.  To create storage on
581       the heap you simply declare a pointer and execute
582       the <B>new</B> method on it.  For example, <B>MyObject *a; a.new();</B>.
583       It's that simple.  Rune will
584       free the storage when the last reference goes away.  <B>Note that
585       Rune does not garbage-collect.  Creating an unreachable cycle is
586       considered a run-time error though, at the moment, Rune does not detect
587       the condition.
588       I consider creating an unreachable cycle to be sloppy programming.  Also
589       note that while Rune will recursively free chains, it is not a good idea
590       to depend on the feature to delete very long chains because you might
591       run the thread out of stack space (XXX this has to be fixed).  Instead
592       we recommend that you NULL-out the chain pointers manually.
593       </B>
594     <P>
595     * Scripting.  Rune supplies a nifty little scripting mechanism which makes
596       writing a program in Rune and executing it via the interpreter trivial.
597     <P>
598     * No version control.  Rune does not attempt to integrate version control
599       mechanisms into the language.  Folks, the plain fact of the matter is
600       that even the most robust Eiffel-like version control mechanism does not
601       make up for actually testing a project with the latest set of so-and-so
602       library.  In fact, I strongly believe that integrating such features into
603       a language create even more problems then they solves because, like
604       exceptions, it results in code paths which are virtually untestable
605       and as likely to blow up as to work the first time they occur in real
606       life.  In balancing one evil against the other I would much prefer 
607       documentation over enforced language-level compatibility.  Rune provides
608       mechanisms, such as argument defaulting, that allow you to create
609       backwards compatible libraries but does not require that you use them.
610       There is also nothing preventing you from including a major version
611       number in the names of the libraries you import, nor is there anything
612       preventing you from importing different versions of the same library
613       (though the usability of doing so is suspect).  Rune is designed to
614       facilitiate, but not enforce, backwards compatibility.
615     <P>
616     * Automatic object locking and ref-counting is fully integrated into
617       the language and threading system.
618       Rune obtains a lock and a ref-count on the storage related to any
619       object it is actively working on or has a local stored pointer for.
620       Rune will obtain a
621       shared or exclusive lock depending on the use case.  The lock
622       structure itself is associated with the objects storage, not embedded
623       in the object itself so the sizeof() an object is always as expected.
624       Object locking is mandatory and handled by Rune itself in order to
625       ensure stability in a multi-threaded environment.
626       <P>
627       Rune utilizes a <B>soft</B> object locking model by default.  Procedures
628       and statement blocks can be coded to use a <B>hard</B> locking model.
629       Deadlocks are not possible in the soft model but locks are allowed to
630       be temporarily lost (and then reacquired) while a thread is blocked,
631       including if it blocks obtaining a nominal object lock.
632       Hard code sections do not allow this temporary release.
633       <P>
634       Thus programmers can depend on a certain degree of automatic locking
635       at all times, but are expected to use <B>hard</B> code sections when
636       lock atomicy over long sections of code is required.
637 </UL>
638
639 <P>
640 <H2><B>(III) Native types and operators</B></H2>
641 <UL>
642     <P>
643     Please refer to the Rune core class module,
644     <A HREF="../classes/sys/class.d">../classes/sys/class.d</A>.
645     <P>
646     Generally speaking core types are as you might expect coming from
647     a C environment, with some exceptions.  Types in Rune do not have
648     the same kind of wiggle room as you see in C:
649     <UL>
650         <P>
651         * char's are always unsigned 8 bit quantities regardless of the
652           architecture.  This is different from C where char is typically
653           signed.  In Rune char is <I>always</I> unsigned and the application
654           must use something like <B>int8_t</B> if a signed 8 bit quantity
655           is desired.
656         <P>
657         * int's are always signed 32 bit quantities regardless of the
658           architecture.
659         <P>
660         * long's are always signed 64 bit quantities regardless of the
661           architecture.
662         <P>
663         * bool's are a subclass of Numeric, NOT a subclass of Integer.
664           They can be cast to or from an integer, however.  This is done
665           on purpose.  Special-case boolean logic makes certain optimizations
666           easier to propagate.
667     </UL>
668     <P>
669 </UL>
670 <P>
671 <H2><B>(IV) Operational Stages</B></H2>
672 <UL>
673     <P>
674     * Lexer
675     <UL>
676         <P>
677         The Rune lexer converts a Rune source file into a stream of tokens.  The
678         lexer is responsible for detecting and skipping comments and
679         whitespace, and for separting tokens out.
680         <P>
681         The Rune lexer is writen directly in C and is extremely fast. 
682         Tokens are tracked through a token_t structure which is typically
683         manipulated by reference, and an integer identifier is returned 
684         along with the new token.  The parser switches on this identifier
685         almost universally.  The lexer has a look-ahead capability which
686         the parser uses on occassion.
687     </UL>
688     <P>
689     * Parser
690     <UL>
691         <P>
692         The Rune parser takes a stream of tokens from the lexer and (well Duhhh!)
693         parses the language.  The Rune parser will also recursively open and
694         parse lexical streams related to <B>import</B> statements.
695         <P>
696         The Rune parser is recursive-descent, written directly in C.  Parser
697         elements are simply procedures.  However, the language is LALR(1)
698         (or LALR(2) depending on how you look at it) and the parser never
699         has to back up.  This makes the parser extremely fast.
700         <P>
701         The Rune parser constructs a hierarchy of statements, expressions, and
702         declarations on the fly.  The primary hierarchical component that
703         glues everything together is the statement.  For example,
704         the statement representing an import will have a reference to
705         the imported entity.
706         <P>
707         However, declarations are used as the cornerstone of the semantic
708         identifier search and management subsystem.  Any identifier that
709         can be looked up will have an associated declaration somewhere.
710         Declarations also earmark storage offsets within structures,
711         compound objects, procedures, and procedure arguments.
712         <P>
713         <B>The Rune parser does not attempt resolve identifiers at parse-time.
714         This is one reason why Rune can have forward-referenced identifiers.
715         Identifiers representing definitions are hashed at parse time,
716         however.</B>
717     </UL>
718     <P>
719     * Resolver
720     <UL>
721         <P>
722         The resolver is responsible for taking a parse set and turning it
723         into something that can be interpreted, compiled, and/or saved
724         and restored.  The resolver takes three passes on the parse-set:
725         <P>
726         <B>* Pass 1 -</B> Resolve subclass hierarchy.  The resolver 
727         must first integrate declarations from the superclass into the
728         subclass.  Refinement issues are handled at this time.  Note
729         that the statement, expression, and declaration subhierarchies
730         are duplicated for each subclass in order to allow Rune to optimize
731         the refined procedures on a subclass-by-subclass basis.  This
732         greatly simplifies the job of the interpreter and compiler.  
733         <FONT color="red">I intend to have Rune figure out which elements
734         in the superclass are not used at all by the subclass and to
735         delete them / not generate them.  For now though Rune will
736         generate them.</FONT>
737         <P>
738         Resolving the subclass hierarchy is a recursive affair.  For
739         example, the declarations in <B>Numeric</B> must be integrated
740         with the declarations in <B>Integer</B> and from there integrated
741         with the declarations in, say, <B>int8</B>.
742         <P>
743         <B>* Pass 2 -</B> Resolve types, expressions, and declarations.
744         This pass is responsible for assigning an intermediate type to
745         each expression, resolving the types (figuring out actual
746         storage and alignment requirements for a type), and resolving
747         non-procedural declarations (figuring out the actual storage
748         requirements for a declaration).  This includes completely
749         resolving compound types, the top-level, and classes, all of
750         which are really just a list of declarations.
751         <P>
752         This pass is responsible for looking up and resolving operators,
753         procedures, and for enforcing casts.  All of these operations
754         involve manipulation of the expression hierarchy.
755         <P>
756         <B>* Pass 3 -</B> Resolve temporary storage requirements.  The
757         interpreter and compiler needs to know about temporary
758         storage requirements for expressions and aggregate
759         storage requirements for procedures.  For example, if you
760         do something like <B>int a = (b + c) * d;</B> then we need
761         to store the intermediate result from (b + c) somewhere.
762         This pass figures out what those requirements are so the
763         interpreter can allocate the necessary space.
764         <P>
765         This pass allows the interpreter or compiler to know how much
766         space a procedure requires to operate inclusive of variable 
767         declarations and temporary space.  The Rune intepreter will
768         reserve the space for the entire procedure up-front, on the
769         stack, when the procedure is called.  The resolver is also able
770         to figure out legal overlappings for storage so when you
771         have multiple executable blocks in a procedure, like this:
772         <B>{ int a; ... } { int b; ... }</B>, Rune will only
773         need to allocate 4 bytes of actual stack space to represent
774         both <B>a</B> and <B>b</B>.  The same goes for temporary
775         space used by an expression.  The resolver is aware of the
776         difference between lvalue and non-lvalue intermediate storage
777         and only needs to allocate actual space for non-lvalue storage.
778     </UL>
779     <P>
780     * Interpreter (selected resolver backend)
781     <UL>
782         <P>
783         The interpreter will execute a Rune program.  It provides internal
784         tie-ins to core classes, operators, and system calls, which are
785         implemented by the interpreter itself rather then in Rune code.
786         For example, adding two integers together ("+" on two ints)
787         requires tie-ins to a native in-interpreter implementation of the
788         operator.
789         <P>
790         The Rune interpreter will do further on-the-fly optimization of
791         the statement and expression hierarchy.  For example, if you
792         have a constant-producing procedure and you call it, the
793         interpreter will interpret the procedure, recognize the
794         constant result, and then shortcut the expression hierarchy so
795         the constant can simply be supplied directly the next time that
796         particular call is made.  Another example is our internal
797         bindings.  When the interpreter sees an operator bound
798         to an internal function it will resolve the binding and from then
799         on simply call the function directly.
800         <P>
801         Other common optimizations are things like <B>variable + constant</B>
802         operations, which Rune will do for certain selected types.  In most
803         cases the interpreter simply changes the ex_Func function
804         vector in the expression or st_Func function vector in the statement
805         to achieve the optimization.
806         <P>
807         The Rune interpreter holds all state necessary to make a procedure
808         call on the stack, allowing us to create pthreads threads
809         for Rune threads on a 1:1 basis.
810     </UL>
811     <P>
812     * Compiler (selected resolver backend)
813     <UL>
814         <P>
815     </UL>
816     <P>
817     * Assembler (selected resolver backend)
818     <UL>
819         <P>
820     </UL>
821     <P>
822     * Linker (selected resolver backend)
823     <UL>
824         <P>
825     </UL>
826 </UL>
827 </BODY>
828 </HTML>