logo To Foot
© J R Stockton, ≥ 2007-03-31

Other Computing Languages.

No-Frame * Framed Index * Frame This
Links within this site :-

The language AMPERE

Readers may be familiar with untyped languages like assembler, weakly typed ones like C/C++, and strongly typed ones like Pascal and Delphi; and with the advantages that strong typeing can confer as long as it can be overridden. And familiar with the need for a physical calculation to be dimensionally correct, and with the proportion of silly errors that an early dimensional check can catch.

In the monthly European Journal of Physics, some while ago, there was an article, in French, about a programming language "AMPERE".

Search results, 2007-03-25 :-

An IoP page "European Journal of Physics / Volume 11, Number 3, May 1990" includes :-

163  AMPERE: a programming language for physics
     M Babout, H Sidhoum and L Frecon
     Abstract  |  References       Full text:  Acrobat PDF (684 KB)

but that PDF is subscribers-only. The Abstract is accessible at IoP. Abstract and References is accessible at UIUC.
Bibliographic Reference :- M Babout et al 1990 Eur. J. Phys. 11 163-171.
AMPERE: un langage de programmation pour la physique. Michel Babout, Hafid Sidhoum et Louis Frecon.

At CNRS :- Résumé - Conception et compilation du langage Ampère 2: langage modulaire pour la programmation physique. That is catalogue entry for a different paper, authors given as "Sidhoum Hafid ; Frecon Louis".

This was, as I recall, a generally Pascal-like language, but the typeing was extended to confer dimensions (such as mass, length, time, current) on variables, and to check that the operands of addition-type operators, and the sides of assignments, matched, and that procedure parameters were dimensionally correct. It struck me as rather a good idea, and not unduly difficult to add into a compiler. Such checks can go much wider than dimensions [MLTI] - for example, in salary work :- Payment := (Pounds/hour) * (hours/day) * (days worked) ; needs to have hours and days "cancel".

Dimension checks should be done at compile time. In cases where this is not possible, they might also be done by associating with each number an array of dimension powers, indexed by enumerated dimension :-

     type Dims = (mass, length, time) ;
     DimArr = array [Dims] of shortint ;
     Value = record D : double ; A : DimArr end ;
     const SmallGee : Value = (D : 9.81; A : [0, 1, -2]) ;

and writing routines to add, multiply, ... these with appropriate regard to dimension.

Input/output should also be typed; the default output for a metric weight should be of the form "[number] kg", and for an imperial one "[number] lb"; input checking would reveal the sort of error which seemingly destroyed Mars Climate Observer (Risks Digest 20.61, etc.). Metric and Imperial lengths would be converted using exact conversion factors : 0.3048 m/ft, 12 in/ft, etc.

Conversion between, say, dollars and euros would only be allowed with a suitable factor provided at run-time. That would, of course, not necessarily represent the current exchange rate. Addition or subtraction of dollars and euros would require conversion, or give NaN.

I've seen a citation of CACM May 1978, Karr and Loveman, "Incorporation of Units into Programming Languages".

Cardinals and Ordinals

Cardinal numbers - one, two, three, ... - are for counting, where the emphasis is on the total; ordinal numbers - first, second, third - are for expressing position, where the order is important. Day-in-Month is clearly ordinal, starting with the 1st; Year Number, being Year-of-A.D., is also ordinal. The difference of two ordinals is a cardinal.

Birthdays are anniversaries, ordinally marking a cardinal number of completed years.

In a Delphi newsgroup, someone wrote :-

... when you perform a calculation using the difference between two TDateTime values, store the result in a numeric variable. That way you'll be less likely to use the result as if it were a sensible TDateTime value.

OTOH, adding or subtracting a number to a TDateTime variable does give a result that is sensible as a TDateTime value.

Agreed : the difference of two TDateTimes is to be treated as a Double.

This is an example of a more general rule, where there is a distinction between a pure number (Cardinal) and a number relative to a base (which may be labelled zero) - an Ordinal.

For example, the difference between Sunday the 21st day of May and Thursday the 11th day of May is 10 days, and is certainly not an actual date. And the difference between fifth in line and second in line is minus three places, not "minus third".

The sum of two TDateTimes is not really meaningful of itself; and the product or ratio are not, either.

Perhaps the concept of "type" should be enlarged to distinguish Ordinals, including appropriate checking. Ordinals are more like a (non-explicitly) enumerated type, though enumerateds cannot be subtracted as such.

JavaScript Date and Time 0 refers.

Uncertainties

This does not require a new language; but it would go more nicely into one.

Readers may be familiar with the use of structured variables; and with the tedious process of working out the uncertainty in a measurement result from the uncertainties in the calibration inputs, the scatter of the raw observations, and the uncertainties of the method itself.

I myself have had to handle uncertainties in a moderately complicated calculation.

I programmed the system to calculate with uncertainties - instead of just declaring simple variables, just about all non-integer variables were records containing [value, (systematic, random) * (arithmetic, RSS) uncertainties, validation status], and all arithmetic combined these accordingly. This means that an uncertainty budget is merely a planning exercise; the answers appear with their actual uncertainties, including in this case the contribution from scatter of readings. In addition, I included a marker for the reliability of the value, ranging from definitely wrong (test only) through correct, validated traceable to standards, and perfectly certain (Pi, for example; or variables which defaulted to 0 or 1).

The method, once understood, is not too difficult to implement with care (and strong typeing is a great help), though TurboPascal's inability to have a record type as a function result is tiresome to work around. One does need to think about each arithmetic operation and the possible correlations of its inputs (but one should do so anyway); one must avoid redundant operations. Later languages allow record results; it would be even nicer if infix notation could be used for binary operators, or if operator symbols could be overloaded.

Where noise and scatter is significant in the final uncertainty, this allows one to take just enough readings to make the result as accurate as is being paid for.

New Structures

For Pascal-like languages.

IF

If every IF needs terminating - I'd choose ENDIF - rather than applying only to a single statement, then there is no need for THEN and ELSE to be limited (like WHILE) to a single statement; they can be like REPEAT.

Then the following is unambiguous :-


   IF boolean expression

      followed by as many as you like, in any order, of

   THEN | ELSE | BOTH | DONT <statements>

      followed by an ENDIF.

BOTH is to introduce parts done whatever the boolean value was; DONT for parts that are never done (but must compile). BOTH is evidently useful; DONT is evidently trivial, and adds completeness. The structure is nestable.

DEC's Macro-11 assembler had conditional assembly equivalent to that.

LOOP

An unconditional loop would be nice :-

  LOOP <statements> IF B THEN BREAK ; <statements> ENDLOOP ;

  LOOP <statements> EXITIF B ; <statements> ENDLOOP ;

FOR control

The control variable of a FOR loop is usually unwanted or undefined after termination. It could, therefore, be declared within the loop, and be loop-local in scope.

   FOR J : integer = 0 to N DO ... ;

Existing syntax could remain, for the cases where it is needed.

FOR Lists

Algol 60 had useful FOR lists, in which an element can be an assignment, a step, or a while :-

   FOR J := 1, 3, 5 STEP 2 UNTIL 11, 2*J WHILE J<99 DO ... ;

A REPEAT would also be useful.

Array Sizes

With conditional compilation and untyped constants, the size of a Pascal/Delphi array can be parameterised; it can be declared as [1..N] and processed with for J := 1 to N do ... ;.

The FOR loop itself is perfectly meaningful for N≤0; it does nothing.

Correspondingly, it should be made possible to dimension an array as [1..N] with N≤0; it would use no space, it could be "assigned" or "copied", using no instructions; but it would have no elements to access individually. Each instance of it might need a unique address; but need not consume any address space.

Links

Home Page
Mail: no HTML
© Dr J R Stockton, near London, UK.
All Rights Reserved.
These pages are tested mainly with MS IE 7 and W3's Tidy.
This site, http://www.merlyn.demon.co.uk/, is maintained by me.
Head.