6. Compound Data Types

What are compound data types?

There are other types of queues and functions in Q-BAL than queues of numbers and functions on numbers. There are queues of queues, or functions on queues, or queues of functions. These are declared with a variable number of Qs and Fs for the type section of a declaration. For example, FQ sort would declare a function on queues. In general, a "queue" or "function" refers to a queue of numbers or a function on numbers. An example of a use of a queue of queues follows:

QQ x
Q y
y = 'in
*$y -> x
; - 3\(#y != 0) -> ;
$x -> 'out
; - 2\(#x != 0) -> ;
; ->

This complete program will read strings until a null string is entered (return with no other characters), and then print them all out in the same order they were entered, followed by a blank line. (Don't worry about understanding it now; we'll refer back to it as we go on.)

The "Greatest Common Denominator"

When an assignment or attachment includes different data types, the "Greatest Common Denominator Rule" is used to determine how the data is manipulated. The GCD of two types is the largest string of Qs and Fs that is common to both, on the right side. In the case of attachment, the GCD must be shorter in length than the shorter of the two types, while in assignment it can be equal to the shorter. The GCD is the longest data type that is manipulated. For any data type, if the GCD is more than one letter shorter than the type in question (if the operation is attachment) or if it is at all shorter (if the operation is assignment), then the excess is put onto the top of the queue (or the output queue for functions.) An example will serve to make this clearer:

FQQ x
QQ y
FQ z
...
y -> x
y = x
z = y
y -> z
x -> z

Admittedly, you aren't likely to run across anything nearly this complex. But it serves a good illustration. Let's take this in order. The first three statements declare x a function on queues of queues, y a queue of queues, and z a function on queues. The fourth line is an ellipsis, indicating that there is probably code in between, but what it is doesn't matter. Now we're at the confusing part.

The first attachment has a GCD of Q (it would be QQ, but an attachment GCD must be shorter than the shortest, which in this case is QQ). Therefore it works on queues. It pops the first queue off y (y is a queue of queues) and appends it to -- what? Well, excess is put onto the output queue, so it appends it to the top queue of queues on the output queue of x, which is a function on queues of queues.

The second statement is an assignment with a GCD of QQ. It sets y (a queue of queues) equal to the top queue of queues in the output queue of x (a function on queues of queues) without popping it off x.

The third statement is an assignment with a GCD of Q. It sets the top of the output queue of z (a function on queues) equal to the top of y (a queue of queues) without popping it off y.

The fourth statement is an attachment with a GCD of Q working the same way between the same variables as the third statement. This one pops the top queue off y (a queue of queues) and appends it to the bottom of the input queue of z (a function on queues).

The fifth statement is an attachment with a GCD of Q. It pops the top queue off the top queue of queues of the output queue of x (a function on queues of queues) and appends it to the bottom of the input queue of z (a function on queues).

Got it? Good!

The Input/Output Override Prefix Operators Revisited

Remember the I/O override operators & and @ from advanced functions? They can apply to multiple data types as well. Normally, excess is put on the top, or the top of the output queue, but these can force it to be put on the bottom, or on the input queue. To this end, they can be applied to queues as well as functions. When used in this way to functions, sometimes they must be applied twice. The default is @ or @@, the top of the output queue. & or && will force it to the bottom of the input queue. &@ will force the bottom of the output queue, and @& the top of the input queue. Needless to say, these are generally considered bad form. But hey; who cares?

Variable Data Types

An object may be declared as a type ending in X;, such as QX or FQX. The X stands for "anything". QX means a queue of anything, and FQX means a function on queues of anything. When used in an expression, consider the X by default to be whatever will make the GCD the longest. If two X-types are used in the same expression, make both the Xs equal to whatever is at the top of the source.

The String Prefix Operator ($)

The String prefix operator $ forces the GCD to a higher level. One use of the string on the source will raise an attachment to the level of the smaller, if possible. For example:

QQ x
Q y
...
$y -> x

This code will leave y a null queue and append to x (a queue of queues) what it used to be. The string operator often leaves its operand a null queue. When used other than this, it causes things to be strung together. For example:

Q x
Q y
...
$x -> y

This code will string together all of x and append it to y. If x = {1,2,3} and y = {1,4,9}, then after this code executes y = {1,4,9,1,2,3} and x is a null queue. In general, be logical: it's usually pretty obvious what the string operator should do in any given situation.

The Diminish Prefix Operator (%)

The Diminish Prefix Operator % is the opposite of the string operator. It lowers the GCD by one letter. It is even more intuitive than the string operator and needs no example.


Previous: Advanced Functions