Getting Started Documentation Glish Learn More Programming Contact Us
Version 1.9 Build 1556
News FAQ
Search Home


next up previous contents index
Next: References Up: The Design of AIPS++ Previous: Glossary

Subsections


Glish Programming Idioms

Glish is a procedural language with whole-array9.30 manipulations loosely based on the ``S'' language. Glish also has powerful facilities for asynchronously controlling and communicating with other processes (either other Glish scripts or compiled programs). This document assumes a reasonable familiarity with Glish; an excellent user manual comes with the Glish distribution.9.31

The AIPS++ group is attempting to use Glish as an end-user command line interpreter (CLI). Since Glish was originally designed for a very different purpose (instrument control) some work and experimentation will be required for Glish to be truly suitable. Much of the work will be ``environmental'': command line editing9.32, on-line help, and the like. Some of this work can, however, can be done by establishing programming conventions within Glish so the end user sees a consistent and convenient way of interacting with Glish values and functions.

Object Oriented Glish

The desire to have object-oriented programming features in Glish originally stemmed from the desire to allow the user to have access to overloaded functions. That is, some of the entities that the user would be manipulating would logically be more complex than Glish values, for example AIPS++ Tables, images, etc. There are many generic functions the user might want to call on these ``objects'' (display, help, history, and the like).

Neither of the obvious alternatives:

1.
Encode the type name in the function: display_table, display_column, display_row, display_image, etc.
2.
Since these types will undoubtedly be represented inside Glish as Glish records, we could case on a type field inside the various functions.
were very attractive. The first solution requires the user to remember a lot of logically identical functions, the second solution is fragile since it requires that every function be looked at when a new ``type'' is added.

Instead, polymorphic methods seemed to solve the problem readily. Additionally, the OO convention diminishes the ``impedance mismatch'' between the C++ libraries and the CLI user, allowing the proxy objects to more closely follow the C++ versions.

Obviously an idea solution would be for Glish to provide built-in support, , i.e. evolve towards S+ from S. We shall investigate the costs and benefits of doing so.

Asynchronous Glish

Many user data reduction and analysis operations take sufficiently long that a user would not necessarily want to wait for them to finish. AIPS (Classic) for instance has ``verbs'' which are relatively low-cost computations which always run synchronously, and ``tasks'' which are inherently asynchronous, although the user may specify that ``tasks'' are to operate synchronously.

Glish has excellent facilities for asynchronous programming. The full set of facilities -- whenever statements, subsequences, etc., -- is far richer than the typical user will to want to deal with.

We can instead establish a convention where the user specifies during the function invocation whether or not the execution takes place asynchronously. In the latter case, the user also needs to know where to find the result, and to know when the computation has finished.

    x := fft(y)*z;        # fft defaults to synchronous; just use it as any
                          # other function.

    fft(y, async=T);      # Run fft asynchronously. Eventually the
    ... other work ...    # user gets notified that it has finished.
    x := results.fft*z;   # Get the result and compute with it

While in the above example ``results.fft'' is an array, it could clearly just as easily be a Glish record for computations which produce multiple output values.

A flaw in the previous example is that since there is only one place to look for the result, only one asynchronous ``fft'' may take place at a time, since there's only one place to look for it. This may not only be inconvenient, it would disallow the user to take advantage of coarse parallelism by spreading computations out over multiple cpu's of a single machine, or multiple hosts on a network.

For example suppose the user is on a four processor machine and wants to fft a cube a plane at a time, spread over all four processors.

    nplanes := cube::shape[3];
    for (i in 1:nplanes) {
        request[i] := fft(cube[,,i], async=T, client_number=i%4+1);
}
    wait_for(requests);
    for (i in 1:nplanes) {
        cube[,,i] := result[request[i]];
    }

A slightly more complicated example would have the client adaptively fill up the fastest CPU's in case some are faster than others (e.g., sharing with another user). Note that this example assumes that the underlying client (i.e., compiled binary) is single threaded; that is, we need one client per CPU. If this wasn't the case, we could just leave out the client number.

A similar example would allow the computation to be spread over a network of machines by specifying host = hostname.

Here we have made the user remember a request number, where before they only had to remember ``result.fft.'' The increase in generality appears to me to be worth the price.

Status

Object-oriented Glish works and is useful, although more language support would make it more convenient for ``class'' implementers.

The asynchronous idiom presented here has not been implemented, although it should be straightforward


next up previous contents index
Next: References Up: The Design of AIPS++ Previous: Glossary   Contents   Index
Please send questions or comments about AIPS++ to aips2-request@nrao.edu.
Copyright © 1995-2000 Associated Universities Inc., Washington, D.C.

Return to AIPS++ Home Page
2006-10-15