6 ms·
It’s mostly semantically very poor to be honest. C really is a nicer assembly in a lot of way. It’s extremely limited. You have branching logic, functions call,
by WastingMyTime89 4y ago
It’s mostly semantically very poor to be honest. C really is a nicer assembly in a lot of way. It’s extremely limited. You have branching logic, functions call, pointer arithmetic, a way to define data structures which are really memory layouts and that’s pretty much it. I guess you can appreciate that as an aesthetic statement but what you wrote would apply equally to any language with more complex semantics.
- sn41 4y ago> that’s pretty much it. Only if you ignore 1. variadic arguments as in printf, 2. function pointers which are a very elementary (type-unsafe) form of closures, 3. a nice way of casting to void 4. setjmp and longjmp goodies (?) which allow you to code up co-routine libraries and exception handling mechanisms I'm sure there are more such facets I am missing. The elegance of the specification may be questionable, but the scope of what C tried to achieve is breathtaking. It actually is superior to most of its improvements.
- WastingMyTime89 4y agoThere is no elegance there. Casting to void is not a plus. That’s just C having no proper type system. Function pointers as an elementary form of closures, come on, what’s next? Closures are defined by capture. It’s nearly as fun as pretending C as coroutines because of setjmp. How can a statement like C being semantically poor even be seen as controversial? For god sake, we are talking about a language which semantically doesn’t even have proper arrays. > The elegance of the specification may be questionable, but the scope of what C tried to achieve is breathtaking. It actually is superior to most of its improvements. Seriously? It wasn’t even a good language when it was released. Lisp and Pascal were far better. It won because of compiler availability and adequate performance on limited platforms. HN really is a joke sometimes.
- youarethejoke 4y agoYou really don't understand, but that's okay. C is a wonderful language, and that's the end of it really. You just try to think C as a language that SHOULD HAVE all the stupid bells and whistles you find convenient. Many of us more advanced coders have found that those stupid bells and whistles are, in fact, inconvenient. Casting to void is a powerful technique and the limits are literally endless. C is semantically rich, way beyond your dull imagination.
- WastingMyTime89 4y agoThe argument is not about what can and can’t be done in C. C is Turing complete and low level. You can do anything in C. The debate is not even about if it’s good idea (I don’t think it is but that’s separate). The question is about C semantics. Given the reply I get it’s pretty obvious that some here don’t understand what language semantics are. It’s about the amount of concepts you can express in the language. Haskell - a language I personally despise - is semantically very rich. So is modern C++ for what it’s worth. C simply isn’t. It’s even deceiving sometimes because it has the apparence of having some semantic elements (arrays for exemple) which are not there in reality and are really only syntactic sugar on top of other semantic constructions(pointers).
- eska 4y agoYou’re whitewashing history if you think Pascal was superior to C. There was no conspiracy among compiler developers as you imply. Also you complain about semantic richness of C, but then only point to semantically rich languages you despise. A curious reader would wonder: why care about semantically rich languages then? An observant reader would wonder: so aren’t there times where semantic richness is not useful?
- WastingMyTime89 4y agoWhat conspiracies are you talking about? C won because its compiler was widely available for free. That’s pretty much a fact. Pascal was indeed a superior language but limited by the proliferation of extensions, paid compilers and its compiler performance. I’m not even complaining about the semantic richness of C. I’m just stating the fact that it doesn’t really have semantic richness. Then again don’t get me wrong. I do think C is a terrible language and I say that having worked on a C static analyser. It’s full of avoidable undefined behaviours and silly sharp edges. Thankfully, nice languages with rich semantic exist. I was just pointing some I don’t like to separate the issue of semantic richness from likability. I enjoyed working in Ada a lot. Ocaml is awesome. I have never used Rust but from what I have seen that seems nice. Semantic richness is useful because it helps programmers express what they want to do in way which are clearer and therefore more likely to be correct.
- WalterBright 4y agoMuch of what you say is true. But I came to C from Pascal. Pascal circa 1982 was unusable without all the numerous extensions each vendor tacked on. C worked out of the box. I could get things done in C without constantly fighting the Pascal and Fortran compilers of the day. This was true despite the terrible C compilers of that time.
- pjmlp 4y agoI remeber that Small-C and RatC were hardly usefull without tons of inline Assembly. As proven by books like "A book on C" from 1984 (Robert Edward Berry and B. A. E. Meekings).
- timbit42 4y agoPascal wasn't ready for real-world use because it came from an academic setting and was initially designed to run P-code in a VM. It's successor, Modula-2, fixed all of Pascal's issues and added a lot of great functionality.
- asveikau 4y ago> HN really is a joke sometimes. A lot of what I'm seeing from your comments here is you can't handle people who have something positive to say about C. They're not saying it's the one true way or something. Just that they like it in some respect. And your attempts to dismiss that and call "HN" a joke for harboring someone who thinks this way look kind of childish to me.
- WastingMyTime89 4y agoThen you are seeing what you want to see. People are straightforwardly arguing that C is semantically rich which is indeed laughable. I have addressed the point under but clearly a lot of you don’t understand what language semantics are. Considering I was having interesting discussion about the subtleties of the Hindley-Milner type system on this same website a decade ago, yes, I do think HN is becoming a joke. The joke is on me however because apparently I keep commenting for reasons which are not always apparent to me I must confess.
- asveikau 4y agoThere are plenty of interesting C works out there, as well as data structures or algorithms that C can express elegantly. Small example, linked lists. I don't think non-C linked list code tends to be as straightforward as I've seen in C. Or the character-at-a-time style of string processing. It's kind of unique to C. You can say there is stuff about that you don't like. That's fine. Linked lists suck with modern CPU caches anyway. C strings have lots of misadventures in terms of buffer overflows. But it's unique and interesting. Lots of elegant things have been written this way. Your unfamiliarity with it doesn't make it "a joke" to point this out. I have my own gripes with HN. Try mentioning politics and it brings out all sorts of fascist-sympathizing crazies. But saying good to neutral things about C (while not even universally praising it) is not one of those issues.
- Koshkin 4y ago> as straightforward as I've seen in C To be fair, the most straightforward definition of the linked list is generic, and C completely lacks such facility. > fascist- Sounds familiar. https://news.ycombinator.com/item?id=33478321 https://news.ycombinator.com/item?id=33478321
- enedil 4y agoClosure is not an anonymous function. It "encloses" variables that were in scope at the point of closure creation. Therefore function pointers cannot serve that purpose as is.
- sn41 4y agoI agree, I should have used anonymous function specifically instead of a closure (for example, Ruby/Smalltalk closures are blocks, not functions.) Thanks for the correction.
- Someone 4y agoC is also relatively poor at providing “a way to define data structures which are really memory layouts”. Integer sizes (historically) and padding are implementation-defined, AFAIK bit fields are underspecified in that you cannot specify in what bits of a byte they end up.
- thesuperbigfrog 4y agoSo true. I wish that C had a more rich way to define struct layouts and low-level representations for integral types. I really like how Ada does it: https://en.wikibooks.org/wiki/Ada_Programming/Representation_clauses https://en.wikibooks.org/wiki/Ada_Programming/Representation... If you need to read or write specialized hardware registers, being able to define a data structure with a custom representation is very nice and can save significant time and effort.
- timbit42 4y agoI wish C had never been born.
- deleted 4y ago[deleted]
- titzer 4y agoC would be a better language if it really lived up to its old ideal of being a "portable assembly language". That stopped being true as compilers started optimizing undefined behavior (e.g. signed overflow). Instead of a "+" in the source code yielding an honest-to-goodness hardware add instruction, it could be "optimized"--i.e. constant folded, CSE'd, strength-reduced, value-range-analyzed, among others--by an optimizing compiler in ways that completely ignore what the hardware instruction actually does upon overflow. That meant the C language became more like a vague suggestion of assembly and it became pretty much impossible to code to the machine anymore.
- menaerus 4y agoIn the absence of CPU instruction which does the saturated ADD, how do you solve the overflow problem in a bare-metal language without introducing the performance hit?
- zozbot234 4y agoThe performance hit of overflow has nothing to do with lacking assembly instructions. It's all about having to preserve error states whenever overflow occurs and inhibiting optimization.
- menaerus 4y agoI don't follow. If we had the saturated ADD instruction supported in hardware we wouldn't have to deal with saturation logic in software. Compiler would simply be able to emit SADD instruction whenever we asked for it to and would be given a chance to spit out more optimized code because that would essentially be a branchless code. Reality though is that we don't have such hardware and we have to deal with it in software, so, instead of a single instruction emitted there will be a bunch of them, and of which there will be certainly branches involved.
- titzer 4y agoIt depends on how you define your language semantics. If you choose 2's complement wraparound semantics, which is what nearly all CPUs in the world have standardized on, there is nothing for the compiler to do. It's a pure operation, a single instruction, and can be constant-folded, strength-reduced, CSE'd, moved, dead-code-eliminated, etc. If you want a different semantics at the source level, e.g. overflow is an exception, then the compiler needs to emit additional code. For Virgil I chose to settle on 2's complement because it's what hardware gives and has no overhead. It comes with the full compliment of fixed-width integers of widths 1-64 and odd-width ones come with zero-extension or sign-extension as necessary to make the underlying hardware width unobservable.