<Prev | [Index] | Next>


ok@cs.otago.ac.nz
Date: Tue, 21 Feb 2017 21:22:23 +1300

Wols Lists wrote about PL/I that "A misplaced parenthesis ran a serious risk of still leaving you with a valid program, but one that did something completely different from what you intended. Caused by the massive overloading of the meaning of said character."

It is well to understand old blunders so that we can avoid them.

Parentheses were used just three ways in PL/I:
- fixed syntax, as in DO WHILE (expr); ... END;
The pattern <keyword>(<stuff>) is common.
- grouping, for expressions and declarations.
- enclosing procedure arguments and array subscripts,
which have the same form, as in Fortran.
"Massive overloading"? Only if you think parentheses are massively overloaded in C, C#, JavaScript, Ruby, ...

A feature was copied from Fortran, because of its "familiarity" and "naturalness". That is that procedure arguments were passed by dummy variable. Supply a variable, and the procedure can change it. Supply an expression, and it's assigned to a hidden variable, so it's sort of like pass by value. So

CALL PROC(VAR); /* PROC can change VAR */
CALL PROC((VAR)); /* PROC cannot change VAR */

Worse than that, if the attributes of VAR did not match the attributes of the formal parameter, there was an *invisible* conversion from VAR to whatever was expected, making it an expression that just *looks* like a variable. E.g.,
DECLARE PROC ENTRY(DECIMAL FIXED (9,0));
DECLARE VAR BINARY FIXED (31,0);
... CALL PROC(VAR); /* invisible conversion, PROC can't change VAR */

>From which we learned that
(1) invisible conversions are a bad idea (hello, C++, Java, &c)
(2) it's really good if you can tell whether an actual
parameter is passed by reference or value by the
form of the call (actually, almost nobody learned this).


<Prev | [Index] | Next>