Live data from Hacker News

GCC SC approves inclusion of Algol 68 Front End

gcc.gnu.org

61–70 of 115 posts

Re: GCC SC approves inclusion of Algol 68 Front End

#61

Will it compile Knuth’s test? https://en.wikipedia.org/wiki/Man_or_boy_test

That test is short enough to just paste it in here:

    begin
      real procedure A(k, x1, x2, x3, x4, x5);
      value k; integer k;
      real x1, x2, x3, x4, x5;
      begin
        real procedure B;
        begin k := k - 1;
              B := A := A(k, B, x1, x2, x3, x4)
        end;
        if k ≤ 0 then A := x4 + x5 else B
      end;
      outreal(1, A(10, 1, -1, -1, 1, 0))
    end
The whole "return by assigning to the function name" is one of my least favorite features of Pascal, which I suppose got it from Algol 60. Where I'm confused though is, what is the initial value of B in the call to A(k, B, x1, x2, x3, x4)? I'm guessing the pass-by-name semantics are coming into play, but I still can't figure out how to untie this knot.

Re: GCC SC approves inclusion of Algol 68 Front End

#62

Earlier quoted context omitted.

> it should have been a postfix operator, like in Euler and Pascal. I never liked Pascal style Pointer^. As the postfix starts to get visually cumbersome with more than one layer of Indirection^^. Especially when combined with other postfix Operators^^.AndMethods. Or even just Operator^ := Assignment. I also think it's the natural inverse of the "address-of" prefix operator. So we have "take the address of this value…

The "natural inverse" relationship between "address-of" and indirect addressing is only partial. You can apply the "*" operator as many times you want, but applying "address-of" twice is meaningless. Moreover, in complex expressions it is common to mix the indirection operator with array indexing and with structure member selection, and all these 3 postfix operators can appear an unlimited number of times in an expre…

> The only reason why they have chosen "" as prefix in C, which they later regretted, was because it seemed easier to define the expressions "++p" and "*p++" to have the desired order of evaluation.

There has been no shortage of speculation, much of it needlessly elaborate. The reality, however, appears far simpler – the prefix pointer notation had already been present in B and its predecessor, BCPL[0]. It was not invented anew, merely borrowed – or, more accurately, inherited.

The common lore often attributes this syntactic feature to the influence of the PDP-11 ISA. That claim, whilst not entirely baseless, is at best a partial truth. The PDP-11 did support pre-increment and post-increment indirect address manipulation – but notably lacked their symmetrical complements: pre-increment and post-decrement addressing modes[1]. In other words, it exhibited asymmetry – a gap that undermines the argument for direct PDP-11 ISA inheritance, i.e.

  MOV (Rn)+, Rm

  MOV @(Rn)+, Rm

  MOV -(Rn), Rm

  MOV @-(Rn), Rm
existed but not

  MOV +(Rn), Rm

  MOV @+(Rn), Rm

  MOV (Rn)-, Rm

  MOV @(Rn)-, Rm
[0] https://www.thinkage.ca/gcos/expl/b/manu/manu.html#Section6_...

[1] PDP-11 ISA allocates 3 bits for the addressing mode (register / Rn, indirect register (Rn), auto post-increment indirect / (Rn)+ , auto post-increment deferred / @(Rn)+, auto pre-decrement indirect / -(Rn), auto pre-increment deferred / @-(Rn), index / idx(Rn) and index deferred / @idx(Rn) ), and whether it was actually «let's choose these eight modes» or «we also wanted pre-increment and post-decrement but ran out of bits» is a matter of historical debate.

Re: GCC SC approves inclusion of Algol 68 Front End

#63
post #62

Earlier quoted context omitted.

The "natural inverse" relationship between "address-of" and indirect addressing is only partial. You can apply the "*" operator as many times you want, but applying "address-of" twice is meaningless. Moreover, in complex expressions it is common to mix the indirection operator with array indexing and with structure member selection, and all these 3 postfix operators can appear an unlimited number of times in an expre…

> The only reason why they have chosen " " as prefix in C, which they later regretted, was because it seemed easier to define the expressions " ++p" and "*p++" to have the desired order of evaluation. There has been no shortage of speculation, much of it needlessly elaborate. The reality, however, appears far simpler – the prefix pointer notation had already been present in B and its predecessor, BCPL[0]. It was not…

The prefix "*" and the increment/decrement operators have been indeed introduced in the B language (in 1969, before the launch of PDP-11 in 1970, but earlier computers had some autoincrement/autodecrement facilities, though not as complete as in the B language), where "*" has been made prefix for the reason that I have already explained.

The prefix "*" WAS NOT inherited from BCPL, it was purely a B invention due to Ken Thompson.

In BCPL, "*" was actually a postfix operator that was used for array indexing. It was not the operator for indirection.

In CPL, the predecessor of BCPL, there was no indirection operator, because indirection through a pointer was implicit, based on the type of the variable. Instead of an indirection operator, there were different kinds of assignment operators, to enable the assignment of a value to the pointer, instead of assigning to the variable pointed by the pointer, which was the default meaning.

BCPL has made many changes in the syntax of CPL, whose main reason was the necessity of adapting the language to the impoverished character set available on American computers, which lacked many of the characters that had been available in Europe before IBM and a few other US vendors have succeeded to replace the local vendors, also imposing thus the EBCDIC and later the ASCII character sets.

Several of the changes done between BCPL and B had the same kind of reason, i.e. they were needed to transition the language from an older character set to the then new ASCII character set. For instance the use of braces as block delimiters was prompted by their addition into ASCII, as they were not available in the previous character set.

The link that you have provided to a manual of the B language is not useful for historical discussions, as the manual is for a modernized version of B, which contains some features back-ported from C.

There is a manual of the B language dated 1972-01-07, which predates the C language, and which can be found on the Web. Even that version might have already included some changes from the original B language of 1969.

Re: GCC SC approves inclusion of Algol 68 Front End

#65
post #62

Earlier quoted context omitted.

> The only reason why they have chosen " " as prefix in C, which they later regretted, was because it seemed easier to define the expressions " ++p" and "*p++" to have the desired order of evaluation. There has been no shortage of speculation, much of it needlessly elaborate. The reality, however, appears far simpler – the prefix pointer notation had already been present in B and its predecessor, BCPL[0]. It was not…

The prefix "*" and the increment/decrement operators have been indeed introduced in the B language (in 1969, before the launch of PDP-11 in 1970, but earlier computers had some autoincrement/autodecrement facilities, though not as complete as in the B language), where "*" has been made prefix for the reason that I have already explained. The prefix "*" WAS NOT inherited from BCPL, it was purely a B invention due to K…

* was the usual infix multiplication operator in BCPL, and it was not used for pointer arithmetic.

The BCPL manual[0] explains the «monadic !» operator (section 2.11.3) as:

  2.11.3 MONADIC !

  The value or a monadic ! expression is the value of the storage cell whose address is the operand of the !. Thus @!E = !@E = E, (providing E is an expression of the class described in 2.11.2).

  Examples.

  !X := Y Stores the value of Y into the storage cell whose address is the value of X.

  P := !P Stores the value of the cell whose address is the value of P, as the new value of P.
The array indexing used the «V ! idx» syntax (section 2.13, «Vector application»).

So, the ! was a prefix operator for pointers, and it was an infix operator for array indexing.

In Richard's account of BCPL's evolution, he noted that on early hardware the exlamation mark was not easily available, and, therefore, he used a composite *( (i.e. a diagraph):

  «The star in *( was chosen because it was available … and it seemed appropriate for subscription since it was used as the indirection operator in the FAP assembly language on CTSS. Later, when the exclamation mark became available, *( was replaced by !( and exclamation mark became both a dyadic and monadic indirection operator».
So, in all likelihood, !X := Y became *(X := Y, eventually becoming *X = Y (in B and C) whilst retaining the exact and original semantics of the !.

[0] https://rabbit.eng.miami.edu/info/bcpl_reference_manual.pdf

Re: GCC SC approves inclusion of Algol 68 Front End

#66
post #14

Earlier quoted context omitted.

> I'm pretty excited for this Aside from historical interest, why are you excited for it?

Personally, I think the whole C tangent was a misstep and would love to see Algo 68 turn into Algo 26 or 27. I sort of like C and C++ and many other languages which came, but they have issues. I think Algo 68 could develop into something better than C++, it has some of the pieces already in place. Admittedly, every language I really enjoy and get along with is one of those languages that produced little compared to t…

Consider exploring Ada 2022 as a capable successor to Algol. Its well supported in GCC and scales well from very small to very large projects. Some information is at https://learn.adacore.com/ and https://alire.ada.dev/

Re: GCC SC approves inclusion of Algol 68 Front End

#67

Earlier quoted context omitted.

> it should have been a postfix operator, like in Euler and Pascal. I never liked Pascal style Pointer^. As the postfix starts to get visually cumbersome with more than one layer of Indirection^^. Especially when combined with other postfix Operators^^.AndMethods. Or even just Operator^ := Assignment. I also think it's the natural inverse of the "address-of" prefix operator. So we have "take the address of this value…

The "natural inverse" relationship between "address-of" and indirect addressing is only partial. You can apply the "*" operator as many times you want, but applying "address-of" twice is meaningless. Moreover, in complex expressions it is common to mix the indirection operator with array indexing and with structure member selection, and all these 3 postfix operators can appear an unlimited number of times in an expre…

A postfix "*" would be completely redundant since you can just use p[0] . Instead of *p++ you'd have (p++)[0] - still quite workable.

Re: GCC SC approves inclusion of Algol 68 Front End

#68
post #60
post #36

Earlier quoted context omitted.

The issue is that certain specific parts of the industry currently pour in a lot of money into the Rust ecosystem, but selectively only where they need it.

How is that different than scratching one’s own itch?

Personal itches are more varied and strange than corporate itches. What companies are willing to pour time (money) into is constrained by market forces. The constraints on the efforts of independent hackers are different.

Both sets of constraints produce patterns and gaps. UX and documentation are commonly cited gaps for volunteer programming efforts, for example.

But I think it's true that corporate funding has its own gaps and other distinctive tendencies.

Re: GCC SC approves inclusion of Algol 68 Front End

#69
post #10

Earlier quoted context omitted.

Does gcc even support go?

Until a few years ago, gccgo was well maintained and trailed the main Go compiler by 1 or 2 releases, depending on how the release schedules aligned. Having a second compiler was considered an important feature. Currently, the latest supported Go version is 1.18, but without Generics support. I don't know if it's a coincidence, but porting Generics to gccgo may have been a hurdle that broke the cadence.

The best thing about gccgo is that it is not burdened with the weirdness of golang's calling convention, so the FFI overhead is basically the same as calling an extern function from C/C++. Take a look at [0] and see how bad golang's cgo calling latency compare to C. gccgo is not listed there but from my own testing it's the same as C/C++.

[0]: https://github.com/dyu/ffi-overhead

Re: GCC SC approves inclusion of Algol 68 Front End

#70
post #65

Earlier quoted context omitted.

The prefix "*" and the increment/decrement operators have been indeed introduced in the B language (in 1969, before the launch of PDP-11 in 1970, but earlier computers had some autoincrement/autodecrement facilities, though not as complete as in the B language), where "*" has been made prefix for the reason that I have already explained. The prefix "*" WAS NOT inherited from BCPL, it was purely a B invention due to K…

* was the usual infix multiplication operator in BCPL, and it was not used for pointer arithmetic. The BCPL manual[0] explains the «monadic !» operator (section 2.11.3) as: 2.11.3 MONADIC ! The value or a monadic ! expression is the value of the storage cell whose address is the operand of the !. Thus @!E = !@E = E, (providing E is an expression of the class described in 2.11.2). Examples. !X := Y Stores the value of…

The BCPL manual linked by you is not useful, as it describes a recent version of the language, which is irrelevant for the evolution of the B and C languages. A manual of BCPL from July 1967, predating B, can be found on the Web.

The use of the character "!" in BCPL is much later than the development of the B language from BCPL, in 1969.

The asterisk had 3 uses in BCPL, as the multiplication operator, as a marker for the opening bracket in array indexing, to compensate for the lack of different kinds of brackets for function evaluation and for array indexing, and as the escape character in character strings. For the last use the asterisk has been replaced by the backslash in C.

There was indeed a prefix indirection operator in BCPL, but it did not use any special character, because the available character set did not have any unused characters.

The BCPL parser was separate from the lexer, and it was possible for the end users to modify the lexer, in order to assign any locally available characters to the syntactic tokens.

So if a user had appropriate characters, they could have been assigned to indirection and address-of, but otherwise they were just written RV and LV, for right-hand-side value and left-hand-side value.

It is not known whether Ken Thompson had modified the BCPL lexer for his PDP computer, to use some special characters for operators like RV and LV.

In any case, he could not have used asterisk for indirection, because that would have conflicted with its other uses.

The use of asterisk for indirection in B became possible only after Ken Thompson has made many other changes and simplifications in comparison with BCPL, removing any parsing conflicts.

You are right that BCPL already had prefix operators for indirection and address-of, which was different from how this had been handled in CPL, but Martin Richards did not seem to have any reason for this choice and in BCPL this was a less obvious mistake, because it did not have structures.

On the other hand, Ken Thompson did want to have "*" as prefix, after introducing his increment and decrement operators, in order to need no parentheses for pre- and post-incrementation or decrementation of pointers, in the context where postfix operators were defined as having higher precedence than prefix.

Also in his case this was not yet an obvious mistake, because he had no structures and the programs written in B at that time did not use any complex data structures that would need correspondingly complex addressing expressions.

Only years later it became apparent that this was a bad choice, while the earlier choice of N. Wirth in Euler (January 1966; the first high-level language that handled pointers explicitly, with indirection and address-of operators) had been the right one. The high-level languages that had "references" before 1966 (the term "pointer" has been introduced in IBM PL/I, in July 1966), e.g. CPL and FORTRAN IV, handled them only implicitly.

Decades later, complex data structures became common while the manual optimization of incrementing/decrementing explicitly pointers for addressing arrays became a way of writing inefficient programs, which prevent the compiler from optimizing correctly the array accessing for the target CPU.

So the choice of Ken Thompson can be justified in its context from 1969, but in hindsight it has definitely been a very bad choice.

Post reply on HN