On 2025-04-12, bart <
bc@freeuk.com> wrote:
On 12/04/2025 14:43, David Brown wrote:
On 12/04/2025 03:27, bart wrote:
>
C type syntax is famous for being difficult and confusing; I think
most will agree about that. Even the creators said so.
I disagree with that claim. I think it is probably fair to say that
advanced, complicated and multi-layer types are difficult in any
programming language.
>
But a type that is a simple linear chain should be straightforward, and
usually is, just not in C. That was illustrated here:
>
array of 10 pointer to function taking int and returning int
1 2 3 4 5 6
You make a good point in that since the type constructing operators are
unary (prefix or postfix), the derivation chain is linear and could be
linearized, without the need for any precedence parentheses.
It follows the use, though.
The function and array derivations are postfix. Only the pointer
derivation is prefix.
If we imagine a C with postfix pointer dereferencing, say using ^
(setting aside the xor meaning for a moment), like:
a[i]^(arg); // index into a at i, dereference, call with arg.
Then the declarator would be similar under declaration-follows-use:
int a[10]^(int); // same as int (*a[10])(int);
the name would always be on the left, just after the declaration
specifiers, and all the derivation would be postfix.
Then, suppose if you didn't want an array of pointers, but
a pointer to an array, you would not add, remove or rearrange
precedence parentheses. You would just reorder the postfixes.
int a^[10](int) // same as int (*a)[10](int);
// Note: invalid! For syntactic discussion only!
This is a type not supported in C: array of functions. I'm just using
it for syntax comparisons to illustrate that if all the type derviations
are postfix, then precedence parentheses serve no purpose and we don't
entertain them.
You do have a point, but the fact that C declarations follow C
expressions (even with the way suboptimal dereferencing is on the left)
is a good thing. The consistency makes it easy to learn declarations,
and also to visually check code for sanity: do declarations match uses.
"Declaration follows use" might be even better with a nicer
expression grammar in the area of arrays and pointers, but we don't
have that.
This (*a[10])(int) clump may seem difficult, but a C programmer cannot
get around learning that same shape in the context of expressions,
where it could occur like this (*a[i])(x + 1). If you grok this,
you're most of the way toward grokking the declarator.
There are some subtleties like expressions giving you various shortcuts.
Arrays can be used as if they were pointers and vice-versa, and
function pointers can be called without explicit dereferencing.
I believe those additional rules in expressions that are not found
in type derivation cause some C programmers to have difficulties
with nested declarations. It's precisely because they cause deviations
from "declaration follow use". The use of a function pointer is rarely
observed as (*ptr)(arg) because ptr(arg) works, but the declarator
must still be (*ptr)(paramtype) as if ptr(arg) didn't exist.
If there were no deviations in "declaration follows use", such that
calling a function pointer taken from an array had to be written
(*a[i])(arg), then new C programmers would struggle less with
declarations. Or should we say, struggle less with declarations of
entities that they already know how to use.
I have said multiple times that if I were to design a new programming
language, its syntax would differ significantly from C's.
>
But it would be a toy unless you could get it adopted by lots of people.
>
By your standards, even a DSL that you create for use in your
professional work would be a toy.
If the DSL reinvents a lot of risky wheels, like doing everything
from scratch, that could be the case. It takes some years to mature
something out of non-toy status at that level.
A DSL that just transliterates some notation to a stable, mature
language, according to a small body of rules, easily inherits
the non-toy status from the platform it sits on.
"Toy" is a not a well-defined concept, which mainly seems function
as "not suitable for some unspecified purposes that I have in mind".
People who use "toy" tend to move their secret goalposts.
There are ways that a DSL could be unsuitable for some of the purposes
it is supposedly designed for, even if it sits on a stable platform;
then some people trying that DSL in earnest might abandon it
and call it a toy.
-- TXR Programming Language: http://nongnu.org/txrCygnal: Cygwin Native Application Library: http://kylheku.com/cygnalMastodon: @Kazinator@mstdn.ca