Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What attributes of a programming language simplify its use?

162 views
Skip to first unread message

Robin Vowels

unread,
Dec 3, 2022, 5:53:27 AM12/3/22
to
From: "gah4" <ga...@u.washington.edu>
Date: Friday, 2 December 2022 11:18 AM


It seems, though, that languages are implemented a small number of
times, and used many times. So, designing for ease of use, instead of
ease of implementation makes more sense.

(Especially if you want a lot of people to want to use it.)

One feature that I find makes them easier to use, and harder to implement, is no reserved words.

For almost 50 years now, my favorite name for an otherwise unnamed
program is "this". (That is, where many people seem to use "foo", and
years before I knew about "foo".)

That worked fine, until Java came along with reserved word "this".
(Second choice, "that", fortunately isn't reserved in Java.)
[I take your point, but in PL/I you can say:

IF THEN = ELSE THEN BEGIN = IF; ELSE END = IF;

COBOL famously has too many reserved words but PL/I overreacted. -John]

Robin Vowels

unread,
Dec 3, 2022, 5:57:11 AM12/3/22
to
On Thursday, December 1, 2022 at 4:18:24 PM UTC-8, gah4 wrote:

(snip)

> One feature that I find makes them easier to use, and harder to implement, is no reserved words.

(snip)
> [I take your point, but in PL/I you can say:
>
> IF THEN = ELSE THEN BEGIN = IF; ELSE END = IF;
>
> COBOL famously has too many reserved words but PL/I overreacted. -John]

COBOL had many useful English words used.

As well as I know it, the idea for PL/I was that you shouldn't need to know
about the parts of the language that you weren't using, even know the words.

But also, PL/I more than other languages has simple rules, instead
of arbitrary restrictions. You can use any expression in any place where
an expression is allowed.

Fortran has always, and still does, have unobvious restrictions on how
expressions can be used. Some it seems intentionally to make it harder
for the programmer. That is, to discourage practices that some don't like.

My favorite complaint is about using REAL variables in DO loops.
Yes there are good reasons not to do it, but it isn't up to the language
to decide that.

The actual reason I follow this one, is that many (many!) years ago
I would sometimes translate BASIC programs to Fortran, where all
variables are Fortran REAL.


PL/I allowed array expressions from the beginning, Fortran added
them much later. PL/I has a simple rule. The subscripts have the
same value for all arrays in the expression.

Fortran has complicated rules, where some arrays index from one,
even if they are declared with different lower bound. You have to
be extremely careful, which one it is using. And it gets even worse
when you pass arrays to subroutines.

But back to the reserved words. Just because it allows them,
doesn't mean that you should use them. In all cases, the person
writing the program should consider readability. And using IF
related words in an IF statement is bound to be confusing.

Robin Vowels

unread,
Dec 3, 2022, 6:03:51 AM12/3/22
to
On 2022-12-02 09:20, gah4 wrote:

> One feature that I find makes them easier to use, and harder to
> implement, is no reserved words.

Not really. A parser for identifying FORTRAN statements
published in 1971 (by AJH Sale) was short and concise.

The parser for DEUCE PL/I (a subset) was trivial.
The initial word of statement in both FORTRAN and PL/I
is sufficient to identify the statement, and most other identifiers
in the statement are not keywords.
A complication in PL/I is that in a few statements
(e.g., GET and PUT), some keywords can appear in any order.

> [I take your point, but in PL/I you can say:

> IF THEN = ELSE THEN BEGIN = IF; ELSE END = IF;

It is really not a great idea to write code like that.

> COBOL famously has too many reserved words but PL/I overreacted. -John]

A COBOL program that I ran on CDC Cyber 70, crashed at
compilation, not even producing a listing, and with no
indication of what was wrong. It turned out to be that the
program name was a (reserved) keyword -- At that time, there were
some 250 reserved words.

The concept of nil or few reserved words is a good one.
For PL/I it meant that new features could be added to the language
without affecting any existing programs.

John W Kennedy

unread,
Dec 3, 2022, 2:54:54 PM12/3/22
to
Yes, but you’re not required to writing such ridiculous code, and adding
only a few reserved words makes the language harder to learn, because it
forces to you memorize more exceptions.

On the other hand, running with zero reserved words, as with PL/I and
FORTRAN, or even with a merely minimal set, as in C, requires extra
keywords and punctuation (usually parentheses).

PL/I if x = 0 then
x = 1;
else do:
x = x + 2;
e = e + 1;
end;

C if (x == 0)
x = 1;
else {
x += 2;
e += 1;
}

Swift if x == 0 {
x = 1
} else {
x += 2
e += 1
}

Honestly, in this, as in most matters, I like Swift best.

But Swift has one really neat trick when it comes to reserved words.

var `in` = 0
var out = 0

The backtick quotes make a reserved word safe for use as a name. (Swift
has features comparable to PL/I GET and PUT DATA, so just changing the
name may not be feasible.)

--
John W. Kennedy
Algernon Burbage, Lord Roderick, Father Martin, Bishop Baldwin,
King Pellinore, Captain Bailey, Merlin -- A Kingdom for a Stage!

Robin Vowels

unread,
Dec 4, 2022, 6:10:34 AM12/4/22
to
In PL/I, in an array expression (and, of course, in an array assignment),
all arrays must have the same lower bounds and the same upper bounds.

In DEUCE PL/I, an array assignment to an array expression
(e.g., A = B * C;) the addresses of the first element of each array
are used as starting values. As each element is assigned,
those addresses are incremented by 1 for each array.
Only one loop counter is required, regardless of whether the arrays
are vectors or matrices.

Unlike Fortran, in PL/I, the lower and upper bounds of an array
are carried around -- even if passed to a function or subroutine.
They do not change.

John W Kennedy

unread,
Dec 4, 2022, 8:26:15 PM12/4/22
to
On 12/3/22 5:53 AM, Robin Vowels wrote:

Spiros Bousbouras

unread,
Dec 5, 2022, 7:44:30 AM12/5/22
to
On Sat, 3 Dec 2022 02:57:09 -0800 (PST)
Robin Vowels <robin....@gmail.com> wrote:
> On Thursday, December 1, 2022 at 4:18:24 PM UTC-8, gah4 wrote:
>
> (snip)
>
> > One feature that I find makes them easier to use, and harder to implement, is no reserved words.
>
> (snip)
> > [I take your point, but in PL/I you can say:
> >
> > IF THEN = ELSE THEN BEGIN = IF; ELSE END = IF;
> >
> > COBOL famously has too many reserved words but PL/I overreacted. -John]
>
> COBOL had many useful English words used.
>
> As well as I know it, the idea for PL/I was that you shouldn't need to know
> about the parts of the language that you weren't using, even know the words.
>
> But also, PL/I more than other languages has simple rules, instead
> of arbitrary restrictions. You can use any expression in any place where
> an expression is allowed.

[...]

It should be noted that you are quoting from 2 messages which were first posted
on comp.compilers , <22-1...@comp.compilers> and <22-1...@comp.compilers> .

Peter Flass

unread,
Dec 5, 2022, 9:32:25 AM12/5/22
to
Kind of the reverse of many ALGOL implementations.

> (Swift
> has features comparable to PL/I GET and PUT DATA, so just changing the
> name may not be feasible.)
>


--
Pete

Robin Vowels

unread,
Dec 5, 2022, 3:30:15 PM12/5/22
to
.
In PL/I :
IF X = 0 THEN
DO; X = 1; END;
ELSE
DO;
X = X + 2; E = E + 1;
END;
and similarly in Fortran.
The bracketing is performed by keywords that are more easily seen than
the single character of curly braces.
.
> C if (x == 0)
> x = 1;
> else {
> x += 2;
> e += 1;
> }
>
> Swift if x == 0 {
> x = 1
> } else {
> x += 2
> e += 1
.
These assignments can be written the same way in PL/I ,
but I prefer the traditional method.
.
> }
>
> Honestly, in this, as in most matters, I like Swift best.
>
> But Swift has one really neat trick when it comes to reserved words.
>
> var `in` = 0
> var out = 0
>
> The backtick quotes make a reserved word safe for use as a name. (Swift
> has features comparable to PL/I GET and PUT DATA, so just changing the
> name may not be feasible.)
.
In PL/I and Fortran, reserved words are safe for a name.
Swift seems to be clumsy: you still need to keep in mind which words are keywords?
Languages should make it easy for the programmer, not easy for the compiler writer.

John W Kennedy

unread,
Dec 5, 2022, 8:18:55 PM12/5/22
to
No, PL/I and FORTRAN don’t /have/ reserved words.

> Swift seems to be clumsy: you still need to keep in mind which words are keywords?
> Languages should make it easy for the programmer, not easy for the compiler writer.

But the FORTRAN-PL/I model requires a good deal of extra punctuation. It
also requires the CALL keyword, which, especially in subsystem
environments like CICS or any sort of GUI, can nearly make anyone trying
to read the code go blind.

Peter Flass

unread,
Dec 5, 2022, 9:57:53 PM12/5/22
to
John W Kennedy <john.w....@gmail.com> wrote:
Nobody in their right mind looks at the calls generated by the CICS
preprocessor.

--
Pete

John W Kennedy

unread,
Dec 5, 2022, 11:00:40 PM12/5/22
to
True enough. Indeed, my first thougt was GDDM, but I don’t suppose that
even exists, any more. (I haven’t really been concerned with mainframes
since the mid-90s, but I try to keep up.) But any environment in which,
out of 100 statements, 90 may be CALLs, illustrates the point. It
induces a sort of “Waldo” (UK: “Wally”) wearyness.

Robin Vowels

unread,
Dec 6, 2022, 1:52:29 AM12/6/22
to
.
I know that.
.
> > Swift seems to be clumsy: you still need to keep in mind which words are keywords?
> > Languages should make it easy for the programmer, not easy for the compiler writer.
.
> But the FORTRAN-PL/I model requires a good deal of extra punctuation.
.
Really? Where did you have in mind?
I like the words "TO" AND "BY" etc in DO statements.
They have the ability to be used in any order.
.
> It also requires the CALL keyword, which, especially in subsystem
> environments like CICS or any sort of GUI, can nearly make anyone trying
> to read the code go blind.
.
I like the word "CALL". It makes it obvious to the reader that a subroutine is being called.

John W Kennedy

unread,
Dec 6, 2022, 5:23:42 PM12/6/22
to
And on the F compiler, that actually meant something, but now the two
expressions are evaluated in arbitrary order.

(Not to mention that the traditional from-to-step looping statement is
increasingly absent from new languages, starting with Ada at the latest.)

However, I said "punctuation", as in the parentheses in
WHILE(expression), SELECT(expression), and many others.

>> It also requires the CALL keyword, which, especially in subsystem
>> environments like CICS or any sort of GUI, can nearly make anyone trying
>> to read the code go blind.
> .
> I like the word "CALL". It makes it obvious to the reader that a subroutine is being called.

You may feel that way, but younger people point at “call” and laugh and
sing “Mama, look a boo boo dey”, and joke about older languages needing
a "preliminary harumph”—I’ve seen that one in print.

Robin Vowels

unread,
Dec 7, 2022, 5:06:54 AM12/7/22
to
On Wednesday, December 7, 2022 at 9:23:42 AM UTC+11, John W. Kennedy wrote:
> On 12/6/22 1:52 AM, Robin Vowels wrote:
> > On Tuesday, December 6, 2022 at 12:18:55 PM UTC+11, John W. Kennedy wrote:
> >> On 12/5/22 3:30 PM, Robin Vowels wrote:
> >>> On Sunday, December 4, 2022 at 6:54:54 AM UTC+11, John W. Kennedy wrote:
> >>>> On 12/3/22 5:53 AM, Robin Vowels wrote:
> >>>>> From: "gah4" <ga...@u.washington.edu>
> >>>>> Date: Friday, 2 December 2022 11:18 AM
.
> >> But the FORTRAN-PL/I model requires a good deal of extra punctuation.
> > .
> > Really? Where did you have in mind?
> > I like the words "TO" AND "BY" etc in DO statements.
> > They have the ability to be used in any order.
.
> And on the F compiler, that actually meant something, but now the two
> expressions are evaluated in arbitrary order.
>
> (Not to mention that the traditional from-to-step looping statement is
> increasingly absent from new languages, starting with Ada at the latest.)
>
> However, I said "punctuation", as in the parentheses in
> WHILE(expression), SELECT(expression), and many others.
.
"BY" and "TO" can be regarded as punctuation.
I don't see the parentheses in SELECT and WHILE as a problem.
They are only a pair of keystrokes.

Peter Flass

unread,
Dec 7, 2022, 1:01:43 PM12/7/22
to
OTOH, I don’t particularly care for C’s, and other languages, () in if
statements.

> .
>>>> It also requires the CALL keyword, which, especially in subsystem
>>>> environments like CICS or any sort of GUI, can nearly make anyone trying
>>>> to read the code go blind.
>>> .
>>> I like the word "CALL". It makes it obvious to the reader that a
>>> subroutine is being called.
>



--
Pete

John W Kennedy

unread,
Dec 7, 2022, 7:41:17 PM12/7/22
to
Which is why modern C-related langages, such as Swift, eliminate them,
at the cost of mandating {...} pairs around single statements, as well
as groups. (But this avoids common errors when updating, anyway, so it’s
seen as a plus, regardless.

>> .
>>>>> It also requires the CALL keyword, which, especially in subsystem
>>>>> environments like CICS or any sort of GUI, can nearly make anyone trying
>>>>> to read the code go blind.
>>>> .
>>>> I like the word "CALL". It makes it obvious to the reader that a
>>>> subroutine is being called.
>>
>
>
>

--

Peter Flass

unread,
Dec 8, 2022, 1:56:06 PM12/8/22
to
John W Kennedy <john.w....@gmail.com> wrote:
At first I thought “this is crazy” until I realized you meant “in an
if-statement.” Sometimes I do this in C, what little C I write. It does
avoid errors.

--
Pete

John Cowan

unread,
Feb 27, 2023, 11:03:52 PM2/27/23
to
On Saturday, December 3, 2022 at 5:57:11 AM UTC-5, Robin Vowels wrote:

> My favorite complaint is about using REAL variables in DO loops.
> Yes there are good reasons not to do it, but it isn't up to the language
> to decide that.

I disagree. Unless you know the details of your floating-point hardware, you do not know how many times your loop will iterate if the value is fractional (if it's integral and not too large, there is no problem). For example, on IEEE 754 hardware:

declare x(binary float);
do x = 0.0 repeat x + 0.1 while x <= 1.0;
...
end;

will iterate 11 times rather than the expected 10. It is better to ban binary-float loops rather than to allow this sort of bug. Subset G bans all floating-point loops, as do many more recent languages.

> The actual reason I follow this one, is that many (many!) years ago
> I would sometimes translate BASIC programs to Fortran, where all
> variables are Fortran REAL.

In that case, iterate thus:

declare i (fixed binary);
do i = 0 repeat i + 1 while i < 10;
x = i / 10;
...
end;

The book _The Elements of Programming Style_ by Brian Kernighan and P. J. Plauger discusses the pitfalls of counting with (binary) floating-point numbers in Chapter 6.

Peter Flass

unread,
Feb 28, 2023, 8:25:47 AM2/28/23
to
Except for the format of loop

DO i=1.0e0, 2.0e0, 3.5e1 …

But most lesser languages do not support this loop format, either.

--
Pete

David W Noon

unread,
Feb 28, 2023, 1:23:38 PM2/28/23
to
On 28/02/23 04:03, John Cowan wrote:
> On Saturday, December 3, 2022 at 5:57:11 AM UTC-5, Robin Vowels wrote:
>
>> My favorite complaint is about using REAL variables in DO loops.
>> Yes there are good reasons not to do it, but it isn't up to the language
>> to decide that.
>
> I disagree. Unless you know the details of your floating-point hardware, you do not know how many times your loop will iterate if the value is fractional (if it's integral and not too large, there is no problem). For example, on IEEE 754 hardware:
>
> declare x(binary float);
> do x = 0.0 repeat x + 0.1 while x <= 1.0;
> ...
> end;
>
> will iterate 11 times rather than the expected 10. It is better to ban binary-float loops rather than to allow this sort of bug. Subset G bans all floating-point loops, as do many more recent languages.

That loop will iterate 11 times, even if you used DECIMAL FIXED, where
the fractional representation is exact. There is no bug here.

>> The actual reason I follow this one, is that many (many!) years ago
>> I would sometimes translate BASIC programs to Fortran, where all
>> variables are Fortran REAL.
>
> In that case, iterate thus:
>
> declare i (fixed binary);
> do i = 0 repeat i + 1 while i < 10;

You have changed the exit criterion from "<=" to "<"!! I assume you
meant to keep it as "<=".

Perhaps more succinctly:

DO i = 0 UPTHRU 10;

That will also loop 11 times.

> x = i / 10;

An integer division can give "interesting" results.

Perhaps a floating point cast:

x = FLOAT(i)/10;

or even use a floating point coercion:

x = i*1E-1;

> ...
> end;
>
> The book _The Elements of Programming Style_ by Brian Kernighan and P. J. Plauger discusses the pitfalls of counting with (binary) floating-point numbers in Chapter 6.

I have owned a copy of that book for many years. Its suggestion are, at
best, a mixed bag. Neither Kernighan nor Plauger seemed to have a really
solid grasp of PL/I.

In particular, you might want a looping construct that does not require
counting but a value assessment, particularly using some transcendental
function. For such a loop, a floating point control variable would be
ideally suited.

--
Regards,

Dave [RLU #314465]
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
david....@ntlworld.com (David W Noon)
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

signature.asc

John Cowan

unread,
Feb 28, 2023, 1:40:45 PM2/28/23
to
On Tuesday, February 28, 2023 at 1:23:38 PM UTC-5, David W Noon wrote:

> That loop will iterate 11 times, even if you used DECIMAL FIXED, where
> the fractional representation is exact. There is no bug here.

You are correct. I meant to write < rather than <=. If you run that version you will see that it still iterates 11 times. However, with an older FPP that might not be the case.

> You have changed the exit criterion from "<=" to "<"!! I assume you
> meant to keep it as "<=".

On the contrary, I meant < in both versions.

> In particular, you might want a looping construct that does not require
> counting but a value assessment, particularly using some transcendental
> function. For such a loop, a floating point control variable would be
> ideally suited.

Can you give me an example? In any case, the stricture in TEoPS is against *counting* with floating-point numbers.

David W Noon

unread,
Mar 1, 2023, 10:14:09 AM3/1/23
to
On 28/02/23 18:40, John Cowan wrote:
> On Tuesday, February 28, 2023 at 1:23:38 PM UTC-5, David W Noon wrote:

[snip]

>> In particular, you might want a looping construct that does not require
>> counting but a value assessment, particularly using some transcendental
>> function. For such a loop, a floating point control variable would be
>> ideally suited.
>
> Can you give me an example?

Certainly. Here is a PL/I procedure to evaluate cube roots.

/* Function procedure to evaluate cube roots.
Copyright (C) 2023, David W. Noon. All rights reserved.
This code is released under the Berkelely License. */

CUBRT:
PROC(x_cubed) RETURNS(BIN FLOAT(53) IEEE) REORDER;
DCL x_cubed BIN FLOAT(53) IEEE BYVALUE;

DCL (epsilon,x) BIN FLOAT(53) IEEE,
ABS BUILTIN;

/* Pick off trivial ones early. */
IF x_cubed = 0 | ABS(x_cubed) = 1 THEN
RETURN(x_cubed);

epsilon = ABS(x_cubed)*1D-12;

/* Newton-Raphson iteration. */
DO x = x_cubed*2D-1
REPEAT (x + x + x_cubed/(x*x))*3.333333333333333D-1
UNTIL(ABS(x_cubed - x*x*x) <= epsilon);
/* No loop body. */
END;

RETURN(x);
END CUBRT;

Note the DO ... REPEAT ... UNTIL ... that uses a floating point control
variable with no prospect of representation errors causing the loop to
go wrong. DO-loops are not limited to counting.

Meanwhile, back to Kernighan and Plauger.

Brian Kernighan was one of the original implementers of C and P.J.
Plauger was a guru spreading the C religion. However, C does not prevent
the use of floaters in for-loops. Here is the above code implemented in
C (1999 or later standard).

/* Function to evaluate cube roots.
Copyright (C) 2023, David W. Noon All rights reserved.
This code is released under the Berkeley License. */

#include <math.h>

double cubrt(double x_cubed)
{
double x;

/* Pick off trivial ones early. */
if (x_cubed == 0.0 || fabs(x_cubed) == 1.0)
return x_cubed;

const double epsilon = fabs(x_cubed)*1e-12;

/* Use Newton-Raphson iteration. */
for (x = x_cubed*0.2;
fabs(x_cubed - x*x*x) > epsilon;
x = (x + x + x_cubed/(x*x))*0.3333333333333333)
{
/* No loop body. */
}

return x;
}

As you can see, Kernighan and Plauger do not practise what they had
earlier preached.

> In any case, the stricture in TEoPS is against *counting* with
> floating-point numbers.

Well, PL/I DO-loops and C for-loops can do more than just count.
Restricting the language to integer-only control variables would be
counterproductive for a lot of numerical work.
signature.asc

Robin Vowels

unread,
Apr 15, 2023, 10:10:26 PM4/15/23
to
On Tuesday, February 28, 2023 at 3:03:52 PM UTC+11, John Cowan wrote:
> On Saturday, December 3, 2022 at 5:57:11 AM UTC-5, Robin Vowels wrote:
>
> > My favorite complaint is about using REAL variables in DO loops.
> > Yes there are good reasons not to do it, but it isn't up to the language
> > to decide that.
.
I did not write that; gah4 wrote it.
.
> I disagree. Unless you know the details of your floating-point hardware, you do not know how many times your loop will iterate if the value is fractional (if it's integral and not too large, there is no problem). For example, on IEEE 754 hardware:
>
> declare x(binary float);
.
No, the forrect form for the DECLARE statement is:
.
DECLARE X FLOAT BINARY.
.
> do x = 0.0 repeat x + 0.1 while x <= 1.0;
> ...
> end;
>
> will iterate 11 times rather than the expected 10. It is better to ban binary-float loops rather than to allow this sort of bug. Subset G bans all floating-point loops, as do many more recent languages.
> > The actual reason I follow this one, is that many (many!) years ago
> > I would sometimes translate BASIC programs to Fortran, where all
> > variables are Fortran REAL.
> In that case, iterate thus:
>
> declare i (fixed binary);
.
DECLARE I FIXED BINARY;
.
> do i = 0 repeat i + 1 while i < 10;
> x = i / 10;
> ...
> end;
,
Alternatively you can use decimal float hardware,
or you can used FIXED DECIMAL.
,

John Cowan

unread,
Apr 15, 2023, 10:44:23 PM4/15/23
to
On Saturday, April 15, 2023 at 10:10:26 PM UTC-4, Robin Vowels wrote:

> I did not write that; gah4 wrote it.

My apologies for the misattribution (and for making a balls of PL/I syntax): I was distressed by the death of my wife two weeks earlier.


Peter Flass

unread,
Apr 17, 2023, 8:11:06 PM4/17/23
to
Oh my God! I’m so sorry.

--
Pete
0 new messages