ACCU Home page ACCU Conference Page
Search Contact us ACCU at Flickr ACCU at GitHib ACCU at Google+ ACCU at Facebook ACCU at Linked-in ACCU at Twitter Skip Navigation

pinAlgol 68 – A Retrospective

Overload Journal #148 - December 2018 + Programming Topics   Author: Daniel James
Algol 68 has influenced programming languages in many ways. Daniel James reminds us just how many.

This month marks the 50th anniversary of the inception of the Algorithmic Language Algol 68 – the first programming language I ever learned, back in 1974 when I first encountered these things called computers, as an undergraduate.

I wrote ‘inception’ … perhaps a little background overview is required.

Nowadays we have more programming languages than you can shake the proverbial stick at, and computers that can shake the stick for you, but in the early 1960s there were really only three major languages available: COBOL for business programming, and FORTRAN and Algol for scientific work (LISP was also around, and deserves an honourable mention, but I’d hesitate to call it ‘major’). The latter two were designed with slightly different goals in mind: FORTRAN (FORmula TRANslation) was developed at IBM specifically for programming computers, while Algol (ALGOrithmic Language), developed by a European and American team at ETH Zurich, was designed also to enable the expression of algorithms in a concise but human-readable form.

FORTRAN was the more widely used – in part because it had IBM behind it, but also because it was seen as the more portable language. The designers of Algol decided not to specify standard input and output operations as they felt that language implementers were better placed to define these facilities for the platform on which they were working. This meant that each new implementation of Algol had its own non-portable i/o functions, and this lack of portability had an impact on the acceptance of Algol.

As the 1960s progressed, a number of new languages appeared and the existing languages were further developed. The IFIP Algol Working Group 2.1 [Wikipedia-1] was formed in 1962 to design a replacement for Algol 60 that was then code-named Algol X. Many ideas were discussed, some in the light of experience of similar features in other languages, but no complete implementation of any proposed candidate for Algol X was produced before the language was formally accepted. This acceptance came when the WG 2.1 members met in December 1968 and voted to accept the language specification [Original] as it then stood, without ever seeing a working prototype. This is the language that became known as Algol 68.

Their decision was by no means unanimous, with some of the committee saying that the language had become over-complex and had lost the simplicity of Algol 60. Some of these famously went on to publish their dissent as the ‘Minority Report’ [Minority], in which they claimed that the language was a failure.

The style of the language reports deserves a mention. The reports are written using a two-level grammar in which the first level defines a meta-language, and the second defines Algol 68 in that meta-language. This style is known as a Van Wijngaarden grammar, after Adriaan van Wijngaarden who invented it and was also instrumental in bringing about the final design of Algol 68. The style of the reports also accounts for their legendary impenetrability to the casual reader.

In July 1970 a conference to discuss Algol 68 implementation [Peck70] took place. While many of the delegates presented papers that discussed the difficulty of implementation of the new language, the small team from the Royal Radar Establishment presented their working compiler for a substantially complete subset of the language that they called Algol 68-R [Wikipedia-2]. Algol68-R was already in daily use for production code on the ICL 1907F computer at RRE, where it had replaced Algol 60 for new development. The Algol 68-R compiler was later distributed without charge by ICL to other users of 1900-series hardware, and it was this compiler that I first used when I went to University.

Development of Algol 68 continued into the 1970s and a revised edition of the Algol 68 Report [Revised] was published in 1975. The team at RRE (by then known as the Royal Signals and Radar Establishment) produced a new version of their compiler called Algol 68-RS, which ran on, among other things, the newer ICL 2900-series mainframes and Dec VAX minicomputers.

A brief overview

So, what sort of language is Algol 68? I’m going to talk mostly about the language of the Revised Report because it is a little more complete than the original language and has fewer idiosyncrasies, but the differences are slight and mainly cosmetic.

An expression-oriented, block-structured, procedural language

Algol 68 is an ‘expression-oriented’ language in that almost every statement – what the Revised Report calls a unit (the original report used the term ‘unitary clause’) – delivers a value, and so can be treated as an expression. Every expression can also legally be used as a statement. If a unit has no value to deliver, it returns the special type VOID. If an expression that yields a value but doesn’t do anything with it, such as

  41+1

appears as a statement on its own, the compiler is likely to offer a warning that the result is to be discarded, but the code is legal.

Declarations aren’t classed as units, and aren’t expressions. A sequence consisting of units or declarations and units separated by semicolons is called a series (originally ‘serial clause’) and has the value of its last unit. Note that the semicolon is a separator, not a terminator: there shouldn’t be one after the last unit in a series.

Algol 68 is a block-structured language in that a program is composed from nested lexical blocks. Each new block introduces a lexical scope that limits the lifetime and visibility of constructs declared within that scope. Each new scope inherits from any containing scope. A block – and everything it contains – is syntactically a unit whose value is the value of the last statement in the block.

A block may simply be one or more statements enclosed between BEGIN and END, or may be a conditional such as IF or CASE, or a loop.

Algol 68 is a procedural language in that its programs are built-up from procedures. A procedure in Algol 68 may be a function that returns a result, or may be a pure procedure that returns no result, in which case its return type is specified as VOID. The body of a procedure is a unit.

As is the case in Algol 60 and some other languages (such as Pascal), but not C or C++ (at least until lambda functions were introduced in C++11) procedures in Algol 68 do not have to be declared at the outermost lexical scope but can be declared within a program block, even a block of another procedure.

Algol 68 also supports user-defined operators, which are defined identically to procedures except that operators can have only one or two arguments. The user can set the priority (from 1 to 9) of an operator symbol, and can define new operator symbols. Operators can be overloaded, however, while procedures cannot.

Basic types

Data types in Algol 68 are called MODEs. The MODEs provided as standard are mostly unsurprising (see Table 1).

INT Signed Integer. Single machine word.
REAL Single-precision floating point number.
COMPL Complex number.
BITS Binary value, packed Booleans.
BYTES Packed characters (provided for efficiency on architectures that are not byte-addressable, such as the ICL1900)
All of the above modes may be prefixed with LONG or LONG LONG to get double or higher precision, depending on the implementation.
CHAR Character. Implementation defined representation.
BOOL Boolean value
Table 1

Additional MODEs are defined in terms of these simple types. A MODE declaration associates an identifier with a MODE as an alias for the full definition.

Derived types

References

Algol 68 supports reference types using the REF keyword, so a reference to an INT type would be written REF INT. Syntactically Algol 68 references are more like C pointers than Java references, and they can be set to a null value which is written NIL.

Algol 68 uses the term ‘name’ when talking about anything that has a reference type. This term is equivalent to ‘lvalue’ in C, and means that a value can be assigned to it. The term ‘identifier’ is used to refer to symbolic names used in source code.

References can be compared for equality using the built-in IS and ISNT operations.

Arrays

Algol 68 supports single- and multi-dimensional arrays. Subscripts are written between square brackets.

  MODE MATRIX = [1:5,1:5] REAL

The lower bound of an array defaults to 1, but may be any value less than the upper bound – even negative. An array ‘knows’ its bounds, and these can be queried at runtime using LWB and UPB. Like Algol 60 and C (but unlike FORTRAN) Algol 68 stores arrays in row major order.

Arrays can be flexible. The built-in STRING datatype is defined as a flexible array of character values:

  MODE STRING = FLEX [1:0] CHAR

Arrays can be sliced. If r is a [1:10]INT then r[3:7] is a [1:5]INT.

The use of flexible arrays implies the use of dynamic (heap) allocation. No explicit deallocation is necessary as this is managed using garbage collection.

Structures

Data structures are defined with the keyword STRUCT. For example the standard type COMPL is defined as:

  MODE COMPL = STRUCT( REAL re, im )

Fields of a structure are selected using the OF keyword (not an operator):

  re OF complexvalue

A structure type may not contain members of that type, but may contain references to that type, so it is possible to write linked lists, binary trees, etc. Listing 1 shows how this may be used to implement linked list functionality.

# (Unordered) Linked List example #
# Demonstrates using HEAP storage #
MODE ELEMENT = STRING;
MODE NODE = 
  STRUCT ( ELEMENT value, REF NODE next );
MODE LIST = REF NODE;
LIST empty = NIL;

# Add an element to the end of the list #
PROC append = ( REF LIST list, ELEMENT val ) VOID:
BEGIN
  IF list IS empty
  THEN
    list := HEAP NODE := ( val, empty )
  ELSE
    REF LIST tail := list;
    WHILE next OF tail ISNT empty
    DO
      tail := next OF tail
    OD;
    next OF tail := HEAP NODE := ( val, empty )
  FI
END;

# Add an element to the beginning of the list #
PROC prepend = 
  ( REF LIST list, ELEMENT val ) VOID:
  list := HEAP NODE := ( val, list )
  
# Print the list out - using a loop #
PROC print list = ( LIST start ) VOID:
BEGIN
  IF start ISNT empty
  THEN
    REF NODE ptr := start;
    WHILE
      print(( "-- ", value OF ptr, newline ));
      next OF ptr ISNT empty
    DO
      ptr := next OF ptr
    OD
  FI;
  print(( "End of list", newline ))
END;

# Print the list out - using recursion #
PROC print list recursively = ( LIST start ) VOID:
BEGIN
  IF start IS empty
  THEN
    print(( "End of list", newline ))
  ELSE
    print(( "-- ", value OF start, newline ));
    print list recursively( next OF start )
  FI
END;
			
Listing 1

The identifiers given to the fields of a structure are part of its type, so two structures containing the same types of fields but with different field names would not be the same type.

Unions

Unions are defined with the keyword UNION.

  MODE STRINT = UNION( STRING, INT )

An Algol 68 union ‘knows’ the type of its current value, and this may be queried at runtime.

Declaration and assignment

A declaration associates an identifier with some value, and uses the ‘equals’ symbol =. The following introduces a new identifier called ultimate answer that represents the integer value 42:

  INT ultimate answer = 42 

Note that white space is not significant within an identifier, so this could equally well be written ultimateanswer or ulti mate answ er.

A variable can be created simply by naming it and its type:

  REAL half pi

The example above introduces a new identifier half pi and associates it with the storage for a variable in the current scope. This is shorthand for:

  REF REAL half pi = LOC REAL

which says that half pi is a constant identifier that represents a reference to a REAL and is initialized to some location allocated on the stack. Although this long form is used by a lot of the early Algol 68 literature, it isn’t really necessary. It is a bit like saying that the declaration of a float variable in C++ is equivalent to:

  float & half_pi =
    *(float*)alloca( sizeof(float) );

It does, however introduce the concept of a generator. In the example above, LOC REAL is a generator that allocates local (stack-based) storage for a REAL variable. Whilst it is never necessary to use this long form with the explicit LOC generator to create storage for a local variable, the use of a HEAP generator is the only way to allocate variables on the heap.

A value can be assigned to a variable using the ‘becomes’ symbol := in what Algol 68 calls an ‘assignation statement’.

  half pi := pi/2

Declaration and initialization can be combined into a single statement:

  REAL half pi := pi/2

Note that pi is a built-in constant of type REAL (higher precision versions – long pi, etc. – also exist).

The difference between the constant declaration (using the ‘equals’ symbol, =) and the declaration and initialization of a variable (using the ‘becomes’ symbol, :=) is slight, and they are easy to confuse.

Algol 68 also provides ‘updating’ operators like PLUSAB (‘PLUS And Becomes’) which can be abbreviated +:=. This syntax has been adopted by many other languages since.

Control flow

Conditions are supported by the choice statements, IF and CASE. These are identical in structure but the IF statement bases its selection on a BOOL value, while the CASE bases its on an INT value:

  IF boolvalue THEN some expression ELSE other  expression FI

  CASE intvalue IN expr1, expr2, …, exprN OUT  another expr ESAC

IN and OUT are CASE’s equivalents of THEN and ELSE. ELIF and OUSE are provided as shorthand forms of ELSE IF and OUT CASE.

That these really are equivalent constructions becomes more apparent when we learn that a BOOL value can be converted to an INT using the ABS operation, and that ABS TRUE has the value 1, while ABS FALSE is 0.

As with all statements in Algol 68, a choice statement may return a value, the value returned is the value of whatever expression is chosen (so long as all the expressions return the same MODE). While C and some other languages have a ‘ternary operator’ that allows one of two values to be used depending on some boolean condition. Algol 68 has no need of such a construction because the structure of the language allows an ordinary IF statement to be used.

This allows for constructions like:

days in month :=
  CASE month OF date IN
    31,
    IF is leap year( year OF date ) THEN 29 ELSE 28
    FI,
    31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  ESAC

IF and CASE introduce lexical scopes, just as BEGIN does. The scope ends with the closing FI or ESAC statement.

Spelling IF and CASE backwards to indicate the end of the block that they introduce is a device that Algol 68 uses in a number of places. The use of FI and ESAC has been adopted in some other languages, notably in the Bourne shell, while still more have taken up the idea but opted for keywords such as ENDIF – perhaps we should be grateful that END is not spelt NIGEB in Algol 68!

It’s interesting that C++17 introduces new ‘if with initializer’ [P0305R0] and ‘switch with initializer’ features that let one declare variables in the condition part of an if or switch statement that have the scope of the whole statement. This enables one to write things like:

  if( int val = get_value(); is_valid( val ) )
  {
    do_stuff_with( val );
  }

which is directly equivalent to the Algol 68 code

  IF INT val := get value(); is valid ( val )
  THEN
    do stuff with( val )
  FI

except that the Algol 68 form is more general.

Note that with the Algol 68 CASE statement there is no possibility that one case can run on into the next (even should you want it to) so there is need for any break-type statement, as in C (nor does the language support one).

Loops are supported by the very versatile Algol 68 DO loop, which has the general form:

  FOR counter FROM start BY step TO stop WHILE
  condition
   DO something OD

Everything here is optional, apart from the DO something OD part, which is the loop itself, the other parts just provide conditions that control the termination of the loop.

The counter, if present, is an integer whose scope is limited to the loop; by default it counts from 1 in increments of 1 but that can be changed using the FROM and BY parts. The loop terminates when the variable reaches the stop value, if specified, or when the condition becomes true … otherwise it will run for ever. The counter cannot be assigned to within the loop – it is not a variable but an INT constant that is re-created with a new value each time around the loop.

The condition of a loop including a WHILE part is syntactically a series of declarations and statements. This syntax caters for cases in which all or part of the body of the loop is to be executed before the WHILE condition is evaluated.

  WHILE INT n; read( n ); is valid input( n )
    DO process( n ) OD

If the whole of the loop is to be executed before the test (as with a do ... while loop in C, for example) the do-nothing operation SKIP can be used to satisfy the syntactic requirement for one or more statements between DO and OD. The Algol 68 DO loop offers all the varieties of loop control that are provided by the for, while, and do ... while constructions in C but with greater flexibility.

Unlike most other constructions in Algol 68, a loop does not return a result.

Here are some examples. These also show three forms of COMMENT, and a call to the built-in print function. Note that the call to print uses two sets of parentheses because multiple values are being printed; the inner pair belong to the representation of the single argument, which is in effect an array of UNIONs of various types.

  
  # Zero all elements of ar from lower to upper 
    bound #
  FOR index FROM LWB ar TO UPB ar DO
    ar[index] := 0
  OD
  CO enhance a until it is greater than some
  threshhold CO
  FOR i WHILE a < threshhold DO
    print( ( "After ", i, " iterations a is ", a,
      newline ) );
    a := enhance( a )
  OD

  COMMENT sound an alarm 10 times COMMENT
  TO 10 DO sound alarm OD

For completeness, and to annoy purists, Algol 68 also supports GOTO.

Procedures

Algol 68 procedures take a number of parameters, possibly zero, and return a result or VOID. A procedure is defined like so:

  PROC twice as much = (INT i) INT: i+i

This defines a procedure named twice as much which takes a single integer parameter by value, and returns an integer result. The body of this procedure is a single statement and so doesn’t need to be enclosed in a block, but most procedures do.

In this definition, the procedure denotation (INT i) INT: i+1 is assigned to the identifier twice as much, which therefore has the mode PROC (INT) INT. As with data quantities, though, the procedure body could be assigned to a procedure variable identifier

  PROC operation := (INT i) INT: i+i

We could then, elsewhere in the program, change the value of that procedure:

  operation := (INT foo) INT: 3*foo+7

Listing 2 shows another example of a function denotation being used as a lambda.

# Print a table of values #

# print a table of values of f(angle) #
# for angle from start to stop (degrees) #

PROC print trig =
  ( REAL start, REAL stop,
    PROC (REAL) REAL f ) VOID:
BEGIN
  REAL val := start;
  
  printf( $" Deg |"$ );
  FOR i FROM 0 TO 9 DO printf(( $z-d.dx,b(l,x)$,
    i/10, i=9 )) OD;
  printf( $5"-" "+" 71"-"l$ );
  
  FOR col FROM 0 WHILE val < stop
  DO
    IF col MOD 10 = 0 
    THEN 
      printf(( $zd.d" | "$, val ))
    FI;
    
    printf(( $+d.3d,b(l,x)$, f((val*pi)/180),
      col MOD  10 = 9 ));
    val +:= 1
  OD
END;

# Print a table of sin(x) using the built-in 
  sin function #
print(( newline, "Printing sin x", newline ));
print trig( 0, 90, sin );

# Print a table of sin^2(x)+cos^2(x) using a lambda #
print(( newline, "Printing sin^2 x + cos x",
  newline ));
print trig( 0, 90, (REAL n) REAL: sin(n)^2+cos(n))
			
Listing 2

The procedure body that we assign in this way is effectively a lambda function. No special syntax is needed for lambda, the functionality is a natural consequence of the design of the language.

Transput

Transput is the word used in the Algol 68 reports to refer to both input and output.

One of the big shortcomings that was recognized in Algol 60 was its lack of any standardized i/o system. The designers of Algol 68 addressed this lack by introducing a standard system for both formatted and formatless output. We have already seen the procedure print, which accepts any simple argument and outputs it in a standard way. This tends not to be very pretty as, for example, numbers are output in their maximum width and precision. This output can be tamed somewhat using built-in functions whole, fixed, and float that convert numbers to strings with specified width and precision.

There is also a system for formatted output that gives the programmer complete control over the format of the output by means of a format designator. This is similar to the format string of C’s printf, but is a special Algol68 FORMAT type, delimited by $ characters, and can be evaluated at compile-time for efficiency. A FORMAT consists of one or more ‘pictures’, separated by commas, each of which describes the layout of a single item.

Formatless input and output are achieved using the functions put and get. We have already seen the print function, which is equivalent to put but always uses the default standard output channel called stand out (similar to cout in C), there is also a read function that is equivalent to get using stand in. Formatted i/o uses putf and getf (and printf and readf).

These three produce identical output on stand out:

  put( stand out, (i, blank, r, newline ));
  print(( i, blank, r, newline ));
  printf(( $gx,gl$, i, r ))

If i is an integer with the value 42 and r is a REAL with the value 22/7 then this would produce three identical lines of:

  +42 +3.14285714285714e  +0

In the put and print cases, the list of items to be printed are enclosed in brackets because they are conceptually an array of values to be output. These include blank and newline, which are PROC(REF FILE) VOID functions that are called to manipulate the output stream.

In the printf case, the argument list begins with a FORMAT containing two pictures using g tags meaning that the values should be printed in the same default format as is used for formatless output, and x and l tags that supply the blank and newline.

Printing values without formatting is not the point of formatted output, of course, and one might more typically see something like

  printf(( $4z-dx,+3d.5dl$, i, r ))

The format string contains two pictures. The first depicts an integer with 4 digits that will be printed as blanks if they are all leading zeros (four z tags) followed by one digit that will always be visible (a d tag) and a space (x tag), with a sign character that will be a blank if the value is positive immediately to the left of the first non-zero digit (- tag) and then a blank (x tag). The second picture depicts a real number with a sign always shown (+ tag), and with three digits (three d tags) before and five digits after (five d tags) a decimal point (. tag), and then a newline (l tag).

With the values of i and r above, this would produce:

  42 +003.14286

Listing 2 shows some examples of formatted output.

Notation

In the Revised Report, Algol 68 is written in lower-case letters, with keywords emphasized in bold. Text files holding program source to be read by compilers don’t provide a mechanism for the representation of bold text, so keywords are typically written in upper-case, as I have done here. The original Algol 68-R compiler ran on ICL 1900 computers, which had a basic character set of only 64 characters. Lower-case characters were available only through a complicated system of shift prefixes, and weren’t used in programming. In Algol 68-R, keywords were distinguished from identifiers by enclosing them in single quotes, which was called ‘quote stropping’.

  'BEGIN'
  'INT' I := 42;
  PRINT(( I, NEWLINE ))
  'END'

Other upper-case systems used ‘dot stropping’, in which a keyword was prefixed with a dot character.

I’ve deliberately chosen a rather ‘wordy’ notation for the examples in most places in this article, but it is worth noting that Algol68 provides symbolic short forms for many operations. For example the pseudo-operators IS and ISNT can be written :=: and :/=: and the MOD operator can be written %*.

Algol 68 also allows round brackets to be used for BEGIN and END … or to look at it another way, Algol 68 treats any expression in round brackets as a BEGIN/END block.

Round brackets can also be used for IF, FI, CASE, and ESAC; vertical bar characters for THEN, ELSE, IN, and OUT, and vertical bar followed by a colon for ELIF and OUSE. It is usually clearer to spell things out, but the short forms can be useful when writing a one-liner.

Implementations

Algol 68 has been implemented on quite a variety of hardware platforms. There’s a good summary in the Wikipedia article [Wikipedia-3] and a lot of detail on the Software Preservation Society’s Algol 68 page [SPS]. In its heyday there were several implementations written in different countries – including the UK, the US, the Netherlands, and Russia – and supporting a wide range of hardware architectures. It was never as widely used as FORTRAN or COBOL, but it had a significant following.

Algol 68 was also the basis for a number of other languages, including the S3 job-control language of the VME/B operating system of ICL 2900 series mainframes, and influenced a good many more.

Most implementations of Algol 68 are no longer in use, as they were developed for computer architectures that are now obsolete. Some are still accessible in one form or another, for example the Algol-68R compiler can still be run under a GEORGE 3 emulator [GEORGE], part of the Algol 68RS compiler survives as the front end of the Algol 68 to C translator [A68TOC] from the ELLA project developed at RSRE and has been Open-Sourced, one of the two implementations named Algol 68S has been ported to a number of more modern platforms and Open-Sourced. A more recent implementation from 2001, Algol 68 Genie [van der Meer16], runs on Windows, Linux, and Mac systems and is Open Source; if you run a Debian-derived Linux distro such as Ubuntu or Raspbian you will find it in the standard repository.

Algol 68 has always had the undeserved reputation of being a large, complex, language for mainframe computers only. The language is actually smaller than C [Henney18], and certainly much smaller than many modern languages. I find it pleasingly ironic that the language I was always told would never catch on because it was too big for any but the largest of computers runs nicely on a Raspberry Pi Zero, on battery power, sitting on the palm of my hand – but perhaps that says more about developments in hardware in the last 50 years than it does about software.

Legacy

Algol 68 has influenced many other languages, many of which are still in widespread use today.

The influence of Algol 68 on C is clear, and Algol 68 is referred to many times by Bjarne Stroustrup when describing the development of C++ [Stroustrup94]. Indeed, Stroustrup notes [Stroustrup13] that “… my ideal when I started on C++ was ‘Algol 68 with Classes’ rather than ‘C with Classes’.

Finally, no discussion of programming languages would be complete without an implementation of FizzBuzz, so I present a modest example in Listing 3. Note here that in Algol 68 the AND operator between two BOOL values does not short-circuit – that is, both BOOL terms are fully evaluated even if the first is found to yield FALSE. Many implementations provide an alternative short-circuiting form usually called ANDF or ANDTH (for ‘and false’ or ‘and then’).

# Fizzbuzz in Algol68 #

print(( "Fizzbuzz from 1 to 100", newline ));

PROC fizz = (INT n) BOOL: 
    IF n MOD 3 = 0 THEN print( "fizz" ); TRUE ELSE FALSE FI;
    
PROC buzz = (INT n) BOOL: 
    IF n MOD 5 = 0 THEN print( "buzz" ); TRUE ELSE FALSE FI;

FOR i TO 100
DO

    IF NOT fizz( i ) AND NOT buzz( i ) 
    THEN 
        print( whole( i, 0 ) ) 
    FI;
    newline( standout )

OD
			
Listing 3

References

[A68TOC] The ELLA and A68toC source is available from: https://cs.nyu.edu/courses/spring02/G22.3130-001/ella/

[GEORGE] Algol 68-R included with the GEORGE 3 Emulator on the BCS Software Preservation and Machine Emulation pages. http://sw.ccs.bcs.org/CCs/g3/index.html

[Henney18] Kevlin Henney. Procedural Programming: It’s Back? It Never Went Away. From the 2018 ACCU Conference. https://www.youtube.com/watch?v=mrY6xrWp3Gs This talk has a good 10-minute account of Algol 68 from about 12 minutes in.

[Minority] Published in the Algol Bulletin, archived online at:http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A31/P111.HTM

[Original] The original report can be found here, scanned to PDF (without OCR): http://web.eah-jena.de/~kleine/history/languages/Algol68-Report.pdf

[P0305R0] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r0.html

[Peck70] Peck, J.E.L., ed. (1970), Proceedings of the IFIP working conference on ALGOL 68 Implementation, Munich: North-Holland, ISBN 0-7204-2045-8. Available online at: http://www.softwarepreservation.org/projects/ALGOL/paper/ALGOL_68-Implementation.pdf

[Revised] Revised Report on the Algorithmic Language Algol 68. Edited by van Wijngaarden, et al. Springer-Verlag (1976). An HTML version is available at: https://jmvdveer.home.xs4all.nl/en.post.algol-68-revised-report.html

[SPS] The Software Preservation Society pages on Algol 68http://www.softwarepreservation.org/projects/ALGOL/algol68impl/

[Stroustrup94] Bjarne Stroustrup. The Design and Evolution of C++. Addison Wesley (1994).

[Stroustrup13] Bjarne Stroustrup. The C++ Programming Language, 4th Edition. Addison Wesley (2013). Sec. 1.2.2.

[van der Meer16] Algol 68 Genie. Marcel van der Veer. https://jmvdveer.home.xs4all.nl/en.algol-68-genie.html

[Wikipedia-1] IFIP Working Group 2.1: https://en.wikipedia.org/wiki/IFIP_Working_Group_2.1

[Wikipedia-2] ALGOL 68-R: https://en.wikipedia.org/wiki/ALGOL_68-R

[Wikipedia-3]AlLGOL 68: https://en.wikipedia.org/wiki/ALGOL_68

Daniel James Daniel James has carried on programming in a variety of languages ever since that first brush with Algol 68 in 1974, and the sparkle has never quite worn off. He sometimes wonders how his life would have turned out if the friend who introduced him to computing had been a FORTRAN user, as all good scientists were supposed to be.

Overload Journal #148 - December 2018 + Programming Topics