History
''Speakeasy'' was initially conceived to work on mainframes (the only kind of computers at that time), and was subsequently ported to new platforms ( minicomputers, personal computers) as they became available. The porting of the same code on different platforms was made easier by using Mortran metalanguage macros to face systems dependencies and compilers deficiencies and differences. Speakeasy is currently available on several platforms: PCs runningSyntax
The symbol :_ (colon+underscore) is both the Speakeasy logo and the prompt of the interactive session. The dollar sign is used for delimiting comments; the ampersand is used to continue a statement on the following physical line, in which case the prompt becomes :& (colon+ampersand); a semicolon can separate statements written on the same physical line. As its own name tells, Speakeasy was aimed to expose a syntax as friendly as possible to the user, and as close as possible to the spoken language. The best example of that is given by the set of commands for reading/writing data from/to the permanent storage. E.g. (the languages keywords are in upper case to clarify the point): :_ GET my_data FROM LIBRARY my_project :_ KEEP my_data AS a_new_name_for_mydata IN LIBRARY other_project Variables (i.e. Speakeasy objects) are given a name up to 255 character long, when LONGNAME option is ON, up to 8 characters otherwise (for backward compatibility). They are dynamically typed, depending on the value assigned to them. :_ a=1 :_ whatis a A is a REAL SCALAR. :_ a="now a character array" :_ whatis a A is a 21 element CHARACTER ARRAY. Arguments of functions are usually not required to be surrounded by parenthesis or separated by commas, provided that the context remains clear and unambiguous. For example: :_ sin(grid(-pi,pi,pi/32)) $ fully specified syntax can be written : :_ sin grid(-pi,pi,pi/32) $ the argument of function sin is not surrounded by parenthesis or even :_ sin grid(-pi pi pi/32) $ the arguments of function grid can be separated by spaces Many other syntax simplifications are possible; for example, to define an object named 'a' valued to a ten-elements array of zeroes, one can write any of the following statements: :_ a=array(10:0,0,0,0,0,0,0,0,0,0) :_ a=0,0,0,0,0,0,0,0,0,0 :_ a=0 0 0 0 0 0 0 0 0 0 :_ a=ints(10)*0 :_ a=10: Speakeasy is a ''vector-oriented'' language: giving a structured argument to a function of a scalar, the result is usually an object with the same structure of the argument, in which each element is the result of the function applied to the corresponding element of the argument. In the example given above, the result of function sin applied to the array (let us call it x) generated by the function grid is the array answer whose element answer(i) equals sin(x(i)) for each i from 1 to noels(x) (the number of elements of x). In other words, the statement :_ a=sin(grid(-pi pi pi/32)) is equivalent to the following fragment of program: x=grid(-pi pi pi/32) $ generates an array of real numbers from -pi to pi, stepping by pi/32 for i = 1,noels(x) $ loops on the elements of x a(i) = sin(x(i)) $ evaluates the i-th element of a next i $ increment the loop index The ''vector-oriented'' statements avoid writing programs for such loops and are much faster than them.Work area and objects
By the very first statement of the session, the user can define the size of the "named storage" (or "work area", or "allocator"), which is allocated once and for all at the beginning of the session. Within this fixed-size work area, the Speakeasy processor dynamically creates and destroys the work objects as needed. A user-tunable The user can decide how often the garbage collections occur, in terms of number of objects created between two of them. This feature (SLOSH command) is actually aimed to linkules debugging. garbage collection mechanism is provided to maximize the size of the free block in the work area, packing the defined objects in the low end or in the high end of the allocator. At any time, the user can ask about used or remaining space in the work area. :_ SIZE 100M $ very first statement: the work area will be 100MBRaw object orientation
Within reasonable conformity and compatibility constraints, the Speakeasy objects can be operated on using the same algebraic syntax. From this point of view, and considering the dynamic and structured nature of the data held in the "named storage", it is possible to say that Speakeasy since the beginning implemented a very raw form of operator overloading, and a pragmatic approach to some features of what was later called "The object families
Speakeasy provides a bunch of predefined "families" of data objects: scalars, arrays (up to 15 dimensions), matrices, sets, time series. The elemental data can be of kind real (8-bytes), complex (2x8-bytes), character-literal or name-literal ( matrices elements can be real or complex, time series values can only be real ).Missing values
ForLogical values
Some support is provided for logical values, relational operators (the Fortran syntax can be used) and logical expressions. Logical values are stored actually as numeric values: with 0 meaning false and non-zero (1 on output) meaning true. :_ a = 1 2 3 4 5 :_ b = 1 3 2 5 4 :_ a>b A>B (A 5 Component Array) 0 0 1 0 1 :_ a<=b A<=B (A 5 Component Array) 1 1 0 1 0 :_ a.eq.b A.EQ.B (A 5 Component Array) 1 0 0 0 0 :_ logical(2) $ this changes the way logical values are shown :_ a>b; a<=b; a.eq.b A>B (A 5 Component Array) F F T F T A<=B (A 5 Component Array) T T F T F A.EQ.B (A 5 Component Array) T F F F FProgramming
Special objects such as "PROGRAM", "SUBROUTINE" and "FUNCTION" objects (collectively referred to as ''procedures'') can be defined for operations automation. Another way for running several instructions with a single command is to store them into a use-file and make the processor read them by mean of the USE command.Use-files
"USEing" a use-file is the simplest way for performing several instruction with minimal typed input. (This operation roughly corresponds to what "source-ing" a file is in other scripting languages.) A use-file is an alternate input source to the standard console and can contain all the commands a user can input by the keyboard (hence no multi-line flow control construct is allowed). The processor reads and executes use-files one line at a time. Use-file execution can be concatenated but not nested, i.e. the control does not return to the caller at the completion of the called use-file.Procedures
Full programming capability is achieved using "procedures". They are actually Speakeasy objects, which must be defined in the work area to be executed. An option is available in order to make the procedures being automatically retrieved and loaded from the external storage as they are needed. Procedures can contain any of the execution flow control constructs available in the Speakeasy programming language.Programs
A program can be run simply invoking its name or using it as the argument of the command EXECUTE. In the latter case, a further argument can identify a label from which the execution will begin. Speakeasy programs differs from the other procedures for being executed at the same scoping "level" they are referenced to, hence they have full visibility of all the objects defined at that level, and all the objects created during their execution will be left there for subsequent uses. For that reason no argument list is needed.Subroutines and functions
Subroutines and Functions are executed at a new scoping level, which is removed when they finish. The communication with the calling scoping level is carried out through the argument list (in both directions). This implements data hiding, i.e. objects created within a Subroutine or a Function are not visible to other Subroutine and Functions but through argument lists. A global level is available for storing object which must be visible from within any procedure, e.g. the procedures themselves. The Functions differ from the Subroutines because they also return a functional value; reference to them can be part of more complex statement and are replaced by the returned functional value when evaluating the statement. In some extent, Speakeasy Subroutines and Functions are very similar to the Fortran procedures of the same name.Flow control
An IF-THEN-ELSE construct is available for conditional execution and two forms of FOR-NEXT construct are provided for looping. A "GO TO ''label''" statement is provided for jumping, while a Fortran-like computed GO TO statement can be used fort multiple branching. An ON ERROR mechanism, with several options, provides a means for error handling.Linkule writing
Linkules are functions usually written in Fortran (or, unsupportedly, in C). With the aid of Mortran or C macros and an API library, they can interface the Speakeasy workarea for retrieving, defining, manipulating any Speakeasy object. Most of the Speakeasy operational vocabulary is implemented via linkules. They can be statically linked to the core engine, or dynamically loaded as they are needed, provided they are properly compiled as shared objects (unix) or dll (windows).Notes
External links