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

iso646.h

852 views
Skip to first unread message

Lawrence D'Oliveiro

unread,
Jan 21, 2024, 8:52:01 PMJan 21
to
How many people know about this? It was introduced in c99. If you
“#include <iso646.h>”, then you can use alternative symbols like “not”
instead of “!”, “and” instead of “&&” and “or” instead of “||”.

C++ already had this, without the need to include such a file.

Lew Pitcher

unread,
Jan 21, 2024, 9:00:35 PMJan 21
to
On Mon, 22 Jan 2024 01:51:48 +0000, Lawrence D'Oliveiro wrote:

> How many people know about this? It was introduced in c99.

It was added in a 1995 amendment to the C90 standard.

> If you
> “#include <iso646.h>”, then you can use alternative symbols like “not”
> instead of “!”, “and” instead of “&&” and “or” instead of “||”.
>
> C++ already had this, without the need to include such a file.

Yah, so?

--
Lew Pitcher
"In Skills We Trust"

James Kuyper

unread,
Jan 21, 2024, 9:48:56 PMJan 21
to
On 1/21/24 20:51, Lawrence D'Oliveiro wrote:
> How many people know about this? It was introduced in c99. If you
> “#include <iso646.h>”, then you can use alternative symbols like “not”
> instead of “!”, “and” instead of “&&” and “or” instead of “||”.

I did, and so did a lot of other people. Google groups lists 222
messages containing <iso646.h>.

> C++ already had this, without the need to include such a file.

That's because backwards compatibility with older versions of C is a
lower priority for C++ than it is for C. Existing code that ysed those
words as identifiers would break if that feature were simply always
enabled. Putting it in a standard header allows it to be under user
control.

Lawrence D'Oliveiro

unread,
Jan 22, 2024, 12:23:43 AMJan 22
to
On Sun, 21 Jan 2024 21:48:36 -0500, James Kuyper wrote:

> On 1/21/24 20:51, Lawrence D'Oliveiro wrote:
>
>> C++ already had this, without the need to include such a file.
>
> That's because backwards compatibility with older versions of C is a
> lower priority for C++ than it is for C.

I don’t think even many C++ programmers know about this.

David Brown

unread,
Jan 22, 2024, 3:30:40 AMJan 22
to
I can't say how many people know about it, but I certainly did. I have
not used it - and I don't use the matching names in C++ either, but I
knew about them. (I know lots more features of C and C++ than I use - I
expect that applies to most programmers.)

Scott Lurndal

unread,
Jan 22, 2024, 11:24:57 AMJan 22
to
David Brown <david...@hesbynett.no> writes:
>On 22/01/2024 02:51, Lawrence D'Oliveiro wrote:
>> How many people know about this? It was introduced in c99. If you

Although it was available before 1999 - the SVR4 C compilation System
(CCS) had an iso656.h header file in the early 90's.

#ifndef _ISO646_H
#define _ISO646_H
#ident "@(#)sgs-head:common/head/iso646.h 1.2"

#define and &&
#define and_eq &=
#define bitand &

#define or ||
#define or_eq |=
#define bitor |

#define xor ^
#define xor_eq ^=

#define compl ~

#define not !
#define not_eq !=

#endif /*_ISO646_H*/
~

Lawrence D'Oliveiro

unread,
Jan 22, 2024, 3:34:18 PMJan 22
to
On Mon, 22 Jan 2024 09:30:21 +0100, David Brown wrote:

> ... I don't use the matching names in C++ either ...

I do, if/when I do use C++ and C. Don’t you think it improves readability:

if (ThisCh < '0' or ThisCh > '9')
{
if (AllowSign and Index == 0 and (ThisCh == '+' or ThisCh == '-'))
{
/* fine */
}
else if (AllowDecimal and not DecimalSeen and ThisCh == '.')
{
DecimalSeen = true; /* only allow one decimal point */
}
else
{
Valid = false;
break;
} /*if*/
} /*if*/

...

if
(
TheEntry->d_name[0] == '.'
and
(
TheEntry->d_name[1] == 0
or
TheEntry->d_name[1] == '.'
and
TheEntry->d_name[2] == 0
)
)
{
/* skip "." and ".." entries */
}

...

if
(
ThisCh >= 'a' and ThisCh <= 'z'
or
ThisCh >= 'A' and ThisCh <= 'Z'
or
ThisCh >= '0' and ThisCh <= '9'
or
ThisCh == '_'
or
ThisCh == '-'
or
ThisCh == '.'
or
ThisCh == '/'
)
{
Result.append(1, ThisCh);
}

Lawrence D'Oliveiro

unread,
Jan 22, 2024, 3:34:55 PMJan 22
to
On Mon, 22 Jan 2024 16:24:36 GMT, Scott Lurndal wrote:

> Although it was available before 1999 - the SVR4 C compilation System
> (CCS) had an iso6[4]6.h header file in the early 90's.

By the way, why is it called “iso646.h”?

Keith Thompson

unread,
Jan 22, 2024, 4:22:56 PMJan 22
to
ISO 646 is the ISO standard for the ASCII 7-bit character set. The
header's original intent was to make C programming easier on systems
that don't support all ASCII characters, either because they use EBCDIC
or because they use 7-bit character sets that replace some puncutation
characters with, for example, accented letters.

As for "and" being more readable than "&&", that's not necessarily the
case for people who are accustomed to reading C code.

--
Keith Thompson (The_Other_Keith) Keith.S.T...@gmail.com
Working, but not speaking, for Medtronic
void Void(void) { Void(); } /* The recursive call of the void */

Kaz Kylheku

unread,
Jan 22, 2024, 4:32:55 PMJan 22
to
On 2024-01-22, Lawrence D'Oliveiro <l...@nz.invalid> wrote:
> On Mon, 22 Jan 2024 09:30:21 +0100, David Brown wrote:
>
>> ... I don't use the matching names in C++ either ...
>
> I do, if/when I do use C++ and C. Don’t you think it improves readability:

Only for someone who has no experience in C or C++, and is unfamiliar
with the regular operators, and speaks English.

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazi...@mstdn.ca
NOTE: If you use Google Groups, I don't see you, unless you're whitelisted.

Lawrence D'Oliveiro

unread,
Jan 22, 2024, 5:07:26 PMJan 22
to
On Mon, 22 Jan 2024 13:22:41 -0800, Keith Thompson wrote:

> As for "and" being more readable than "&&", that's not necessarily the
> case for people who are accustomed to reading C code.

You mean, “old-style C code”.

I imagine the introduction of ANSI-style argument declarations, as opposed
to the old K&R style, was a bit of a jar, too. But we got over it.

Keith Thompson

unread,
Jan 22, 2024, 5:57:11 PMJan 22
to
Lawrence D'Oliveiro <l...@nz.invalid> writes:
> On Mon, 22 Jan 2024 13:22:41 -0800, Keith Thompson wrote:
>> As for "and" being more readable than "&&", that's not necessarily the
>> case for people who are accustomed to reading C code.
>
> You mean, “old-style C code”.

No, I mean C code.

> I imagine the introduction of ANSI-style argument declarations, as opposed
> to the old K&R style, was a bit of a jar, too. But we got over it.

As far as I can tell, the macros defined in <iso646.h> have never caught
on significantly. Code using the "and" and "or" macros isn't new-style;
it's just (likely to be seen as) peculiar.

I don't think I'd have any trouble reading code that uses the macros --
but the fact that I've never had a chance to find out is telling.

If you find them more readable, that's fine, but I think that most C
programmers with any reasonable amount of experience are more likely to
find them slightly jarring.

Blue-Maned_Hawk

unread,
Jan 22, 2024, 6:09:13 PMJan 22
to
Lawrence D'Oliveiro wrote:

> Don’t you think it improves readability:

No.

--
Blue-Maned_Hawk│shortens to
Hawk│/
blu.mɛin.dʰak/
│he/him/his/himself/Mr.
blue-maned_hawk.srht.site
Cenunfly!

Lawrence D'Oliveiro

unread,
Jan 22, 2024, 6:37:48 PMJan 22
to
On Mon, 22 Jan 2024 23:08:53 -0000 (UTC), Blue-Maned_Hawk wrote:

> Lawrence D'Oliveiro wrote:
>
>> Don’t you think it improves readability:
>
> No.

Lessig’s Law: The one who writes the code makes the rules.

Lawrence D'Oliveiro

unread,
Jan 22, 2024, 6:44:21 PMJan 22
to
On Mon, 22 Jan 2024 14:56:53 -0800, Keith Thompson wrote:

> As far as I can tell, the macros defined in <iso646.h> have never caught
> on significantly.

The nice thing is, I don’t have to care. They have to be part of any
standards-compliant C compiler, therefore I am free to use them. And I do.

Kaz Kylheku

unread,
Jan 22, 2024, 7:10:36 PMJan 22
to
On 2024-01-22, Lawrence D'Oliveiro <l...@nz.invalid> wrote:
Indentation not being required is part of any conforming C compiler.
Therefore, I take advantage of it by starting each line of code without
any leading whitespace, regardless of the nesting level. My coworkers
love me!

Kaz Kylheku

unread,
Jan 22, 2024, 7:12:41 PMJan 22
to
On 2024-01-22, Lawrence D'Oliveiro <l...@nz.invalid> wrote:
Accordingly, if you get to rewrite the genetic code
of someone reading the code, you may be able to dictate
what they find readable.

Tim Rentsch

unread,
Jan 22, 2024, 11:24:18 PMJan 22
to
Lawrence D'Oliveiro <l...@nz.invalid> writes:

[.. using ISO646 names for logical operators ..]

> I do, if/when I do use C++ and C. Don't you think it improves
> readability:
>
> [example]

No, quite the contrary.

Janis Papanagnou

unread,
Jan 23, 2024, 12:47:25 AMJan 23
to
On 22.01.2024 21:34, Lawrence D'Oliveiro wrote:
> On Mon, 22 Jan 2024 09:30:21 +0100, David Brown wrote:
>
>> ... I don't use the matching names in C++ either ...
>
> I do, if/when I do use C++ and C. Don’t you think it improves readability:
> [...]

I'm a big proponent of readable code. Most of the early languages that
I used had such keywords (and also 'begin' etc. instead of braces).

I seem to recall that the (one?) reason to not have them was to reduce
the number of literal alphabetic keywords, to avoid name clashes.

But replacing '&&' by 'and' also doesn't add to the comprehensibility
of the source code (YMMV), presuming that we want the code to be read
by people who know how to program. It's also idiomatic. And in other
contexts (than C) these symbols have similar meanings.

There's also problems with these names. For example '&&' has not the
semantics of 'and' but of 'and_then', 'or' is actually 'or_else'. Even
it that gets "fixed", it's also not addressing other punctuation token
issues, like using '==' instead of the common '=' or 'equals_to'.

Since the beginning of C we had also other inherent issues with these
symbols; not simple lexical ones like 'and', but e.g. the operator
precedence that is (IMO) broken in at least one place. (I guess you
know them.) And in the earlier C days we had not even a true boolean
type or the 'true' and 'false' literals. Fixing things in a language
like C appears to me to be an arduous and unrewarding task.

So I take it as it comes, and I think, in C, we'd need other things
than an iso646.h header or disputes about personal token preferences.
Anyway.

Janis

Janis Papanagnou

unread,
Jan 23, 2024, 12:55:12 AMJan 23
to
If by "The one" you mean the company and the project leader then
you are right. If you mean the individual programmer you are not
necessarily right; in my professional contexts there where even
[coding] standards defined that you had to follow. What people
make in their private cubbyhole is of course their own business
(and no one cares).

Janis

David Brown

unread,
Jan 23, 2024, 3:24:45 AMJan 23
to
On 22/01/2024 21:34, Lawrence D'Oliveiro wrote:
> On Mon, 22 Jan 2024 09:30:21 +0100, David Brown wrote:
>
>> ... I don't use the matching names in C++ either ...
>
> I do, if/when I do use C++ and C. Don’t you think it improves readability:

No. But I fully appreciate that this is personal preference and habit.
The same applies to brace style, and the use of parenthesis, and
variable naming :

if ((ch < '0') || (ch > '0')) {
if (allow_sign && (i == 0) && ((ch == '+') || (ch == '-'))) {
// All fine
} else if (allow_dec && !seen_dec && (ch == '.')) {
seen_dec = true;
} else {
valid = false;
break;
}
}


I wouldn't object to seeing "and" and "or", but I would not feel it
improves readability - it would make the code look more like Python than C.

bart

unread,
Jan 23, 2024, 6:54:47 AMJan 23
to
On 22/01/2024 20:34, Lawrence D'Oliveiro wrote:
> On Mon, 22 Jan 2024 09:30:21 +0100, David Brown wrote:
>
>> ... I don't use the matching names in C++ either ...
>
> I do, if/when I do use C++ and C. Don’t you think it improves readability:
>
> if (ThisCh < '0' or ThisCh > '9')
> {
> if (AllowSign and Index == 0 and (ThisCh == '+' or ThisCh == '-'))
> {
> /* fine */
> }
> else if (AllowDecimal and not DecimalSeen and ThisCh == '.')
> {
> DecimalSeen = true; /* only allow one decimal point */
> }
> else
> {
> Valid = false;
> break;
> } /*if*/
> } /*if*/
>

I strongly dislike C syntax, but this iso646 thing barely address 1% of
it. So I'm not surprised few bother.

Especially if you have to go the the trouble of including a header file
just to be able to use what should be language keywords.

In my everyday language (lower level like C) this can be written as:

if ch not in '0'..'9' then
if allowsign and index = 0 and ch in ['+', '-'] then
# fine

elsif allowdecimal and not decimalseen and ch = '-' then
decimalseen := true

else
valid := false
exit

end if
end if

(Notice no braces or parentheses.)


> if
> (
> ThisCh >= 'a' and ThisCh <= 'z'
> or
> ThisCh >= 'A' and ThisCh <= 'Z'
> or
> ThisCh >= '0' and ThisCh <= '9'
> or
> ThisCh == '_'
> or
> ThisCh == '-'
> or
> ThisCh == '.'
> or
> ThisCh == '/'
> )
> {
> Result.append(1, ThisCh);
> }

This one could be a Switch (mine allows 'a'..'z' like using gcc's
extension), but that might be overkill.

Otherwise:

if ch in 'A'..'Z' or ch in 'a'..'z' or ch in '0'..'9' or
ch in ['_', '-', '.', '/'] then
result.append(1, ch)

I shortened your ThisCh to something more apt for a local variable.

Alternatively, I'd use:

if namemap[ch] then
...

but this is now rewriting your code, not just showing alternate synax.

Malcolm McLean

unread,
Jan 23, 2024, 11:32:26 AMJan 23
to
On 22/01/2024 20:34, Lawrence D'Oliveiro wrote:
> On Mon, 22 Jan 2024 09:30:21 +0100, David Brown wrote:
>
>> ... I don't use the matching names in C++ either ...
>
> I do, if/when I do use C++ and C. Don’t you think it improves readability:
>
It breaks the rule that, in C, variables and functions are alphnumeric,
whilst operators are symbols. sizeof is an exception, but a justified
one. However it's harder to justify a symbol for "plus" but a word for "or".

--
Check out Basic Algorithms and my other books:
https://www.lulu.com/spotlight/bgy1mm

Lew Pitcher

unread,
Jan 23, 2024, 12:21:54 PMJan 23
to
On Tue, 23 Jan 2024 16:32:09 +0000, Malcolm McLean wrote:

> On 22/01/2024 20:34, Lawrence D'Oliveiro wrote:
>> On Mon, 22 Jan 2024 09:30:21 +0100, David Brown wrote:
>>
>>> ... I don't use the matching names in C++ either ...
>>
>> I do, if/when I do use C++ and C. Don’t you think it improves readability:
>>
> It breaks the rule that, in C, variables and functions are alphnumeric,
> whilst operators are symbols. sizeof is an exception, but a justified
> one. However it's harder to justify a symbol for "plus" but a word for "or".

Less importantly, it also violates the convention that C macros are named in
upper case to distinguish them from keywords and "regular" identifiers.

I'll stick with the native C operators, but IF I were working in an environment
where 'special characters' were problematic (such as where digraphs or trigraphs
are necessary), I'd rather use
a OR b
instead of
a or b

bart

unread,
Jan 23, 2024, 1:34:25 PMJan 23
to
On 23/01/2024 16:32, Malcolm McLean wrote:
> On 22/01/2024 20:34, Lawrence D'Oliveiro wrote:
>> On Mon, 22 Jan 2024 09:30:21 +0100, David Brown wrote:
>>
>>> ... I don't use the matching names in C++ either ...
>>
>> I do, if/when I do use C++ and C. Don’t you think it improves
>> readability:
>>
> It breaks the rule that, in C, variables and functions are alphnumeric,
> whilst operators are symbols. sizeof is an exception, but a justified
> one. However it's harder to justify a symbol for "plus" but a word for
> "or".

But it's OK to justify 'pow' for exponentiation?

Every explanation for && and || for every language that copied them from
C, is that && means AND, and || means OR.

Presumably everyone knows what AND and OR mean. So why not just use AND
and OR?

A lot of C code already looks a sea of punctuation; it can be good to
break it up a little.

Scott Lurndal

unread,
Jan 23, 2024, 1:52:38 PMJan 23
to
bart <b...@freeuk.com> writes:
>On 23/01/2024 16:32, Malcolm McLean wrote:

>
>Every explanation for && and || for every language that copied them from
>C, is that && means AND, and || means OR.

in C, && specifically means 'conditional and'. The programmer can
rely on the fact that the second term will not be evaluated if
the first term evaluates to false.

James Kuyper

unread,
Jan 23, 2024, 2:23:21 PMJan 23
to
Actually, C uses the term "Logical AND". I don't have any idea what
"conditional and" is supposed to mean, except that the explanation you
provide matches the term "Logical AND".

Kalevi Kolttonen

unread,
Jan 23, 2024, 2:32:46 PMJan 23
to
bart <b...@freeuk.com> wrote:
> Presumably everyone knows what AND and OR mean. So
> why not just use AND and OR?

Maybe back in the early days of C even a one byte
mattered? strlen("AND") is 3 and strlen("&&") is 2.
So they chose "&&" and then "||" was chosen because
of symmetry? Just speculation, of course.

Dennis Ritchie has said that he regretted the
spelling of creat(2) function. Presumably the
abbreviation was supposed to save one byte of
storage.

Anyway, sorry for the off-topic, but Python aims to
be like what you say. It should be like executable
pseudo-code in the sense that your carefully written
code reads almost like plain English. I once wrote
a 300 line Python script without any comments simply
because all the identifiers were long enough and
carefully chosen so that comments were not needed.

But the Python designers botched at least one thing
concerning that philosophy: private functions are not
defined by "private" keyword like in Java but instead
the designers violated their own basic principle of easy
readability: the "privateness" is defined by
by prefixing the function names with an underscore ("_").

I find that decision wrong.

br,
KK

bart

unread,
Jan 23, 2024, 3:00:13 PMJan 23
to
On 23/01/2024 19:32, Kalevi Kolttonen wrote:
> bart <b...@freeuk.com> wrote:
>> Presumably everyone knows what AND and OR mean. So
>> why not just use AND and OR?
>
> Maybe back in the early days of C even a one byte
> mattered?

Plenty of languages already existed that used 'and', 'or' and 'not'.

My first language did so as well, and was implemented on a smaller
machine than the first C compiler.

If compact code was advantageous, then you have to wonder about the
considerable amount of punctuation in C.

> strlen("AND") is 3 and strlen("&&") is 2.
> So they chose "&&" and then "||" was chosen because
> of symmetry? Just speculation, of course.

Why two & and two |? Was '|' even commonly available on keyboards at the
time? I'm pretty sure 'o' and 'r' were!

Although whether in lower case, I don't know. If not, then just typing
'if' was going to be a problem.


> Dennis Ritchie has said that he regretted the
> spelling of creat(2) function. Presumably the
> abbreviation was supposed to save one byte of
> storage.

Such identifiers would been exposed to external tools such as assemblers
and linkers, which may have had their own limits. Keywords such as 'and'
are internal to the C compiler.


> Anyway, sorry for the off-topic, but Python aims to
> be like what you say. It should be like executable
> pseudo-code

That's a good idea. I've often wondered why, if pseudo-code is so easy
to understand, why it isn't used more for real languages.


Keith Thompson

unread,
Jan 23, 2024, 3:09:26 PMJan 23
to
kal...@kolttonen.fi (Kalevi Kolttonen) writes:
> bart <b...@freeuk.com> wrote:
>> Presumably everyone knows what AND and OR mean. So
>> why not just use AND and OR?
>
> Maybe back in the early days of C even a one byte
> mattered? strlen("AND") is 3 and strlen("&&") is 2.
> So they chose "&&" and then "||" was chosen because
> of symmetry? Just speculation, of course.
>
> Dennis Ritchie has said that he regretted the
> spelling of creat(2) function. Presumably the
> abbreviation was supposed to save one byte of
> storage.

C's predecessor language B had "&" and "|" operators, bitwise "and" and
"or". It didn't have "&&" or "||". "&" and "|" were used in
expressions like:

if (x > 3 & x < 42)

which was reasonably safe because the "<" and ">" operators always yield
0 or 1.

The logical (not bitwise) and short-circuit "&&" and "||" operators were
added in C and appear in the 1974 C manual. The symbols were a fairly
obvious extension of the existing "& and "|" symbols.

There was probably a fairly strong inclination to use punctation rather
than identifiers for operators. There's no explicit rule to this
effect, but sizeof (and later _Alignof) are the only exceptions to the
pattern.

(Perl did something interesting. It has "&&" and "||" operators like
C's, but it also has "and" and "or" keywords, which have the same
semantics but different precedence.)

Keith Thompson

unread,
Jan 23, 2024, 3:13:42 PMJan 23
to
bart <b...@freeuk.com> writes:
[...]
> But it's OK to justify 'pow' for exponentiation?

"pow" is a library function, not an operator. If C had an exponentation
operator, it would probably have been represented using punctuation
characters, perhaps "**". (Adding a "**" operator now would break some
existing code; `x**y` currently means `x * (*y)`. "^^" might work, but
there doesn't seem to be much demand for an exponentation operator
anyway.)

(Yes, sizeof and _Alignof are operators that use keywords rather than
punctuation symbols. There's no hard rule that operators must be
punctuation, just a general trend.)

Kalevi Kolttonen

unread,
Jan 23, 2024, 3:18:22 PMJan 23
to
bart <b...@freeuk.com> wrote:
> On 23/01/2024 19:32, Kalevi Kolttonen wrote:
>> bart <b...@freeuk.com> wrote:
>>> Presumably everyone knows what AND and OR mean. So
>>> why not just use AND and OR?
>>
>> Maybe back in the early days of C even a one byte
>> mattered?
>
> Plenty of languages already existed that used 'and', 'or' and 'not'.

I actually know that but it could have mattered
to Dennis Ritchie to be as succinct as possible.

In the same spirit as UNIX has "ls" not "list", "cp"
not "copy" and "mv" not "move".

> My first language did so as well, and was implemented on a smaller
> machine than the first C compiler.
>
> If compact code was advantageous, then you have to wonder about the
> considerable amount of punctuation in C.

True.

>> strlen("AND") is 3 and strlen("&&") is 2.
>> So they chose "&&" and then "||" was chosen because
>> of symmetry? Just speculation, of course.
>
> Why two & and two |? Was '|' even commonly available on keyboards at the
> time? I'm pretty sure 'o' and 'r' were!

I really do not know. I never thought of that but
it does seem strange especially if one claims
that they wanted to save storage.

I guess some old formal logic books use
a single "&" for logical AND before the operators
became standardized.

> Although whether in lower case, I don't know. If not,
> then just typing
> 'if' was going to be a problem.
>
>
>> Dennis Ritchie has said that he regretted the
>> spelling of creat(2) function. Presumably the
>> abbreviation was supposed to save one byte of
>> storage.
>
> Such identifiers would been exposed to external tools such as assemblers
> and linkers, which may have had their own limits. Keywords such as 'and'
> are internal to the C compiler.

I don't believe strlen("create") == 6 would have
exceeded any limits. Ritchie's regret seems to
confirm that. It implies that he could have chosen
"create" as well, but for some reason he did not
do so.

>> Anyway, sorry for the off-topic, but Python aims to
>> be like what you say. It should be like executable
>> pseudo-code
>
> That's a good idea. I've often wondered why, if pseudo-code
> is so easy to understand, why it isn't used more for real
> languages.

Yes, Python is a nice language but the last time
I checked, an O'Reilly Learning Python book was something
like 2000 pages long...

ChatGPT did not know the answer, but this time Google
did: Learning Python, 5th edition (2013) is 1643 pages.

I have no problem with large texts, but I just have to
live with a proper subset of Python features.

br,
KK

Kalevi Kolttonen

unread,
Jan 23, 2024, 3:32:53 PMJan 23
to
James Kuyper <james...@alumni.caltech.edu> wrote:
> Actually, C uses the term "Logical AND". I don't have any idea what
> "conditional and" is supposed to mean, except that the explanation you
> provide matches the term "Logical AND".

The term "conditional and" is probably not so good, but the
meaning of it here refers to the familiar short-circuiting
behaviour of C's "&&". The same behaviour exists in, I
think, all UNIX shells.

If I write this in bash:

rm foo.txt && rm bar.txt

then if the first rm-command fails with a non-zero exit value,
then the second rm-command is not executed at all.

It is similar in C code but the zero evaluation value
there means false, i.e. it is completely opposite of the
UNIX shell.

br,
KK

Scott Lurndal

unread,
Jan 23, 2024, 4:28:37 PMJan 23
to
James Kuyper <james...@alumni.caltech.edu> writes:
>On 1/23/24 13:52, Scott Lurndal wrote:
>> bart <b...@freeuk.com> writes:
>>> On 23/01/2024 16:32, Malcolm McLean wrote:
>>
>>>
>>> Every explanation for && and || for every language that copied them from
>>> C, is that && means AND, and || means OR.
>>
>> in C, && specifically means 'conditional and'. The programmer can
>> rely on the fact that the second term will not be evaluated if
>> the first term evaluates to false.
>
>Actually, C uses the term "Logical AND".

The term 'conditional and' has been in common use for decades.

I never claimed it was the term used in the standard, regardless
of the use of the word 'specifically'.

An issue with the use of the iso646 'and' macro is that the
typical reader, unfamiliar with iso646, might assume a bitwise
and rather than a 'logical' or 'conditional' and.

Kaz Kylheku

unread,
Jan 23, 2024, 4:30:35 PMJan 23
to
On 2024-01-23, David Brown <david...@hesbynett.no> wrote:
> On 22/01/2024 21:34, Lawrence D'Oliveiro wrote:
>> On Mon, 22 Jan 2024 09:30:21 +0100, David Brown wrote:
>>
>>> ... I don't use the matching names in C++ either ...
>>
>> I do, if/when I do use C++ and C. Don’t you think it improves readability:
>
> No. But I fully appreciate that this is personal preference and habit.

I believe that some of the identifiers improves readability for people
coming from a programming language which uses those English words for
very similar operators rather than && and ||.

In a green field programming language design, it's probably better
to design that way from the start. It's a nice bonus if a language
looks readable to newcomers.

Generations of C coders are used to && and || though; that's the normal
way to write C. Using these aliases is a vanishingly rare practice. An
important aspect of readability is writing code like everyone else. When
a language is newly designed so that there isn't anyone else, that
doesn't have to be considered.

For that reason, these identifiers should not be used, except for
machine-encoding of programs into a 6 bit character set.

Additionally certain names in the iso646.h header are poorly considered,
and obstruct readability. They use the _eq suffix for an operation that
is assignment.

#define and_eq &=

If the purpose of this header were to optimize readability for those
unfamiliar with C, this should be called

#define and_set &=

or similar.

The assignment operator = should not be read "equals", but "becomes" or
"takes the value" or "is assigned" or "is set to". This should be taken
into consideration when coming up with word-like token or token fragment
to represent it.

Also note the following inconsistency:

#define and &&
#define bitand &
#define and_eq &= // what happened to "bit"?

This looks like and_eq should correspond to &&=, since and is &&,
and bitand is &. &= wants to be bitand_eq.

Clearly, the purpose of this header is to allow C to be written with the
ISO 646 character set. The choices of identifiers do not look like
evidence of readability having been highly prioritized.

Kaz Kylheku

unread,
Jan 23, 2024, 4:49:39 PMJan 23
to
On 2024-01-23, Lew Pitcher <lew.p...@digitalfreehold.ca> wrote:
> On Tue, 23 Jan 2024 16:32:09 +0000, Malcolm McLean wrote:
>
>> On 22/01/2024 20:34, Lawrence D'Oliveiro wrote:
>>> On Mon, 22 Jan 2024 09:30:21 +0100, David Brown wrote:
>>>
>>>> ... I don't use the matching names in C++ either ...
>>>
>>> I do, if/when I do use C++ and C. Don’t you think it improves readability:
>>>
>> It breaks the rule that, in C, variables and functions are alphnumeric,
>> whilst operators are symbols. sizeof is an exception, but a justified
>> one. However it's harder to justify a symbol for "plus" but a word for "or".
>
> Less importantly, it also violates the convention that C macros are named in
> upper case to distinguish them from keywords and "regular" identifiers.

So do true, false, bool, complex, imaginary, errno, assert, fpclassify,
..., and any function supplanted by a macro, such as used to be the case
with getc.

Lawrence D'Oliveiro

unread,
Jan 23, 2024, 4:50:17 PMJan 23
to
On Tue, 23 Jan 2024 06:47:10 +0100, Janis Papanagnou wrote:

> There's also problems with these names. For example '&&' has not the
> semantics of 'and' but of 'and_then', 'or' is actually 'or_else'.

Funnily enough, that is how the languages that offer those words interpret
them. Not just C and C++.

Lawrence D'Oliveiro

unread,
Jan 23, 2024, 4:51:44 PMJan 23
to
On Tue, 23 Jan 2024 16:32:09 +0000, Malcolm McLean wrote:

> It breaks the rule that, in C, variables and functions are alphnumeric,
> whilst operators are symbols.

Where is there such a “rule”?

> sizeof is an exception, but a justified one.

This is how religious people argue: they use circular reasoning to say
something is justified because it is justified.

Lawrence D'Oliveiro

unread,
Jan 23, 2024, 4:52:15 PMJan 23
to
On Tue, 23 Jan 2024 17:21:40 -0000 (UTC), Lew Pitcher wrote:

> Less importantly, it also violates the convention that C macros are
> named in upper case to distinguish them from keywords and "regular"
> identifiers.

Why does C allow lowercase in macro names, then?

Lawrence D'Oliveiro

unread,
Jan 23, 2024, 4:53:15 PMJan 23
to
On Tue, 23 Jan 2024 20:32:39 -0000 (UTC), Kalevi Kolttonen wrote:

> If I write this in bash:
>
> rm foo.txt && rm bar.txt

Then the second is only executed if the first one returns zero.

What does C do in this case?

Lawrence D'Oliveiro

unread,
Jan 23, 2024, 4:56:12 PMJan 23
to
On Tue, 23 Jan 2024 19:32:26 -0000 (UTC), Kalevi Kolttonen wrote:

> Dennis Ritchie has said that he regretted the spelling of creat(2)
> function. Presumably the abbreviation was supposed to save one byte of
> storage.

Given that, in POSIX, all the functions of creat(2) have been subsumed
under open(2) anyway, we can largely ignore that.

There are other worse problems with C. Like its use of “=” (the
mathematical equality operator) for assignment, instead of using the “:=”
symbol that the Algols had adopted.

> But the Python designers botched at least one thing concerning that
> philosophy: private functions are not defined by "private" keyword like
> in Java but instead the designers violated their own basic principle of
> easy readability: the "privateness" is defined by by prefixing the
> function names with an underscore ("_").

That is merely a convention, a hint that the user might want to stay away
from such a symbol, not a hard requirement, which is why it was designed
that way. As Guido van Rossum has said: “We are all consenting adults
here”.

There are things wrong with Python you can complain about. But that isn’t
one of them.

Lawrence D'Oliveiro

unread,
Jan 23, 2024, 5:00:46 PMJan 23
to
On Tue, 23 Jan 2024 12:09:09 -0800, Keith Thompson wrote:

> C's predecessor language B ...

Let me see if I understand the genealogy:

B was an adaptation of Martin Richards’ BCPL. BCPL was a low-level,
typeless language designed for system programming. It originated before
byte-addressable machines became popular. In fact, Richards looked at
adapting BCPL to the PDP-11, and came away unimpressed with the latter’s
architecture.

So B was BCPL adapted by the Bell Labs crew to work on a byte-addressable
machine. But it still didn’t have types. And types turned out to be rather
important to the implementation of a decent OS and accompanying software.
So the Bell Labs came up with the successor language C, which did have
types.

Kaz Kylheku

unread,
Jan 23, 2024, 5:00:59 PMJan 23
to
On 2024-01-23, Scott Lurndal <sc...@slp53.sl.home> wrote:
> James Kuyper <james...@alumni.caltech.edu> writes:
>>On 1/23/24 13:52, Scott Lurndal wrote:
>>> bart <b...@freeuk.com> writes:
>>>> On 23/01/2024 16:32, Malcolm McLean wrote:
>>>
>>>>
>>>> Every explanation for && and || for every language that copied them from
>>>> C, is that && means AND, and || means OR.
>>>
>>> in C, && specifically means 'conditional and'. The programmer can
>>> rely on the fact that the second term will not be evaluated if
>>> the first term evaluates to false.
>>
>>Actually, C uses the term "Logical AND".
>
> The term 'conditional and' has been in common use for decades.

Also, a bitwise and is logical!

ANSI Common Lisp uses symbols like logand, logior, logxor, ...
for bitwise operations.

When you implement this stuff with electronic gates it is digital logic
circuits. You can read live values in it with a logic probe.

Lawrence D'Oliveiro

unread,
Jan 23, 2024, 5:01:24 PMJan 23
to
On Tue, 23 Jan 2024 12:13:27 -0800, Keith Thompson wrote:

> There's no hard rule that operators must be
> punctuation, just a general trend.

And iso646.h demonstrates that that trend is at an end.

bart

unread,
Jan 23, 2024, 5:03:18 PMJan 23
to
On 23/01/2024 21:30, Kaz Kylheku wrote:

> Also note the following inconsistency:
>
> #define and &&
> #define bitand &
> #define and_eq &= // what happened to "bit"?
>
> This looks like and_eq should correspond to &&=, since and is &&,
> and bitand is &. &= wants to be bitand_eq.
>
> Clearly, the purpose of this header is to allow C to be written with the
> ISO 646 character set. The choices of identifiers do not look like
> evidence of readability having been highly prioritized.

It shows this is a poor man's way of extending a language's syntax.

It's forgivable in user-code, as there is no other way of doing it. But
those new operator names are supposed to look like they are built-in.

If they were, you'd be able to do this:

a bitand= b;

Actually, I thought the macros could be used like that. But '&=' needs
to be a single token, not two.

Also, why isn't 'a &&= b' valid? It would just mean 'a = a && b'.

Kaz Kylheku

unread,
Jan 23, 2024, 5:09:51 PMJan 23
to
C also doesn't evaluate the right operand if the left one is
true.

However in C, the following:

a && b || c && d

is parsed like this:

(a && b) || (c && d)

whereas in the shell:

(((a && b) || c) && d)

where I'm using "virtual parentheses". If you actually stick in real
ones, they denote subshell execution in a separate process. (Bash
allows curly braces for command grouping that doesn't create
processes.)

bart

unread,
Jan 23, 2024, 5:34:13 PMJan 23
to
On 23/01/2024 22:00, Kaz Kylheku wrote:
> On 2024-01-23, Scott Lurndal <sc...@slp53.sl.home> wrote:
>> James Kuyper <james...@alumni.caltech.edu> writes:
>>> On 1/23/24 13:52, Scott Lurndal wrote:
>>>> bart <b...@freeuk.com> writes:
>>>>> On 23/01/2024 16:32, Malcolm McLean wrote:
>>>>
>>>>>
>>>>> Every explanation for && and || for every language that copied them from
>>>>> C, is that && means AND, and || means OR.
>>>>
>>>> in C, && specifically means 'conditional and'. The programmer can
>>>> rely on the fact that the second term will not be evaluated if
>>>> the first term evaluates to false.
>>>
>>> Actually, C uses the term "Logical AND".
>>
>> The term 'conditional and' has been in common use for decades.
>
> Also, a bitwise and is logical!

Only on individual bits. The result of A & B can be any value in the
range of A and B's type, not just true and false.

(My tools internally use ANDL/ORL/NOTL for logical versions, and
IAND/IOR/IXOR/INOT for bitwise. I don't use bare AND/OR/NOT. There is
some confusion however with x64 opcodes which use those for bitwise
instructions.)

> ANSI Common Lisp uses symbols like logand, logior, logxor, ...
> for bitwise operations.

Then it is confusing. What does it use for non-bitwise logical operations?

> When you implement this stuff with electronic gates it is digital logic
> circuits. You can read live values in it with a logic probe.

Yes. You put the probe on one signal line to read true or false on that
line.


Kalevi Kolttonen

unread,
Jan 23, 2024, 5:38:00 PMJan 23
to
Kaz Kylheku <433-92...@kylheku.com> wrote:
> On 2024-01-23, Lawrence D'Oliveiro <l...@nz.invalid> wrote:
>> On Tue, 23 Jan 2024 20:32:39 -0000 (UTC), Kalevi Kolttonen wrote:
>>
>>> If I write this in bash:
>>>
>>> rm foo.txt && rm bar.txt
>>
>> Then the second is only executed if the first one returns zero.
>>
>> What does C do in this case?
>
> C also doesn't evaluate the right operand if the left one is
> true.

We are speaking about logical AND evaluation here.

If the left one is *false*, then the evaluation stops
because the whole conjunction is known to false.

If we are talking about logical OR, then if the left
operand is true, then the evaluation stops because
the disjunction is known to be true.

So this distinction between "conditional and" and
"logical and" boils down to the short-circuiting
left-to-right evaluation order that is guaranteed
by C language standard.

We could conceivably have "logical and" with
out-of-order or right-to-left evaluation. I am
pretty sure that not all computer languages
provide guarantees about the order of evaluation.

br,
KK

Scott Lurndal

unread,
Jan 23, 2024, 5:45:32 PMJan 23
to
I don't see you you can draw that conclusion. The header
file has been around for over three decades, yet it's not
in common (or even uncommon) use.

Kalevi Kolttonen

unread,
Jan 23, 2024, 5:47:44 PMJan 23
to
Lawrence D'Oliveiro <l...@nz.invalid> wrote:
> On Tue, 23 Jan 2024 19:32:26 -0000 (UTC), Kalevi Kolttonen wrote:
>
>> Dennis Ritchie has said that he regretted the spelling of creat(2)
>> function. Presumably the abbreviation was supposed to save one byte of
>> storage.
>
> Given that, in POSIX, all the functions of creat(2) have been subsumed
> under open(2) anyway, we can largely ignore that.

I know. creat() is now completely redundant because
open() suffices. The reason I brought it up was just
so that people would realize that at least sometimes
it was a matter of saving storage space - even one
byte.

> There are other worse problems with C. Like its use of “=” (the
> mathematical equality operator) for assignment, instead of using the “:=”
> symbol that the Algols had adopted.

Well I started with Microsoft BASIC on Commodore 64 39 years ago.
So I am well used to "=" and do not consider it a problem.

>> But the Python designers botched at least one thing concerning that
>> philosophy: private functions are not defined by "private" keyword like
>> in Java but instead the designers violated their own basic principle of
>> easy readability: the "privateness" is defined by by prefixing the
>> function names with an underscore ("_").
>
> That is merely a convention, a hint that the user might want to stay away
> from such a symbol, not a hard requirement, which is why it was designed
> that way. As Guido van Rossum has said: “We are all consenting adults
> here”.

What?! Are you saying that there is no way to label functions as private
in Python? That sounds absolutely horrible. Why would anyone design a
language with object-oriented features without support for encapsulation?

br,
KK

Keith Thompson

unread,
Jan 23, 2024, 5:49:25 PMJan 23
to
sc...@slp53.sl.home (Scott Lurndal) writes:
[...]
> An issue with the use of the iso646 'and' macro is that the
> typical reader, unfamiliar with iso646, might assume a bitwise
> and rather than a 'logical' or 'conditional' and.

It uses "bitand" for "&", "and" for "&&". (Reasonable, IMHO, because
"&&" is more common. One might argue that when C split B's "&" operator
into bitwise and logical versions, it would have made sense to use "&"
for logical and "&&" for bitwise -- but that ship sailed *long* ago.)

Here are the symbols defined in <iso646.h> on my system; it should be
the same in any implementation.

#define and &&
#define and_eq &=
#define bitand &
#define bitor |
#define compl ~
#define not !
#define not_eq !=
#define or ||
#define or_eq |=
#define xor ^
#define xor_eq ^=

Keith Thompson

unread,
Jan 23, 2024, 5:52:07 PMJan 23
to
Lawrence D'Oliveiro <l...@nz.invalid> writes:
Because it's a convention, not a language rule.

Kalevi Kolttonen

unread,
Jan 23, 2024, 5:54:47 PMJan 23
to
Lawrence D'Oliveiro <l...@nz.invalid> wrote:
In the real world, iso646.h is almost never used. I
do not claim to be any kind of programming expert but
I have read a considerable amount of C code of various
projects. I have personally witnessed that everybody
always uses "&&" and "||".

You can probably download thousands of C codebases
from github and you will find out that reality is
like that.

br,
KK

Keith Thompson

unread,
Jan 23, 2024, 6:10:54 PMJan 23
to
Lawrence D'Oliveiro <l...@nz.invalid> writes:
It does no such thing. Macro names are identifiers, and <iso646.h> only
defined macro names. Since <iso646.h> is rarely used, its existence
doesn't demonstrate any kind of trend.

The header was introduced to make it easier (or possible) to write C
code on systems/keyboards that don't support certain characters like '&'
and '|' -- similar to digraphs and trigraphs.

Lawrence D'Oliveiro

unread,
Jan 23, 2024, 6:34:02 PMJan 23
to
On Tue, 23 Jan 2024 14:51:52 -0800, Keith Thompson wrote:

> Lawrence D'Oliveiro <l...@nz.invalid> writes:
>
>> On Tue, 23 Jan 2024 17:21:40 -0000 (UTC), Lew Pitcher wrote:
>>
>>> Less importantly, it also violates the convention that C macros are
>>> named in upper case to distinguish them from keywords and "regular"
>>> identifiers.
>>
>> Why does C allow lowercase in macro names, then?
>
> Because it's a convention, not a language rule.

So what would one mean by “violate”, other than “I personally don’t like
it”?

Keith Thompson

unread,
Jan 23, 2024, 6:35:53 PMJan 23
to
kal...@kolttonen.fi (Kalevi Kolttonen) writes:
> Lawrence D'Oliveiro <l...@nz.invalid> wrote:
>> On Tue, 23 Jan 2024 19:32:26 -0000 (UTC), Kalevi Kolttonen wrote:
>>
>>> Dennis Ritchie has said that he regretted the spelling of creat(2)
>>> function. Presumably the abbreviation was supposed to save one byte of
>>> storage.
>>
>> Given that, in POSIX, all the functions of creat(2) have been subsumed
>> under open(2) anyway, we can largely ignore that.
>
> I know. creat() is now completely redundant because
> open() suffices. The reason I brought it up was just
> so that people would realize that at least sometimes
> it was a matter of saving storage space - even one
> byte.

I don't believe it was ever about storage space.

Early UNIX systems used ASR-33 teletypes for interactive I/O. The
keyboard required a lot more physical force than modern keyboards do,
which made names like "mv" and "rm" easier to type than, say "rename"
and "delete". (And it's turned out that the terse names aren't much of
a problem. It would be easy to set up aliases with more verbose names,
but few if any people bother to do so.)

Some function names were limited to 6 characters by linker limitations,
but that doesn't explain "creat", which was just a poor choice.

[...]

Lawrence D'Oliveiro

unread,
Jan 23, 2024, 6:37:54 PMJan 23
to
On Tue, 23 Jan 2024 22:47:30 -0000 (UTC), Kalevi Kolttonen wrote:

> What?! Are you saying that there is no way to label functions as private
> in Python? That sounds absolutely horrible. Why would anyone design a
> language with object-oriented features without support for
> encapsulation?

Because Python is not Java.

For comparison, Java’s core language reference manual is (last I checked)
around 900 pages. Python’s core language is less than a quarter of that.
And yet it manages to include features, like custom operator overloads,
that Java does not.

Python also has metaclasses. Does your favourite OO language have
metaclasses?

Python doesn’t need “final” or “private” or “protected”, because it is
after all a dynamic language. You can write functions which are class
factories and function factories.

Actually, you can achieve the effect of access restrictions that way.

Lawrence D'Oliveiro

unread,
Jan 23, 2024, 6:39:21 PMJan 23
to
On Tue, 23 Jan 2024 22:45:17 GMT, Scott Lurndal wrote:

> The header file has been around for over three decades, yet it's not in
> common (or even uncommon) use.

The nice thing is, I don’t have to care. It has to be part of any
standards-compliant C compiler, therefore I am free to use it. And I do.

Lawrence D'Oliveiro

unread,
Jan 23, 2024, 6:40:39 PMJan 23
to
On Tue, 23 Jan 2024 15:10:36 -0800, Keith Thompson wrote:

> Lawrence D'Oliveiro <l...@nz.invalid> writes:
>
>> On Tue, 23 Jan 2024 12:13:27 -0800, Keith Thompson wrote:
>>
>>> There's no hard rule that operators must be punctuation, just a
>>> general trend.
>>
>> And iso646.h demonstrates that that trend is at an end.
>
> It does no such thing.

A “trend” means ongoing developments continue to follow the same pattern.
There have been no new non-alphanumeric operators added to C in, oh, over
40 years. Therefore the “trend” actually came to an end a long time ago.

Kaz Kylheku

unread,
Jan 23, 2024, 6:46:30 PMJan 23
to
On 2024-01-23, bart <b...@freeuk.com> wrote:
>> ANSI Common Lisp uses symbols like logand, logior, logxor, ...
>> for bitwise operations.
>
> Then it is confusing. What does it use for non-bitwise logical operations?

and, or, not

Scott Lurndal

unread,
Jan 23, 2024, 6:52:07 PMJan 23
to
kal...@kolttonen.fi (Kalevi Kolttonen) writes:
>Lawrence D'Oliveiro <l...@nz.invalid> wrote:
>> On Tue, 23 Jan 2024 19:32:26 -0000 (UTC), Kalevi Kolttonen wrote:
>>
>>> Dennis Ritchie has said that he regretted the spelling of creat(2)
>>> function. Presumably the abbreviation was supposed to save one byte of
>>> storage.
>>
>> Given that, in POSIX, all the functions of creat(2) have been subsumed
>> under open(2) anyway, we can largely ignore that.
>
>I know. creat() is now completely redundant because
>open() suffices. The reason I brought it up was just
>so that people would realize that at least sometimes
>it was a matter of saving storage space - even one
>byte.

IIRC, it was more about allowing space for a leading underscore
added during the link process.

bart

unread,
Jan 23, 2024, 7:06:28 PMJan 23
to
On 23/01/2024 22:47, Kalevi Kolttonen wrote:
> Lawrence D'Oliveiro <l...@nz.invalid> wrote:
>> On Tue, 23 Jan 2024 19:32:26 -0000 (UTC), Kalevi Kolttonen wrote:
>>
>>> Dennis Ritchie has said that he regretted the spelling of creat(2)
>>> function. Presumably the abbreviation was supposed to save one byte of
>>> storage.
>>
>> Given that, in POSIX, all the functions of creat(2) have been subsumed
>> under open(2) anyway, we can largely ignore that.
>
> I know. creat() is now completely redundant because
> open() suffices. The reason I brought it up was just
> so that people would realize that at least sometimes
> it was a matter of saving storage space - even one
> byte.
>
>> There are other worse problems with C. Like its use of “=” (the
>> mathematical equality operator) for assignment, instead of using the “:=”
>> symbol that the Algols had adopted.
>
> Well I started with Microsoft BASIC on Commodore 64 39 years ago.
> So I am well used to "=" and do not consider it a problem.

I've used ":=" with Algol and "=" with Fortran (a bit longer ago).

That is not itself the problem.

The problem is allowing both assignment and equality within the same
expression, which is what C does. Algol, Fortran and BASIC didn't do that.

If that wasn't the case, then you could use "=" for both assignment, and
equality, without ambiguity.

Languages that use ":=" and "=" for those operations, fare better than C
that uses "=" and "==".

>>> But the Python designers botched at least one thing concerning that
>>> philosophy: private functions are not defined by "private" keyword like
>>> in Java but instead the designers violated their own basic principle of
>>> easy readability: the "privateness" is defined by by prefixing the
>>> function names with an underscore ("_").
>>
>> That is merely a convention, a hint that the user might want to stay away
>> from such a symbol, not a hard requirement, which is why it was designed
>> that way. As Guido van Rossum has said: “We are all consenting adults
>> here”.
>
> What?! Are you saying that there is no way to label functions as private
> in Python? That sounds absolutely horrible. Why would anyone design a
> language with object-oriented features without support for encapsulation?

Python is 'ultra-dynamic'. That's why it's so hard to make it
performant. So you can do this:

import math

math.pi = "pie"
math.sqrt = lambda x:x*x

print(math.pi*2)
print(math.sqrt(10))

Output is:

piepie
100

Keith Thompson

unread,
Jan 23, 2024, 7:16:46 PMJan 23
to
Lawrence D'Oliveiro <l...@nz.invalid> writes:
> On Tue, 23 Jan 2024 14:51:52 -0800, Keith Thompson wrote:
>> Lawrence D'Oliveiro <l...@nz.invalid> writes:
>>> On Tue, 23 Jan 2024 17:21:40 -0000 (UTC), Lew Pitcher wrote:
>>>> Less importantly, it also violates the convention that C macros are
>>>> named in upper case to distinguish them from keywords and "regular"
>>>> identifiers.
>>>
>>> Why does C allow lowercase in macro names, then?
>>
>> Because it's a convention, not a language rule.
>
> So what would one mean by “violate”, other than “I personally don’t like
> it”?

Obviously, it would mean not following the convention.

There clearly is a convention that most macro names should be defined in
all caps. Equally clearly, the standard library does not uniformly
follow that convention. I have no problem with that.

I might have some more thoughts on the matter, but I'm not sure where
you're going with this.

Keith Thompson

unread,
Jan 23, 2024, 7:27:43 PMJan 23
to
OK, "trend" was not the best word; it implies something changing over
time, which isn't really the case here. Perhaps "convention" would have
been more apt.

I believe the only thing iso646.h demonstrates is the (largely former)
need to write C on systems that do not support full ASCII. This is
fully explained in the C99 Rationale,
<http://www.open-std.org/jtc1/sc22/WG14/www/C99RationaleV5.10.pdf>;
search for "MSE.4". It says nothing about "and" being more readable
than "&&" on systems that are able to display the '&' character.

If you want to use it in your own code, nobody will stop you.

Chris M. Thomasson

unread,
Jan 23, 2024, 7:35:17 PMJan 23
to
Actually, this rings a bell in my head about that leading underscore.
Notice the difference between:

Take this function:
____________________________
.align 16
.globl ac_i686_stack_mpmc_push_cas
ac_i686_stack_mpmc_push_cas:
movl 4(%esp), %edx
movl (%edx), %eax
movl 8(%esp), %ecx

ac_i686_stack_mpmc_push_cas_retry:
movl %eax, (%ecx)
lock cmpxchgl %ecx, (%edx)
jne ac_i686_stack_mpmc_push_cas_retry
ret
____________________________


vs this one wrt mingw over on windows:

http://web.archive.org/web/20060214112545/http://appcore.home.comcast.net/appcore/src/cpu/i686/ac_i686_mingw_asm.html

Notice the leading underscore! Iirc, I could not get it to link
correctly using mingw.
____________________________
.align 16
.globl _ac_i686_stack_mpmc_push_cas
_ac_i686_stack_mpmc_push_cas:
movl 4(%esp), %edx
movl (%edx), %eax
movl 8(%esp), %ecx

_ac_i686_stack_mpmc_push_cas_retry:
movl %eax, (%ecx)
lock cmpxchgl %ecx, (%edx)
jne _ac_i686_stack_mpmc_push_cas_retry
ret
____________________________

Lawrence D'Oliveiro

unread,
Jan 23, 2024, 7:39:33 PMJan 23
to
On Tue, 23 Jan 2024 16:16:31 -0800, Keith Thompson wrote:

> Obviously, it would mean not following the convention.

Thumbing one’s nose at staid convention? How shocking!

Chris M. Thomasson

unread,
Jan 23, 2024, 7:40:28 PMJan 23
to
On 1/23/2024 4:35 PM, Chris M. Thomasson wrote:
> On 1/23/2024 3:51 PM, Scott Lurndal wrote:
>> kal...@kolttonen.fi (Kalevi Kolttonen) writes:
>>> Lawrence D'Oliveiro <l...@nz.invalid> wrote:
>>>> On Tue, 23 Jan 2024 19:32:26 -0000 (UTC), Kalevi Kolttonen wrote:
>>>>
>>>>> Dennis Ritchie has said that he regretted the spelling of creat(2)
>>>>> function. Presumably the abbreviation was supposed to save one byte of
>>>>> storage.
>>>>
>>>> Given that, in POSIX, all the functions of creat(2) have been subsumed
>>>> under open(2) anyway, we can largely ignore that.
>>>
>>> I know. creat() is now completely redundant because
>>> open() suffices. The reason I brought it up was just
>>> so that people would realize that at least sometimes
>>> it was a matter of saving storage space - even one
>>> byte.
>>
>> IIRC, it was more about allowing space for a leading underscore
>> added during the link process.
>
> Actually, this rings a bell in my head about that leading underscore.
> Notice the difference between:
[...]

For some damn reason that bell toll made me think of the following song:

Ring My Bell

https://youtu.be/Dp11DjaUc5A?t=45

lol! ;^D


Lawrence D'Oliveiro

unread,
Jan 23, 2024, 7:41:16 PMJan 23
to
On Tue, 23 Jan 2024 15:35:39 -0800, Keith Thompson wrote:

> The keyboard required a lot more physical force than modern keyboards
> do, which made names like "mv" and "rm" easier to type than, say
> "rename" and "delete".

And yet it turns out the OS calls are indeed things like “rename” and
“unlink”, not “mv” or “rm”.

James Kuyper

unread,
Jan 23, 2024, 7:46:10 PMJan 23
to
On 1/23/24 16:28, Scott Lurndal wrote:
> James Kuyper <james...@alumni.caltech.edu> writes:
>> On 1/23/24 13:52, Scott Lurndal wrote:
>>> bart <b...@freeuk.com> writes:
>>>> On 23/01/2024 16:32, Malcolm McLean wrote:
>>>
>>>>
>>>> Every explanation for && and || for every language that copied them from
>>>> C, is that && means AND, and || means OR.
>>>
>>> in C, && specifically means 'conditional and'. The programmer can
>>> rely on the fact that the second term will not be evaluated if
>>> the first term evaluates to false.
>>
>> Actually, C uses the term "Logical AND".
>
> The term 'conditional and' has been in common use for decades.

I've never heard of it. When searching Wikipedia, "conditional and" the
first two pages of hits don't seem to contain any that are actually
relevant. A search on "logical and", on the other hand, redirects to
"logical conjunction", which does seem to be relevant, yet it makes no
reference to "conditional and" as an alternative term for the same
thing. I think that that term might not be as widely used as you think.

A Google search for "logical and" has many relevant hits. A search for
"conditional and" produces a much smaller number of hits, which suggest
that it's a term associated with C# and Java, and at least one source
described it by saying the "coditional and operator performs a ogical
and operation", which sounds rather confused to me.

Lawrence D'Oliveiro

unread,
Jan 23, 2024, 7:47:18 PMJan 23
to
On Tue, 23 Jan 2024 16:27:25 -0800, Keith Thompson wrote:

> I believe the only thing iso646.h demonstrates is the (largely former)
> need to write C on systems that do not support full ASCII.

It does seem a very late addition for a purpose which would have been a
lot more relevant decades earlier. By that point, implementations that did
not support full ASCII would have been museum pieces.

Reminds me of how PL/I added “eq”, “ne”, “lt”, ”gt”, “le”, “ge” as
alternatives to “=”, “¬=”, “<”, ”>“, “¬>”, “¬<” for use on systems which
didn’t have the requisite character set.

Incidentally, those six symbols were the only reserved words in the entire
language. You’d think they could have done it Fortran-style, without
reserved words.

> If you want to use it in your own code, nobody will stop you.

But will I continue to hear complaints from you about it?

Keith Thompson

unread,
Jan 23, 2024, 8:32:58 PMJan 23
to
Lawrence D'Oliveiro <l...@nz.invalid> writes:
> On Tue, 23 Jan 2024 16:27:25 -0800, Keith Thompson wrote:
>> I believe the only thing iso646.h demonstrates is the (largely former)
>> need to write C on systems that do not support full ASCII.
>
> It does seem a very late addition for a purpose which would have been a
> lot more relevant decades earlier. By that point, implementations that did
> not support full ASCII would have been museum pieces.

<iso646.h> was added in 1995, and it was intended to replace a number of
implementation-specific workarounds. You can learn more if you'll read
the C99 Rationale that I cited earlier.

[...]

>> If you want to use it in your own code, nobody will stop you.
>
> But will I continue to hear complaints from you about it?

I can't continue what I never started.

Lawrence D'Oliveiro

unread,
Jan 23, 2024, 9:42:15 PMJan 23
to
On Tue, 23 Jan 2024 17:32:37 -0800, Keith Thompson wrote:

> Lawrence D'Oliveiro <l...@nz.invalid> writes:
>>
>> It does seem a very late addition for a purpose which would have been a
>> lot more relevant decades earlier. By that point, implementations that
>> did not support full ASCII would have been museum pieces.
>
> <iso646.h> was added in 1995, and it was intended to replace a number of
> implementation-specific workarounds.

Just in time for them to become unnecessary, I would say.

>> But will I continue to hear complaints from you about it?
>
> I can't continue what I never started.

I’ll take that as a “yes”.

Kaz Kylheku

unread,
Jan 23, 2024, 10:13:25 PMJan 23
to
Consider that the /bin/mv executable perhaps only contains as few
as just one call to the rename function.

The mv program is invoked many more times than the number of
times someone typed out the rename call in its source code.

Short keyboard sequences in the UI level are much more important
than function names in the source code.

James Kuyper

unread,
Jan 23, 2024, 11:27:09 PMJan 23
to
On 1/23/24 19:27, Keith Thompson wrote:
...
> I believe the only thing iso646.h demonstrates is the (largely former)
> need to write C on systems that do not support full ASCII. This is
> fully explained in the C99 Rationale,
> <http://www.open-std.org/jtc1/sc22/WG14/www/C99RationaleV5.10.pdf>;
> search for "MSE.4". It says nothing about "and" being more readable
> than "&&" on systems that are able to display the '&' character.

It does say, in lines 26-29, that "The Committee recognizes that the
solution offered in this header is incomplete and involves a mixture of
approaches, but nevertheless believes that it can help make Standard C
programs more readable." However, if you examine the context of that
statement, what it's saying is that they are more readable than is
trigraphs. In other words, they are saying that "or" is more readable
than "??!??!", which I doubt that anyone would disagree with.

Keith Thompson

unread,
Jan 23, 2024, 11:53:25 PMJan 23
to
It's also more readable than, say, "Hello, world¥n", which is what
"Hello, world\n" looks like in JIS X 0201, a Japanese variant of ASCII.

Before Unicode, it was common to define 7-bit character sets that
replaced some characters with local versions such as accented letters.
I vaguely recall that some C programmers back in the day simply got used
to backslashes looking like Yen signs.

The Rationale also makes it clear that trigraphs, digraphs, and
<iso646.h> were all invented (not all at the same time) to solve the
same class of problems.

James Kuyper

unread,
Jan 23, 2024, 11:56:26 PMJan 23
to
On 1/23/24 19:47, Lawrence D'Oliveiro wrote:
> On Tue, 23 Jan 2024 16:27:25 -0800, Keith Thompson wrote:
>
>> I believe the only thing iso646.h demonstrates is the (largely former)
>> need to write C on systems that do not support full ASCII.
>
> It does seem a very late addition for a purpose which would have been a
> lot more relevant decades earlier. By that point, implementations that did
> not support full ASCII would have been museum pieces.

No, <iso646.h> was approved as part of AMD1, in 1995. For the countries
it was targeted at, full ASCII was not a tenable solution - it could not
be used to write their languages. The were still using encodings such as
shift-JIS and ISO/IEC 8859-10. Those did not become museum pieces until
after the widespread adoption of Unicode, which came out in 1996, and
did not become widely supported for many years after that.

>> If you want to use it in your own code, nobody will stop you.
>
> But will I continue to hear complaints from you about it?

If you've misunderstood the comments you've already received as
complaints, I think it's quite likely that you'll continue doing so.

Lawrence D'Oliveiro

unread,
Jan 24, 2024, 12:24:53 AMJan 24
to
On Tue, 23 Jan 2024 23:56:11 -0500, James Kuyper wrote:

> No, <iso646.h> was approved as part of AMD1, in 1995. For the countries
> it was targeted at, full ASCII was not a tenable solution - it could not
> be used to write their languages. The were still using encodings such as
> shift-JIS and ISO/IEC 8859-10.

But ASCII is a 7-bit code. The ISO 8859 codes are all ASCII supersets. And
also remember what the “shift” in “shift-JIS” stands for. Oh, and the name
of the corporation that created it in the first place is a bit of a
giveaway.

Keith Thompson

unread,
Jan 24, 2024, 12:44:08 AMJan 24
to
Lawrence D'Oliveiro <l...@nz.invalid> writes:
> On Tue, 23 Jan 2024 23:56:11 -0500, James Kuyper wrote:
>> No, <iso646.h> was approved as part of AMD1, in 1995. For the countries
>> it was targeted at, full ASCII was not a tenable solution - it could not
>> be used to write their languages. The were still using encodings such as
>> shift-JIS and ISO/IEC 8859-10.
>
> But ASCII is a 7-bit code.

Yes, we know.

> The ISO 8859 codes are all ASCII supersets.

Right, so ISO 8859-10 might not have been a good example.

> And
> also remember what the “shift” in “shift-JIS” stands for.

Remember? I never knew. Feel free to enlighten us if it's relevant.

> Oh, and the name
> of the corporation that created it in the first place is a bit of a
> giveaway.

Since you don't seem inclined to share that information, it was
developed by a Japanese company called "ASCII Corporation". Perhaps you
could explain whether and how that's relevant.

In the Shift-JIS encoding, character 0x5C, which is the backslash in
ASCII and Unicode, is the Yen sign. That means that if a C source file
contains "Hello, world\n", viewing it as Shift-JIS makes it look like
"Hello, world¥n", but a C compiler that treats its input as ASCII would
see a backslash. C's use of almost all of the printable ASCII
characters caused problems on systems that used certain other character
sets. Trigraphs, digraphs, and <iso646.h> were all attempts to lessen
the impact of those problems. (Of these, only trigraphs are relevant
for the backslash character.)

EBCDIC systems were another problem area; for example at least some
variants of EBCDIC have no '[' and ']' characters.

Unicode and UTF-8 (or, if necessary, UTF-16) have largely reduced the
need for these solutions, but the problems were very real in 1995, and
may still be present in some niche environments today.

Lawrence D'Oliveiro

unread,
Jan 24, 2024, 1:05:14 AMJan 24
to
On Tue, 23 Jan 2024 06:54:56 +0100, Janis Papanagnou wrote:

> ... in my professional contexts there where even [coding] standards
> defined that you had to follow.

What about the open-source code that your company takes without paying? Do
you demand that that code follow your rules as well? Do you send it back
to the developers to demand they rewrite it for you?

Lawrence D'Oliveiro

unread,
Jan 24, 2024, 1:35:18 AMJan 24
to
On Tue, 23 Jan 2024 21:43:44 -0800, Keith Thompson wrote:

> In the Shift-JIS encoding, character 0x5C, which is the backslash in
> ASCII and Unicode, is the Yen sign. That means that if a C source file
> contains "Hello, world\n", viewing it as Shift-JIS makes it look like
> "Hello, world¥n", but a C compiler that treats its input as ASCII would
> see a backslash.

So what exactly does iso646.h offer to deal with this?

.

.

.

(crickets)

.

.

.

Janis Papanagnou

unread,
Jan 24, 2024, 2:25:52 AMJan 24
to
On 23.01.2024 18:21, Lew Pitcher wrote:
> On Tue, 23 Jan 2024 16:32:09 +0000, Malcolm McLean wrote:
>> On 22/01/2024 20:34, Lawrence D'Oliveiro wrote:
>>> On Mon, 22 Jan 2024 09:30:21 +0100, David Brown wrote:
>>>
>>>> ... I don't use the matching names in C++ either ...
>>>
>>> I do, if/when I do use C++ and C. Don’t you think it improves readability:
>>>
>> It breaks the rule that, in C, variables and functions are alphnumeric,
>> whilst operators are symbols. sizeof is an exception, but a justified
>> one. However it's harder to justify a symbol for "plus" but a word for "or".
>
> Less importantly, it also violates the convention that C macros are named in
> upper case to distinguish them from keywords and "regular" identifiers.

Interestingly the convention had been (AFAICT) to uppercase *all* CPP
items, _mostly_. But in practice we've seen CPP function macros that
were lowercase even in system headers (ISTR some functions in stdio).
It certainly has advantages to uppercase macro functions to be sure
about possible side effects, like in FUNCT(a++). OTOH, for plain CPP
constants literals it's probably unnecessary to capitalize them.

> [...]

Janis


Janis Papanagnou

unread,
Jan 24, 2024, 2:38:54 AMJan 24
to
On 23.01.2024 21:32, Kalevi Kolttonen wrote:
>
> The term "conditional and" is probably not so good, but the
> meaning of it here refers to the familiar short-circuiting
> behaviour of C's "&&". The same behaviour exists in, I
> think, all UNIX shells.
>
> If I write this in bash:
>
> rm foo.txt && rm bar.txt
>
> then if the first rm-command fails with a non-zero exit value,
> then the second rm-command is not executed at all.

I don't think shell's behavior is so intuitive (unless also
considering the evaluation semantics)

$ echo a || echo b && echo c
a
c


Janis

Janis Papanagnou

unread,
Jan 24, 2024, 2:53:20 AMJan 24
to
On 23.01.2024 22:30, Kaz Kylheku wrote:
> On 2024-01-23, David Brown <david...@hesbynett.no> wrote:
>> On 22/01/2024 21:34, Lawrence D'Oliveiro wrote:
>>> On Mon, 22 Jan 2024 09:30:21 +0100, David Brown wrote:
>>>
>>>> ... I don't use the matching names in C++ either ...
>>>
>>> I do, if/when I do use C++ and C. Don’t you think it improves readability:
>>
>> No. But I fully appreciate that this is personal preference and habit.
>
> I believe that some of the identifiers improves readability for people
> coming from a programming language which uses those English words for
> very similar operators rather than && and ||.

Well, I can only speaking for myself. But as someone originally coming
from such languages I have no problems with these operators. (== vs =
aggravated me more).

> [...]
>
> For that reason, these identifiers should not be used, except for
> machine-encoding of programs into a 6 bit character set.
>
> [...]
>
> Clearly, the purpose of this header is to allow C to be written with the
> ISO 646 character set. The choices of identifiers do not look like
> evidence of readability having been highly prioritized.

I don't quite understand your thought. The "6-bit characters" OSes
that I used had no lowercase letters, as opposed to IA5/ASCII/ISO646.

To be sure I had also re-inspected the ASCII character set and it
seems that all C characters (including these operators) are anyway
in the ASCII domain. It's beyond me why they've used the name
"iso646.h".

Janis

Janis Papanagnou

unread,
Jan 24, 2024, 3:00:17 AMJan 24
to
On 23.01.2024 22:50, Lawrence D'Oliveiro wrote:
> On Tue, 23 Jan 2024 06:47:10 +0100, Janis Papanagnou wrote:
>
>> There's also problems with these names. For example '&&' has not the
>> semantics of 'and' but of 'and_then', 'or' is actually 'or_else'.
>
> Funnily enough, that is how the languages that offer those words interpret
> them. Not just C and C++.

From the languages I know of that support them (Ada and Eiffel) these
languages support both forms.

Janis

Janis Papanagnou

unread,
Jan 24, 2024, 3:02:17 AMJan 24
to
On 23.01.2024 22:52, Lawrence D'Oliveiro wrote:
> On Tue, 23 Jan 2024 17:21:40 -0000 (UTC), Lew Pitcher wrote:
>
>> Less importantly, it also violates the convention that C macros are
>> named in upper case to distinguish them from keywords and "regular"
>> identifiers.
>
> Why does C allow lowercase in macro names, then?

It's the nature of "conventions" to take the place where there's no
rule.

Janis

Janis Papanagnou

unread,
Jan 24, 2024, 3:06:41 AMJan 24
to
On 23.01.2024 21:13, Keith Thompson wrote:
> [...] There's no hard rule that operators must be
> punctuation, just a general trend.)

Anyone still writing "MULTIPLY a BY b GIVEN c" ? :-)

(Luckily I've never programmed in COBOL, even after
it allowed "COMPUTE c = a * b" (or some such).)

Janis

Janis Papanagnou

unread,
Jan 24, 2024, 3:09:19 AMJan 24
to
On 23.01.2024 23:09, Kaz Kylheku wrote:
> [...]
> whereas in the shell:
>
> (((a && b) || c) && d)
>
> where I'm using "virtual parentheses". If you actually stick in real
> ones, they denote subshell execution in a separate process. (Bash
> allows curly braces for command grouping that doesn't create
> processes.)

Make that "POSIX allows..." (it's standard behavior for POSIX shells).

Janis

Janis Papanagnou

unread,
Jan 24, 2024, 3:11:18 AMJan 24
to
On 23.01.2024 23:37, Kalevi Kolttonen wrote:
>
> [...] I am
> pretty sure that not all computer languages
> provide guarantees about the order of evaluation.

What?!

Janis

Janis Papanagnou

unread,
Jan 24, 2024, 3:15:57 AMJan 24
to
On 24.01.2024 00:33, Lawrence D'Oliveiro wrote:
> On Tue, 23 Jan 2024 14:51:52 -0800, Keith Thompson wrote:
>
>> Lawrence D'Oliveiro <l...@nz.invalid> writes:
>>
>>> On Tue, 23 Jan 2024 17:21:40 -0000 (UTC), Lew Pitcher wrote:
>>>
>>>> Less importantly, it also violates the convention that C macros are
>>>> named in upper case to distinguish them from keywords and "regular"
>>>> identifiers.
>>>
>>> Why does C allow lowercase in macro names, then?
>>
>> Because it's a convention, not a language rule.
>
> So what would one mean by “violate”, other than “I personally don’t like
> it”?

I would interpret it in [professional] project contexts where more
than one person is programming on the same project.

Janis

Kaz Kylheku

unread,
Jan 24, 2024, 3:26:04 AMJan 24
to
You might think, but due to scoping, they can cause problems, unless
they are namespaced. If you define macro like

#define speed 42.0

anything which includes this cannot use the speed identifier
for any purpose. Not as a structure member name, enumerator, parameter
name, function name, typedef, goto label, nothing.

If we use SPEED instead, and never use such an identifier as a function,
parameter, or any of those roles I mentioned, then we have a kind of
namespace separation.

This is why simple constants are capitalized.

What we don't want to capitalize are function-like macros (those
that take parameters) which are well-behaved and blend nicely into the
language. Making them SHOUT just reduces the nice blending.

A function-like macro is not invoked if it is not followed by an open
parenthesis, which reduces the possibility of a clash.

Macros that do weird things, and/or have severe or bizarre contextual
restrictions on their use probably ought to SHOUT.

Janis Papanagnou

unread,
Jan 24, 2024, 3:28:26 AMJan 24
to
On 24.01.2024 01:45, James Kuyper wrote:
> On 1/23/24 16:28, Scott Lurndal wrote:
>>
>> The term 'conditional and' has been in common use for decades.
>
> I've never heard of it. When searching Wikipedia, [...]

In the context of Ada I read about "boolean operator" ('and')
and "boolean shortcut operator" ('and then').

In an Eiffel book (which oriented its this operator choice on Ada)
they speak about "non-commutative" operators when the mean the e.g.
'and then' sorts of operators.

In my book the other formulation(s) mentioned in the threads are
clear enough to understand them (I did, at least) and unless one
is on the argument trip we should stop that fruitless discussion.

Janis

Janis Papanagnou

unread,
Jan 24, 2024, 3:34:38 AMJan 24
to
Since you're making up your comfort situations feel free to answer them
yourself.

Janis Papanagnou

unread,
Jan 24, 2024, 3:41:46 AMJan 24
to
On 24.01.2024 00:10, Keith Thompson wrote:
>
> The header was introduced to make it easier (or possible) to write C
> code on systems/keyboards that don't support certain characters like '&'
> and '|' -- similar to digraphs and trigraphs.

I think this is the most likely explanation; the restricted _keyboards_
(and not the restricted [ASCII] character set). Matches my experiences
with old keyboards I used decades ago.

Janis

David Brown

unread,
Jan 24, 2024, 4:03:17 AMJan 24
to
On 23/01/2024 22:30, Kaz Kylheku wrote:
> On 2024-01-23, David Brown <david...@hesbynett.no> wrote:
>> On 22/01/2024 21:34, Lawrence D'Oliveiro wrote:
>>> On Mon, 22 Jan 2024 09:30:21 +0100, David Brown wrote:
>>>
>>>> ... I don't use the matching names in C++ either ...
>>>
>>> I do, if/when I do use C++ and C. Don’t you think it improves readability:
>>
>> No. But I fully appreciate that this is personal preference and habit.
>
> I believe that some of the identifiers improves readability for people
> coming from a programming language which uses those English words for
> very similar operators rather than && and ||.
>
> In a green field programming language design, it's probably better
> to design that way from the start. It's a nice bonus if a language
> looks readable to newcomers.
>

Agreed.

> Generations of C coders are used to && and || though; that's the normal
> way to write C. Using these aliases is a vanishingly rare practice. An
> important aspect of readability is writing code like everyone else. When
> a language is newly designed so that there isn't anyone else, that
> doesn't have to be considered.
>

Agreed. (Although people coming to your new language probably have
experience with some other languages, and you'll want to avoid being
confusingly different from common existing languages. Choosing "&&" and
"&" for "bitwise and" and "logical and" would be a bad idea for a new
language, even if it arguably makes more sense based on the prevalence
of these operator usages.)

> For that reason, these identifiers should not be used, except for
> machine-encoding of programs into a 6 bit character set.
>
> Additionally certain names in the iso646.h header are poorly considered,
> and obstruct readability. They use the _eq suffix for an operation that
> is assignment.
>
> #define and_eq &=
>
> If the purpose of this header were to optimize readability for those
> unfamiliar with C, this should be called
>
> #define and_set &=
>
> or similar.

Or "bitmask" ?

>
> The assignment operator = should not be read "equals", but "becomes" or
> "takes the value" or "is assigned" or "is set to". This should be taken
> into consideration when coming up with word-like token or token fragment
> to represent it.

Yes.

>
> Also note the following inconsistency:
>
> #define and &&
> #define bitand &
> #define and_eq &= // what happened to "bit"?
>
> This looks like and_eq should correspond to &&=, since and is &&,
> and bitand is &. &= wants to be bitand_eq.
>
> Clearly, the purpose of this header is to allow C to be written with the
> ISO 646 character set. The choices of identifiers do not look like
> evidence of readability having been highly prioritized.
>

They are still better than trigraphs :-)


Janis Papanagnou

unread,
Jan 24, 2024, 4:09:26 AMJan 24
to
Umm.., but that is just a normal name clash situation.

I mean I see where you're coming from but that doesn't seem convincing.
The convention then "disallows" (sort of) use of
char* TLA = "three letter acronym";
because its lexical form is "reserved" (in an artificial name-space)
for CPP entities?

I suppose we just disagree on that point (or have other preferences).

>
> If we use SPEED instead, and never use such an identifier as a function,
> parameter, or any of those roles I mentioned, then we have a kind of
> namespace separation.
>
> This is why simple constants are capitalized.
>
> What we don't want to capitalize are function-like macros (those
> that take parameters) which are well-behaved and blend nicely into the
> language. Making them SHOUT just reduces the nice blending.
>
> A function-like macro is not invoked if it is not followed by an open
> parenthesis, which reduces the possibility of a clash.
>
> Macros that do weird things, and/or have severe or bizarre contextual
> restrictions on their use probably ought to SHOUT.

I'm familiar a design philosophy where it's even unnecessary to write
parenthesis in function calls in case there's no arguments, so I know
what you're aiming at. Only the fact that the CPP is just a poor tool
that does simple replacements may lead to issues, say, FUN(a) a+a
and a call with FUN(b++) . Notwithstanding that we could discuss the
responsibility of the macro designer, such behavior at least may be a
reason to clearly indicate that caution is necessary here.

I think we agree here.

Janis

David Brown

unread,
Jan 24, 2024, 4:13:16 AMJan 24
to
A better choice would be:

static const double speed = 42.0;

That has none of the scoping or identifier issues that you mention.

Alternatively, if I had to use #define for some reason, I'd prefer:

#define maximum_speed 42.0

or some other appropriate name that would not clash with other
identifiers (in that translation unit) because it has a unique name that
will not be re-used. I find that far neater than using all-caps to make
an alternative namespace.

>
> What we don't want to capitalize are function-like macros (those
> that take parameters) which are well-behaved and blend nicely into the
> language. Making them SHOUT just reduces the nice blending.
>
> A function-like macro is not invoked if it is not followed by an open
> parenthesis, which reduces the possibility of a clash.
>
> Macros that do weird things, and/or have severe or bizarre contextual
> restrictions on their use probably ought to SHOUT.
>

Agreed.

I need good reasons to SHOUT an identifier - it needs to be something
that can easily have unexpected effects.


David Brown

unread,
Jan 24, 2024, 6:38:03 AMJan 24
to
On 24/01/2024 01:06, bart wrote:
> On 23/01/2024 22:47, Kalevi Kolttonen wrote:
>> Lawrence D'Oliveiro <l...@nz.invalid> wrote:
>>> On Tue, 23 Jan 2024 19:32:26 -0000 (UTC), Kalevi Kolttonen wrote:
>>>
>>>> Dennis Ritchie has said that he regretted the spelling of creat(2)
>>>> function. Presumably the abbreviation was supposed to save one byte of
>>>> storage.
>>>
>>> Given that, in POSIX, all the functions of creat(2) have been subsumed
>>> under open(2) anyway, we can largely ignore that.
>>
>> I know. creat() is now completely redundant because
>> open() suffices. The reason I brought it up was just
>> so that people would realize that at least sometimes
>> it was a matter of saving storage space - even one
>> byte.
>>
>>> There are other worse problems with C. Like its use of “=” (the
>>> mathematical equality operator) for assignment, instead of using the
>>> “:=”
>>> symbol that the Algols had adopted.
>>
>> Well I started with Microsoft BASIC on Commodore 64 39 years ago.
>> So I am well used to "=" and do not consider it a problem.
>
> I've used ":=" with Algol and "=" with Fortran (a bit longer ago).
>
> That is not itself the problem.
>
> The problem is allowing both assignment and equality within the same
> expression, which is what C does. Algol, Fortran and BASIC didn't do that.
>
> If that wasn't the case, then you could use "=" for both assignment, and
> equality, without ambiguity.
>
> Languages that use ":=" and "=" for those operations, fare better than C
> that uses "=" and "==".
>
>>>> But the Python designers botched at least one thing concerning that
>>>> philosophy: private functions are not defined by "private" keyword like
>>>> in Java but instead the designers violated their own basic principle of
>>>> easy readability: the "privateness" is defined by by prefixing the
>>>> function names with an underscore ("_").
>>>
>>> That is merely a convention, a hint that the user might want to stay
>>> away
>>> from such a symbol, not a hard requirement, which is why it was designed
>>> that way. As Guido van Rossum has said: “We are all consenting adults
>>> here”.
>>
>> What?! Are you saying that there is no way to label functions as private
>> in Python? That sounds absolutely horrible. Why would anyone design a
>> language with object-oriented features without support for encapsulation?
>
> Python is 'ultra-dynamic'. That's why it's so hard to make it
> performant. So you can do this:
>
>     import math
>
>     math.pi = "pie"
>     math.sqrt = lambda x:x*x
>
>     print(math.pi*2)
>     print(math.sqrt(10))
>
> Output is:
>
>     piepie
>     100
>

Nothing beats Forth:

: 1 2 ; ok
1 1 + . 4 ok

Redefining "1" to mean "2" is a great way to obfuscate your code :-)


Malcolm McLean

unread,
Jan 24, 2024, 6:53:43 AMJan 24
to
On 24/01/2024 00:16, Keith Thompson wrote:
> Lawrence D'Oliveiro <l...@nz.invalid> writes:
>> On Tue, 23 Jan 2024 14:51:52 -0800, Keith Thompson wrote:
>>> Lawrence D'Oliveiro <l...@nz.invalid> writes:
>>>> On Tue, 23 Jan 2024 17:21:40 -0000 (UTC), Lew Pitcher wrote:
>>>>> Less importantly, it also violates the convention that C macros are
>>>>> named in upper case to distinguish them from keywords and "regular"
>>>>> identifiers.
>>>>
>>>> Why does C allow lowercase in macro names, then?
>>>
>>> Because it's a convention, not a language rule.
>>
>> So what would one mean by “violate”, other than “I personally don’t like
>> it”?
>
> Obviously, it would mean not following the convention.
>
> There clearly is a convention that most macro names should be defined in
> all caps. Equally clearly, the standard library does not uniformly
> follow that convention. I have no problem with that.
>
> I might have some more thoughts on the matter, but I'm not sure where
> you're going with this.
>
I always write clamp() and lerp() in any numerical C code that goes
beyond a certain complexity. They are function-like macros, and should
look like functions. Of course you can pass parameters with side
effects, but unlikely in practice.
--
Check out Basic Algorithms and my other books:
https://www.lulu.com/spotlight/bgy1mm

Malcolm McLean

unread,
Jan 24, 2024, 7:20:57 AMJan 24
to
On 23/01/2024 18:34, bart wrote:
> On 23/01/2024 16:32, Malcolm McLean wrote:
>> On 22/01/2024 20:34, Lawrence D'Oliveiro wrote:
>>> On Mon, 22 Jan 2024 09:30:21 +0100, David Brown wrote:
>>>
>>>> ... I don't use the matching names in C++ either ...
>>>
>>> I do, if/when I do use C++ and C. Don’t you think it improves
>>> readability:
>>>
>> It breaks the rule that, in C, variables and functions are
>> alphnumeric, whilst operators are symbols. sizeof is an exception, but
>> a justified one. However it's harder to justify a symbol for "plus"
>> but a word for "or".
>
> But it's OK to justify 'pow' for exponentiation?
>
Mathematically operators are functions, so a mathematican would say that
"add" is just as much of a function as "gamma". But to a computer
programmer an operator compiles to a trivial number of machine code
instructions, whilst a function is a subroutine call. Pow is not usually
supported in hardware. However it's such a basic mathematical function
that it has special notation. So some languages say it should be an
operator. However ASCII won't represent the standard notation. SO there
are good arguments for and against pow as an operators, and different
language take differnet views. But I think the C decision is better, as
C code is for programming computers, not for translating formulae into
machine readable form.

bart

unread,
Jan 24, 2024, 8:00:32 AMJan 24
to
On 24/01/2024 12:20, Malcolm McLean wrote:
> On 23/01/2024 18:34, bart wrote:
>> On 23/01/2024 16:32, Malcolm McLean wrote:
>>> On 22/01/2024 20:34, Lawrence D'Oliveiro wrote:
>>>> On Mon, 22 Jan 2024 09:30:21 +0100, David Brown wrote:
>>>>
>>>>> ... I don't use the matching names in C++ either ...
>>>>
>>>> I do, if/when I do use C++ and C. Don’t you think it improves
>>>> readability:
>>>>
>>> It breaks the rule that, in C, variables and functions are
>>> alphnumeric, whilst operators are symbols. sizeof is an exception,
>>> but a justified one. However it's harder to justify a symbol for
>>> "plus" but a word for "or".
>>
>> But it's OK to justify 'pow' for exponentiation?
>>
> Mathematically operators are functions, so a mathematican would say that
> "add" is just as much of a function as "gamma". But to a computer
> programmer an operator compiles to a trivial number of machine code
> instructions, whilst a function is a subroutine call. Pow is not usually
> supported in hardware. However it's such a basic mathematical function
> that it has special notation. So some languages say it should be an
> operator. However ASCII won't represent the standard notation.

Which is what? Usually the operator is implied when using mathematical
notation, as is multiply.

Computer languages commonly use '**' or '^' for this operator.

SO there
> are good arguments for and against pow as an operators, and different
> language take differnet views. But I think the C decision is better, as
> C code is for programming computers, not for translating formulae into
> machine readable form.

C's decision is possibly the worst. A proper built-in operator, say
'**', can be overloaded to work on both ints and floats.

If you do 'pow(a,3)' in C when 'a' is an integer, then it will convert
to a float, call the external function, and return a float result, which
is likely to force neighbouring terms and operators to work as floats too.

Using 'a**3', that would probably be a call to an integer power
function, but here it can also easily choose to do a*a*a.


It is loading more messages.
0 new messages