eX version 0.4b User's Manual                         File eXMan05.txt
(C) Copyright 1995, 1996 William E. Wilgus III.   All rights reserved.



Aggregation

Some computer language manuals describe aggregations as meaning `do
what is inside the parenthesis first'.  The complete definition
continues `and treat the result as an entity', and the continuation is
essential to the eX language.  eX aggregations may be nested and may
span macros.  

The language includes three forms of what it considers aggregation.
Two of the forms, however, are intended to fulfill special roles and
are not normally used for aggregation---and it is a `big stretch' to
consider one an aggregation at all!  Since they may be used for
aggregation, they are presented here as such. 


`Standard' Aggregation

The usual matching left and right parens `()', ASCII codes 40 and 41, 
are used as eX's `standard' aggregation delimiters.  Some mechanics
are associated with eX's `standard' aggregation.  First, when one is
encountered, eX increments the level (minor dimension of the
accumulator array) to which accumulation will occur.  The new level
within the plane then, becomes the new current level.  Then the new
current plane, level numeric accumulator is reset to zero (0.0) and
the new current plane, level string accumulator is reset to null ("").
Next, it asserts that an addition operation is pending in the current 
plane, level (which merely serves to `load' the accumulator(s) with
the first value(s) encountered in the aggregation) and then resumes
macro execution.  

Three controls are provided to faciltate using the accumulators as
`registers' in the same manner that an assembly language programmer
may use the CPU registers, and whitespace must follow these
accumulator commands.    

First, upon entry to a level, its accumulator value(s) may be `pushed'
on an internal stack for later recall before they are nulled.  The
apostrophe ', ASCII code 39 is used as the `push' command, and it must
immediately follow the aggregation beginning delimiter: ('.  If the
apostrophe is immediately followed by a numeric suffix #, the numeric
accumulator is pushed; if immediately followed by a string suffix $,
the string accumulator is pushed.  In the absence of a suffix, both
the numeric and string accumulators are pushed; first the numeric,
then the string.  Logically then, only one suffix may be employed with
a push; and perhaps illogically, a push command may appear only once
in an aggregation.

Second, the aggregation's accumulator value(s) can be held instead of
nulled.  The semi-colon `;', ASCII code 59 is used as the hold command. 
It must immediately follow the aggregation beginning delimiter unless
an accumulator push command is given, and in this case it must
immediately follow the push command.  (I.e., if both a push and a hold
are given, the push must appear first and no whitespace may
intervene.)  A numeric or string suffix may be employed with a hold
command in the same manner that suffixes may be used with a push
command.  In the absence of a suffix, both the numeric and string
accumulators are held.  Note that holding either or both of the
accumulators precludes the implied addition normally associated with
the `standard' aggregation beginning delimiter.  (eX would have to be
re-named heLL otherwise.)  


When the end of the aggregation is encountered, eX decrements the
level to which accumulation will occur and the values of the numeric
and string accumulators of the aggregation are made available to any
pending value requirement(s) (tasks) preceding the aggregation.  A
parens aggregation always provides both a numeric and a string value,
which eX considers valid, or to exist.  (If it has not been made
clear, the ability to accumulate at level 0 exists and is no different
than in an aggregation.  However, accumulation at level 0 is not
automatic and must be initiated with an operator.) 

Returning to the left paren's implied addition operation, it loads the
value(s) returned by the first value-producing term within the
aggregation. Therefore, the following are not equivalent:

     (5 + "string")        returns 5 and "string"
     (5 "string")          returns 5 and "" (the null string)
     ("string" 5)          returns 0 and "string"

In the latter two above, the second of the aggregtion's terms was
never accumulated, therefore that term's data class is returned as
null.  

Since there is a push command, there must be a `pop' command to recall
the pushed accumulator values.  This is the third aggregation
accumulator control for using accumulators as registers.  Again the
apostrophe is used and it must immediately follow the aggregation
ending delimiter: )'.  As with the push and hold commands, a numeric
or string suffix may be employed to limit the pop to that accumulator
indicated by the suffix.  Also as with the push and hold commands,
only one suffix may be employed.  If no suffix is employed, both
accumulators are popped; first the string and then the
numeric---inversely matching the order of a no-suffix accumulator 
push.  Although the pop command's suffix (if any) must normally match
that of the preceding push command (or you're gonna un-justly call me
bad names), the following is possible: 

                   (' ... )'$ ( ... )'#


Non-Standard Aggregation

Bracket Aggregations

The first of the two non-standard aggregations is formed with matching
left and right brackets [ ], ASCII codes 91 and 93.  The only difference 
between bracket and `standard' aggregations regarding accumulation is 
that the left bracket does not imply an addition operation.  

     [5 "string"]        returns   0 and "" (the null string)
     [+ 5 "string"]      returns   5 and "" (the null string)
     [5 + "string"]      returns   0 and "string"
     [+ 5 + "string"]    returns   5 and "string"

The same accumulator push, hold and pop commands that are available
with a `standard' aggregation are available with a bracket
aggregation, and it always returns the values of both its numeric and
string accumulators when exited.  It also represents an accumulator
level, incremented when entered and decremented when exited. 

Useful when the addition implied by the left aggregation delimiter and
an accumulator hold command to preclude the `standard' aggregation's
implied addition are un-desirable, a bracket aggregation carries
additional overhead and therefore is slower than a `standard'
aggregation.  Letting the cat out of the bag, the additional overhead
is because bracket structures are used to form conditional execution
structures.  But as you've just seen, they can be used simply for
aggregation as well.  In fact, they can be used for aggregation while
serving as conditional execution structures.



Brace Aggregations

The other non-standard aggregation is formed with matching left and
right braces { }, ASCII codes 123 and 125.  When thought of as an
aggregation, the structure is very strange, indeed.  I think it will
help to let you know immediately that braces are normally used to form
conditional test structures, called test(s) for short, and I chose
braces to form the structure because they're pretty `iffy-looking'. 
But you might find a use for the structure as an aggregation, so here
goes. 

Like a `standard' aggregation, the left brace implies an addition 
operation to `load' the accumulators.  But un-like the `standard' and
bracket aggregations, no accumulator push, hold, or pop commands are
available.  It also differs in that it never returns a string, and
returns a numeric only when used as an aggregation.  Although the
accumulator level is incremented when the structure is entered and
decremented when exited, a brace structure forces the accumulator 
plane to -1 if not already so when the structure is entered.  But
before you panic, eX saves the current plane, level when forced to
enter plane -1 by a brace structure beginning delimiter and restores
that plane and level when the matching brace structure terminating
delimiter is encountered. 

As with the `standard' and bracket aggregations, any code may appear
in a brace structure.  However, if a logical or relational operation
is encountered and proves false, execution of the code subsequent to
the false operation up to the end of the brace structure is precluded
and the structure is exited.  In this case, the value returned by the
structure is 0 (false).  Otherwise the value returned by the structure
is either 1 or -1 (mirroring the sign of the structure's numeric
accumulator when it is exited) to indicate true.  Therefore, the only
sane use of the structure as an aggregation is to provide either the
truth of a logical or relational test or the knowledge of whether or
not all the code within the structure executed.  (If you're thinking
ahead to whether or not multiple logical or relational tests may
appear within a single brace structure, the answer is yes!)


A Potential Problem

Before reading this section, you should know that you will probably
never encounter the potential problem it discusses.  If you do
encounter it, you're either writing some really strange code (that 
is perhaps allowed by only eX and Assembly Language) and you've
forgotten to provide a necessary exception handling routine, or you've
just plain messed up, because it certainly is not a design defect or
bUGH!  If you have already encountered the problem and are just now
reading this section, my reply to you is "Like-wise, I'm sure"! 


The chapter on operators contained a statement to the effect 

     Operators are quasi-local to the plane and level in 
     which they appear. 

The `quasi' part is the potential problem.  In actuality, only the
requirement(s)---which act like a gun's trigger and `fire off' the
operation(s)---is (are) local to an operator's plane and level.  
Operators themselves are actually global, i.e., with the exception
that multiple operators are executed right to left, operators are
executed left to right as they appear in a macro---PERIOD. 

An example will help show the potential problem.  Consider the first
four of the following macro fragments: 

     * (5 + 10)
     [ ]
     ()
     * (5 +)
     / (; )

The first is normal, of course and presents no problem.  The second is
normal in eX.  The third might be normal in many languages, but it is
not normal in eX.  The fourth is definitely abnormal, and let's
discuss it first. 

The missing right-hand operand for the addition operator in the
aggregation leaves that operation un-performed within the aggregation.
Exiting the aggregation returns the values 5 and "", which triggers
what you might expect to be the multiplication operation---but is not!
The addition operation is performed with the aggregation's eevs as the
right-hand operand and the accumulators that were to serve as the 
multiplication operation's left-hand operators serve as the left-hand
operands.  Unfortunately, the left-hand operators for the addition
operation were supposed to be the aggregation's accumulators!  So the
operators and operands are out of sync and we still have a `hang fire'
(operation pending `trigger') in the aggregation.  If the macro
continues, the situation will assuredly get worse.  

Let's touch on the third macro fragment momentarily.  It leaves an
addition operation hanging in the aggregation just like the fourth
macro fragment does because of the implied addition of the left 
parens.  Was that moment arily enough? 

The fifth fragement given above is quite normal in eX.  It's just a
handy way to return the values of an accumulator that was used as a
`register'.  Its accumulator hold command `;' not only held the
`register' values so they could be returned, it also precluded the
left paren's implied addition, so there's no `hang fire'. 

If strange things are being produced by your macro, you might do well
to look for an operator that doesn't get a right-hand operand. 
Or---have we just discovered a new math discipline?  

