6 ms·
Not exactly, read the exact paragraph in The Development of the C Language: > [...] In all these cases the declaration of a variable resembles its usage in an
by lifthrasiir 2y ago
Not exactly, read the exact paragraph in The Development of the C Language:
> [...] In all these cases the declaration of a variable resembles its usage in an expression whose type is the one named at the head of the declaration.
> The scheme of type composition adopted by C owes considerable debt to Algol 68, although it did not, perhaps, emerge in a form that Algol's adherents would approve of. The central notion I captured from Algol was a type structure based on atomic types (including structures), composed into arrays, pointers (references), and functions (procedures). Algol 68's concept of unions and casts also had an influence that appeared later.
Algol 68 by the way had a sensible type syntax that is akin to Go's. Ritchie "explains" the syntax difference by having the same syntax for the type and the expression, but that's not exactly why. For example there are actually two expressions relevant here, `*` dereference and `&` reference. Why was the former used? Why couldn't `*` be made a postfix at this point if the same syntax was a big concern? Ritchie himself never fully elaborated on those points, and I think that's because it was never his primary concern at all.
As you have noted, it is very important to realize that C did have their design goals (for which C did a very excellent job). On the other hand it would be very misleading to claim that C had some bigger visions even at that time and they validate its design! Ritchie and others were clearly smart but they didn't design C to be something magnificant, it was a rough product from various trade-offs they had to endure. So why this particular syntax? Well, because B already picked a prefix `*` which Ritchie didn't want to change at all, and he allowed it to infect all other aspects of the type syntax without much consideration. (Or more neutrally, Ritchie couldn't figure out any other option when he had to keep the B compatibility. But keep in mind that B have already changed that operator from BCPL.)
Technically speaking it was somehow designed, but only by following the path of the least resistance, not a solid reasoning, hence my use of the word "accidental". There are many other examples, such as the logical `&` (etc.) being renamed to `&&` but the bitwise `&` keeping the original precedence order because nothing was done. To be fair to Ritchie though, it is not his fault, but rather a fault of the whole software community that was fixated on this ancient language designed for specific purposes way too long.
- rramadass 2y agoThe relevant paragraphs from Ritchie's paper are not just what you quoted (much of your comment is not relevant) but much more; For each object of such a composed type, there was already a way to mention the underlying object: index the array, call the function, use the indirection operator on the pointer. Analogical reasoning led to a declaration syntax for names mirroring that of the expression syntax in which the names typically appear. Thus, int i, *pi, **ppi; declare an integer, a pointer to an integer, a pointer to a pointer to an integer. The syntax of these declarations reflects the observation that i, pi, and ppi all yield an int type when used in an expression. Similarly, int f(), *f(), (*f)(); declare a function returning an integer, a function returning a pointer to an integer, a pointer to a function returning an integer; int *api[10], (*pai)[10]; declare an array of pointers to integers, and a pointer to an array of integers. In all these cases the declaration of a variable resembles its usage in an expression whose type is the one named at the head of the declaration. The above can be summarized as the following two points; 1) "Declaration reflects Use" (from K&R C book) which leads us to the corollary, 2) Syntax is variable-centric rather than type-centric i.e. You look at how the variable is supposed to be used and then work out its type. > To be fair to Ritchie though, it is not his fault, but rather a fault of the whole software community that was fixated on this ancient language designed for specific purposes way too long. Again, this is completely baseless and merely your opinion. I have already pointed out the main design goals which drove its design and the fact that it is still relevant today is proof of that. The "simplicity" of its very design is its greatest strength. The fact that modern needs (eg. Strong Type Safety, Multi-paradigm, Security, Concurrency etc.) require us to design/seek out more language features is not a reflection on the language itself since it was designed well before these "wants" became "needs". On the other hand the various extensions of C (eg. Objective-C, Concurrent-C, Handel-C etc.) are proof of its versatility and extensibility and hence its enduring relevance.
- lifthrasiir 2y agoNot only you swiftly dismissed most of my comment without even trying, but you have no backing evidence for why declaration has to reflect use (K&R has no rationale for that AFAIK). And even that principle doesn't imply your claim; it only means that syntax changes to the declaration and uses have to be synchronized. > On the other hand the various extensions of C (eg. Objective-C, Concurrent-C, Handel-C etc.) are proof of its versatility and extensibility and hence its enduring relevance. Most popular enough languages will eventually have tons of extensions, most of which would be obscure and not known to the general public though. I'm not even sure which "concurrent" C you are talking about (there had been multiple extensions of the same name in the literature, none of them ever gained traction in the industry). Have you ever actually seen or used suggested extensions firsthand? Also extending a language is actually kinda easy and doesn't imply some kind of quality. You seem to value your own decade-long experience, but I had been also a programming language researcher decades ago and I know that because any PL researcher will make new languages all the time. Or let's put in this way: Brainfuck has been extended and adapted so many times [1]. Does that make Brainfuck "versatile and extensible" in your definition? Is the enduring relevance even a necessary consequence of such qualities? Think about that. [1] https://esolangs.org/wiki/Brainfuck#Related_languages https://esolangs.org/wiki/Brainfuck#Related_languages