This is one of the STIPPLE Documentation pages.

STIPPLE Rationale

The rationale roughly follows the outline of the reference manual. Thus, appendix section A.1 roughly corresponds to chapter 1, appendix section to chapter 3, etc.

Introduction

What does STIPPLE mean and why make it a registered trade-mark.

STIPPLE stands for Strongly-Typed Internationalizable Parameterized Programming Language, Extensible.

The intention is to make STIPPLE readily available to the public. By making STIPPLE a registered trade-mark, I have some legal recourse on the use of the STIPPLE programming language.

Why improve programmer productivity

The reasons for improving programmer productivity are:

Why static type-checking

The reasons for static type-checking are: The arguments in favor of dynamically type-checked code are: For STIPPLE, it is felt that the cost-benefit ratio for static type checking versus dynamic type checking is in static type checking's favor. In addition, if it is desired, there is a relatively easy way to achieve dynamic type checking in STIPPLE.

Why parameterized types

Parameterized types are a pretty complicated feature to add to any programming language. In addition, they tend to be used primarily for lower level abstractions such as lists, vectors, tables, trees, sets, etc. However, they are extremely useful for these low-level abstractions. In a strongly typed language without either parameterization or typecasts, it is necessary for the programmer to duplicate code for different instantiations of these low-level abstractions. Duplicated code wastes space, is error prone and is difficult to maintain. Thus, even though good type parameterization is difficult to add to a language, it appears to be worthwhile.

Why referential integrity

Referential integrity is accomplished by ensuring that there are never any variables or objects that contain values that do not point to objects of the correct type.

The reasons for referential integrity are:

Referential integrity is accomplished by ensuring that there is always at least one object of every type that is assigned etc.

Why garbage collection

The advantages of garbage collection are: The disadvantages of garbage collection are:

Why modularity

There is plenty of evidence in the literature that defining clean, well-defined interfaces to the data and algorithms that make up a program enhances its maintainability. Anything that improves program maintainability directly improves programmer productivity, since programmers spend a great deal of time maintaining code.

The STIPPLE language is a little different from other languages in that the interface definitions are not kept in separate files. Instead, the STIPPLE compiler has the ability to directly extract the interface information from the source code that defines a module. Another compiler mode enables the extraction of the module documentation.

Why object-oriented

The term "object-oriented" is ill defined. STIPPLE definitely has objects and operations on those objects; it also supports a restricted form of inheritance; it definitely does not support the C++ model of static and dynamic inheritance. So depending upon your definition of what features must be in an object oriented language, STIPPLE either is or is not "object-oriented."

The most important feature that STIPPLE supports is the concept of data abstraction. The literature abounds with evidence that cleanly separating the implementation of an abstraction from its use improves code comprehensibility and maintainability. It is the data abstraction aspects of object-oriented programming that is directly supported by STIPPLE.

For some people, type inheritance (i.e. sub-classing) is the most critical aspect of an object-oriented programming language. STIPPLE supports explicit static inheritance (including multiple inheritance.) It is explicit in the sense that each "sub-class" must completely list all of the operations it supports. By making everything explicit, the user of a "sub-class" need only look at the "sub-class" definition to know what it can and can not do. Dynamic inheritance stores the pointer to a virtual function table with each object. While STIPPLE permits the user to manually construct and access a virtual function table, it does not provide much assistance in constructing such tables. The operation vectors provided by parameterized types are the closest construct to virtual function tables produced by STIPPLE.

Why exception handling

It is very difficult to write a routine that does not have any failure modes. Without exception handling, the way failure modes are communicated to the user of a routine is done in an ad hoc fashion (e.g. returning a special value and testing for it at the call site.) With a language supported exception handling scheme, the interfaces to routine failures are well defined and consistent.

STIPPLE supports a single-level termination model for exceptions. When a routine signals an exception, control is transferred to an appropriate exception handler in the caller. Some languages support the continuation model of exceptions where the exception handler can return control back to the signal point. This model was rejected due to its complexity and relative lack of utility.

A multi-level exception model permits a signal handler to reside several levels up in the call stack. The multi-level model was rejected because it violated data abstraction and could easily leave behind damaged data structures. The STIPPLE resignal statement provides an easy way of passing a signal through a routine.

Why internationalization

Programming is an international profession. It seems rather silly to ask a bunch of programmers that live in a country and speak its native language to write programs in English or mixed English and another language. None-the-less, that is currently what happens, since current compilers require that all keywords be written in English. STIPPLE provides keywords in the native language. In order to support this feature, STIPPLE always spells keywords in their entirety so that they can be easily translated to different languages.

The STIPPLE compiler also has a mode that helps translate code from one native language to another. This is accomplished with the aid of a manually created translation table that provide translations for comments and symbols within a given program. This enables the development and maintenance of software between people who do not use the same native language.

There is an international market for software. In order to meet this market, applications must be designed so that they can be localized to a particular native language. STIPPLE directly supports this ability to localize programs by providing two kinds of string literals and a special kind of comment called a translation hint comment. String literals enclosed in single quotes are meant to be translated for localization, whereas string literals enclosed in double quotes are not translated. There is a compiler mode that extracts a table of translation hints and translatable strings. Somebody manually translates the strings using the translation hints as guide. These translated strings can be picked and used up by the application without requiring any recompilation or relinking.

Why make STIPPLE readily available

It is very hard for a proprietary language to succeed. Most organizations are unwilling to write software in a programming language that is only available from a single source (unless, of course, they are the source of the language.) While a language can succeed if the first implementation is not freely available (e.g. PostScript), it has a greater chance of seceding if the first implementation is freely available. If making money is an objective, publishing the definitive reference manual is always a possibility.

Why a portable compiler

A new programming language that can not be run a wide variety of machines is not competitive with languages that are. For this reason, STIPPLE is portable. Extra effort has gone into the ANSI-C code generator to make the resulting code quite readable.

Why a portable debugger

Programmers are human and they write buggy programs. A portable compiler without a portable debugger only solves half of the portability problem. By providing a portable debugger, it is that much easier for people to adopt STIPPLE.

Why extensible

All successful languages evolve over time. The ready availability of the basic STIPPLE compiler in source code form should encourage the experimentation of various language features. STIPPLE is architected to support this experimentation. This is accomplished by structuring the syntax to easily support the addition of new keywords without breaking existing programs (i.e. keywords are not reserved words as they are in most compilers.) In addition, STIPPLE has the version and extension declarations. The version declaration is required for every source file and it specifies which version the language the source code is written in (e.g. "1.0", "1.1", "2.0", etc.) The extension declaration is used to explicitly enable a named language extension that has been added to the compiler. When an extension gains wide-spread acceptance, it is folded into the basic compiler and the compiler version number is incremented.

Why word processor compatible

Word processors have a number of features that are not found in the typical plain text editor. These features include the ability change fonts, draw pictures, create tables, check spelling, etc. All of these features can be used to increase the readability and maintainability of software. For this reason, STIPPLE permits code to be written using a word processor.

Overview

Why have iterators

Without the concept of an iterator, some abstract data types have to expose more of the internal representation to the user than is necessary. Alternatively, they have to cobble together their own way of doing iteration. It is better to make iterators a first-class concept in the language so that everybody uses the same way to implementing them.

Iterators can be thought of as co-routines that are executed inside of loops.

The requirements and desirable characteristics for iterators are:

Why initial objects

The overall goal of STIPPLE is to have referential integrity. This means that when a composite type is created it must have all of its pointers initialized to point to a valid object. One solution to this problem is to have a constructor syntax that requires the programmer to provide initial values for all of the pointers when a composite object is created. For recursive record types, there is a "chicken-and-egg" problem. (The next and previous fields in a doubly linked list are obvious examples of recursive record types.) Since an instance of the recursive record type is needed to create another instance of the type, there is no way to create the first instance. In CLU, it was necessary to break the data structure recursion with some sort of variant. Initial objects solve the recursive record problem rather elegantly.

Since STIPPLE initializes all composite objects to point to initial objects at create time for referential integrity purposes, there is no need to have syntax that combines object creation with object initialization. However, for record types it is still useful to have to have the ability to force the explicit initialization of all fields. A common cause of bugs is adding a field to a record type and then forgetting to initialize the field in all locations where the record is created. In order to combat this common bug, STIPPLE provides the initialize statement.

Lexical Issues

Why use indentation

The reason for explicitly using indentation is to make it possible for the compiler resilient to single character errors, such as, missing semicolons (`;'), missing braces (`{', `}'), missing parenthesis (`(', `)'), etc. By requiring that the program be properly indented, whenever the compiler is having problems parsing a statement, it can give up and continue to the next statement. Another advantage of using indentation is that it eliminates a whole discussion of where to put braces.

Why use sharp ("#") for comments

The reasons for using sharp (`#') for comments are

Why identify program identifiers in comments

If an organization ever decides that it is going to maintain translated versions of code, it may have a totally separate department that is responsible for doing comment translations. (In general, it is doubtful that a having a separate translation department will yield the greatest of translations.) By translating the program identifiers separately from the rest of the comments, a programmer can change an identifier without causing all comments that use it to be gratuitously retranslated by the translation department.

Why use full word keywords

The reason for always using full words and phrases in STIPPLE keywords is to make it easier to translate the keywords into another language.

Why keywords are not reserved

The primary reason why keywords are not reserved is to support extensibility. If keywords are reserved identifiers, an extension that needs to add a new keyword might break existing programs that already use the keyword as a regular identifier. Another reason is because people sometimes forget that they are using a reserved word as an identifier; the resulting error messages can be quite confusing. (For example, for a long time the keyword entry was reserved in C, but not used for anything. The error messages that resulted from using entry as an identifier could be quite confusing.)

Notational Issues

The Prelude Declarations

Why constrain declaration order

The order in which declarations are specified is constrained because helps improve uniformity between code. With the exception of requiring the language and version declarations to be first, there is no technical reason for imposing an order on the declarations.

Why support conditional compilation

In a production environment, there is a need to recompile an application to support multiple different configurations. If conditional compilation is not directly supported by the language, it will be grafted on via a macro preprocessor. By making conditional compiliation be directly supported by the compiler, it is better integrated into the language. Why variadic procedures

Type Declarations

Routine and Object Declarations

Why have implicit initial objects in needs clauses

Some implementations of a parameterized procedure will need to define variables with same types as the parameters. Sometimes the definition of a variable needs to be initially assigned the initial object for the type. If the initial object for parameters where not implicitly passed in via a needs/variadic_needs clause, they would have to be explicitly specified in the needs/variadic_needs clause. The problem with explicit specification is that it is reflecting the implementation of a procedure up to the abstract procedure interface. Thus, if an implementor suddenly decides they need the initial object for a parameterized type, they would have to change the procedure's abstract interface. It seems incorrect to have changes in a procedures implemention require changes to its abstract interface and the subsequent recompilation of the code at all its use sites. This is the reason why the initial objects for parameterized types are implicitly passed in for needs/variadic_needs clauses.

Why support variadic procedures

There are two reasons for supporting variadic procedures in STIPPLE, despite their obvious complexity. First, they seem to provide the best solution to support internationalized print strings. Second, there are some applications that can naturally use variadic procedures.

In C, output is frequently done using a function called printf. The printf function takes a format string, followed by a list of arguments to be printed. The format string is printed character-by-character to the output until a percent character (`%') is encountered. At this time the next argument is printed to the output stream uses the letter following the percent character (`%') to specify the output format for the argument. (Additional characters between the percent and the letter specify additional formatting control.) In additions, the X/Open version of printf permits the user to specify format strings that print arguments out of order. This feature is used for internationalization because it permits the person doing localization to print output in a form more natural for the local language. A draw-back of the X/Open feature is that a mistake in the localization can cause the application to dump core if the wrong argument type is specified (e.g. string instead of integer.)

One major problem with the printf function is that it only supports the output of base types. C++ addresses this problem with streams and the overloading of left shift operator (`<<'). Unfortunately, the order of text and arguments is hard coded into the application and is unchangeable by the localization process. For this reason, the C++ solution is not acceptable for STIPPLE.

Statements

Expressions


From here you can backt to the table of contents.
Copyright (c) 1991 -- Wayne C. Gramlich. All rights reserved.