Things that Dennis Ritchie got wrong.



  • @dkf said:

    Check out Lisp or m4 sometime.

    (attest "I'm somewhat familiar with both but as far as I'm aware neither one is a "language feature."")dnl



  • @superjer said:

    as devastatingly powerful as C macros

    Do you mean that they have the power to devastate a codebase? C++ templates are, in my opinion, vastly more useful and powerful. The syntax leaves a lot to be desired, but thankfully the newer standards have gone to some lengths to improve the situation.



  • C++ templates would be the best thing ever if they didn't require C++.


  • Garbage Person

    Point of order: Wingwoman, not SO. She's not into dudes.



  • @Weng said:

    Point of order: Wingwoman, not SO. She's not into dudes.

    Oh, so IO.



  • @Kian said:

    Do you mean that they have the power to devastate a codebase? C++ templates are, in my opinion, vastly more useful and powerful.

    The way I use macros is not something templates were designed for. So to me they seem a lot less powerful. I don't think templates are as devastating either as long as they are used for their intended purpose (generics). But don't get me started on generic low level coding...

    @Kian said:

    The syntax leaves a lot to be desired, but thankfully the newer standards have gone to some lengths to improve the situation.

    But it's not C++ if it isn't ugly as sin!


  • Garbage Person

    Yes. In fact, if there were a Facebook relationship status for that...



  • @Weng said:

    Yes. In fact, if there were a Facebook relationship status for that...

    That sounds complicated.



  • This post is deleted!


  • @dkf said:

    C macros; a big mistake of Dennis's

    DMR seems to be laying the blame on others: specifically Alan Snyder, Mike Lesk and John Reiser.



  • @Kian said:

    thankfully the newer standards have gone to some lengths to improve the situation.

    I was actually disappointed that the C++11 standard didn't introduce any new meanings for static...



  • Would you prefer everything looking like LISP instead?

    Yes. Or, better yet, Haskell.


  • Discourse touched me in a no-no place

    @superjer said:

    The way I use macros is not something templates were designed for. So to me they seem a lot less powerful. I don't think templates are as devastating either as long as they are used for their intended purpose (generics). But don't get me started on generic low level coding...

    The good thing about macros in C and C++ is that you can use them to create new control structures, albeit crudely. This horrifies many lesser users of those two languages because it takes them a bit outside their comfort zone. However, this is only a shadow of what you can do with a truly advanced macro system, which mixes in the capabilities of C++ templates and inline functions as well. (Lisp's macro system is regarded as being pretty much the limit here; that language is far better at mixing compile-time and run-time execution than C++ is.)

    Lisp has a lot of good stuff in it. It's just a shame that its practitioners got the “syntax is insignificant” bug, when that's obviously not true among most programmers. (They also had problems for a long time with getting good implementations out there that weren't very expensive or associated with other sorts of strangeness.) It's therefore productive to visit from time to time in order to riffle through Lisp's pockets in search of neat stuff to filch.


  • Banned

    If someone says C macros are powerful, they must have never seen macros in other languages. Take Rust for example. It's not just simple find and replace. It offers semantical checks of argument type (though it's different set of types than the types of variables; you can mark argument to be identifier, expression, code block, type name, or match pattern). It's also far more flexible in how you can define usage syntax. For example, since in Rust you can't have mutable globals (and as a consequence, non-trivial constructors for them), someone made lazy_static! macro that works akin to C++'s placement new. The invocation syntax is like lazy_static! { pub static ref global: i32 = 5; }. It can be called only if arguments are written like that, with pub being optional, and variable name, type and initializing expression varying. The words static and ref aren't actually necessary, but they look nice. Note the braces in where you would expect parens in a macro (it doesn't really matter; Rust allows for both, and it's up to programmer to choose). Try having something like that with C macros.

    Another feature is having variable number of arguments. Except thanks to flexible definition of invocation syntax, you don't have to have them at the end; you can put them somewhere in the middle, or you can have multiple lists of unspecified amount of arguments; you can even nest one expansion of varargs in another. You can also have multiple macros with the same name that only differ in invocation syntax (actually, a single macro with multiple invocations and multiple matching transcriptions). This allows for recursive macros. Try that with C.

    Note: Rust is still in prealpha stage and many features suck, including these macros (I asked on IRC once why I need to explicitly enable them in my every project, and they said it will be like that until someone comes up with an idea how to make them better).





  • Can I pass an operator to a Rust macro? E.g. transmogrify( x, y, z, <= )


  • Banned

    @superjer said:

    Can I pass an operator to a Rust macro? E.g. transmogrify( x, y, z, <= )

    That's probably why macros aren't considered good enough to be stable. Or you might write macro with separate invocation for each operator (there are no custom operators in Rust). I think it would be possible to write macro generating a macro for each operator.


  • Discourse touched me in a no-no place

    @Gaska said:

    (there are no custom operators in Rust)

    Shame. Other languages support them. I know SML does, and Haskell might well too as that's a language that's very aware of what SML did before it (and is from the same sort of community).



  • @dcon said:

    if I ever review a line like that, it will be rejected with extreme prejudice

    ++++++++++a would reject again


  • Banned

    Note that Rust is still in development, and it's open for suggestions. If you care, you can write on their Discourse-powered forum you won't find a link to on their main page, briefly describe what you think it should look like, how it will affect existing language constructs, and with bit of support it might be pushed through.



  • @Gaska said:

    Rust is still in prealpha stage and many features suck

    I'd like to see Rust mature and start to gain some traction. So far, it's the only language I've seen which could be a credible replacement for C++'s niche (native code, generic programming, C-like syntax, has macros). At the moment, it's probably too early in development to do anything real with it.

    @dkf said:

    I know SML does [operators], and Haskell

    SML is fun, but I only ever played with it (and Haskell even less than that). Does it let you create your own new operators? How do you define the precedence of your new operators? That sounds like it could cause all kinds of interesting problems...


  • Discourse touched me in a no-no place

    @tar said:

    SML is fun, but I only ever played with it (and Haskell even less than that). Does it let you create your own new operators? How do you define the precedence of your new operators? That sounds like it could cause all kinds of interesting problems...

    You do it like this (for the new left-associative operator -:-):

    infix -:- 3;
    

    The 3 (which is optional) is the precedence level. (It shares that with the reference assignment and function concatenation operators.) Right-associative operators use infixr instead of infix. You've also got to supply the definition of what it does, of course. With that done, you've really got your own operator. This was a critical feature of how SML works; the language was designed to host little languages within it (particularly for writing theorem provers) and supporting custom operators is how they tame the syntax problems.

    What SML doesn't do (or didn't back when I used it heavily) is let you overload different type signatures onto an operator; that's only allowed for certain system operators (like + and *, which are overloaded between int and real) and the overload capability is locked out of reach of user code. This means that when you look at some code, you can immediately either know that it's standard code or that you've got to look up how the code defines some symbols (just like with normal user-defined functions).

    I don't actually know if Haskell does the same things, but as I said, it comes from the same sort of community as SML so it would be surprising if they missed that out.


  • BINNED

    @dkf said:

    I don't actually know if Haskell does the same things, but as I said, it comes from the same sort of community as SML so it would be surprising if they missed that out.

    Haskell operators work basically the same way, except that the numeric operators are generally defined to take type classes as parameters. That way you don't need one set of operators for ints and another for floats (I'm looking at you, ocaml).

    (+) :: Num a => a -> a -> a
    

    So + will work with two parameters of any type that is a member of the Num class, as long as the two are of the same type.


  • Discourse touched me in a no-no place

    @antiquarian said:

    That way you don't need one set of operators for ints and another for floats (I'm looking at you, ocaml).

    SML went the other way, building in an overload mechanism. It's just that they disable it after reading in the language implementation, so user code can't define its own overloads. (I poked my fingers in very deep into how things work in this area long ago, trying to make things build on Linux back when the library loading scheme was the outright demented “ld.so”.)



  • @dkf said:

    The 3 (which is optional) is the precedence level. (It shares that with the reference assignment and function concatenation operators.) Right-associative operators use infixr instead of infix.

    Is the [SML] precedence level specified as an int, or a float? A float would seem more flexible, if I wanted to squeeze in my new operator at 3.5, midway between 3 and 4...


  • ♿ (Parody)

    @chubertdev said:

    I have no idea how women do that, I'd break it in 5 minutes.

    They usually wear their pants a lot higher than men. Urkel excepted, of course.


  • FoxDev

    @boomzilla said:

    Urkel excepted, of course.

    I am still amazed that he (supposedly) actually has a crotch given how high he wore his pants


  • FoxDev

    @accalia said:

    I am still amazed that he (supposedly) actually has a crotch given how high he wore his pants

    Maybe wearing them so high was what allowed him to voice three young hedgehogs (one of them female) later on?


  • Discourse touched me in a no-no place

    @tar said:

    Is the [SML] precedence level specified as an int, or a float? A float would seem more flexible, if I wanted to squeeze in my new operator at 3.5, midway between 3 and 4...

    int, not real. I didn't design the system. (I think not all levels are populated by default, but I can't remember for sure and I'm not going to bother installing it just to find out.)



  • @blakeyrat said:

    newsgroups and all of those pre-Internet sources.

    Just how were your newsgroups distributed, if not the Internet?

    Filed under: The Internet existed prior to the Web.



  • @HardwareGeek said:

    Just how were your newsgroups distributed, if not the Internet?

    They used the PDN, the Pedantic Dickweeed Network.



  • @HardwareGeek said:

    Just how were your newsgroups distributed, if not the Internet?

    Filed under: The Internet existed prior to the Web.

    QFPFP


  • I survived the hour long Uno hand

    @chubertdev said:

    QFPFP (Quoted for pedantry fail permanency fail)

    I'm pretty sure your acronym is missing an F somewhere there.


  • Discourse touched me in a no-no place

    @HardwareGeek said:

    Just how were your newsgroups distributed, if not the Internet?

    Newsgroups were originally distributed via UUCP.



  • @dkf said:

    Newsgroups were originally distributed via UUCP.

    Yes, but it eventually moved over to NNTP.



  • @izzion said:

    I'm pretty sure your acronym is missing an F somewhere there.

    I'm going to plead the fifth on this one.



  • My gripes not yet mentioned :


    Whitespace being near meaningless :

    Indentation is ignored.
    Too bad if it mismatches imbrication.
    Too bad we have to put both {} AND indentation.
    I would have much preferred "indentation is imbrication".

    Newline is ignored.
    Too bad we have to type both ; AND return.
    I would have much preferred "return is end-of-statement", except with a "break line" symbol.


    The wonky ordering of type piling.

    Things like char const *(*foo())[] that nobody sane can read and you have to break into a chain of typedefs.

    If I remember well, DR himself said it was broken design and a plain linear order would have been better.


    Basic types too abstract.

    By trying too hard to be machine-agnostic, and providing only a few one-size-fits-all types, C has deprived us of ways to master :

    • Data alignment
    • Member ordering
    • Bit endianness
    • Data representation
    • Compiler optimization

    Pretty bad shortcomings for such a "bare metal" language.


  • Discourse touched me in a no-no place

    @Musaran said:

    Whitespace being near meaningless :

    This is one where people will argue about it for ages. I quite like having to use braces, as it makes sending code to other people via media like email and IRC much easier.
    @Musaran said:
    The wonky ordering of type piling.

    Fair.
    @Musaran said:
    Basic types too abstract.

    That depends on what you're doing. Trying to do the things that you're talking about would make C an immensely more awkward general programming language.

    Most of the things you mentioned have been fixed by either later standards or by ABI specifications. The rest are really very niche indeed…


  • BINNED

    @Musaran said:

    Whitespace being near meaningless :

    Indentation is ignored.Too bad if it mismatches imbrication.Too bad we have to put both {} AND indentation.I would have much preferred "indentation is imbrication".

    If you have a good editor (or even Visual Studio), once you have the braces, the editor can take care of the indentation for you.



  • @Musaran said:

    I would have much preferred [b]to write Python instead of C.[/b]

    I noticed a small typo in your argument, so I went ahead and fixed it for you...



  • No, he would have preferred to write using python syntax, reasonable semantics, and useful abstractions for low level code.
    I would too, by the way.
    Rust kinda has the third and the second part fixed (it's c-style syntax, though). But it's currently too.. rusty to work with seriously<'a>. Might change with 1.0 or 2.0 or something.

    And no, there's nothing in python-style syntax that restricts it to dynamic high level scripting languages. Just as there's nothing in c-style syntax that restricts it to static low level languages.
    It's really a preference.

    I like python-style more since indentation alone is enough to understand code structure, while being less noisy (with the extra closing '}') to allow understanding a greater amount of code in the same amount of time.


  • Discourse touched me in a no-no place

    @created_just_to_disl said:

    I like python-style more since indentation alone is enough to understand code structure, while being less noisy (with the extra closing '}') to allow understanding a greater amount of code in the same amount of time.

    I prefer braces, since then when something mangles the indentation ( :angry: ) it's possible to recover without having to play “guess the semantics”. There are lots of communication channels where whitespace mangling is all too common.



  • @dkf said:

    I prefer braces, since then when something mangles the indentation ( ) it's possible to recover without having to play “guess the semantics”. There are lots of communication channels where whitespace mangling is all too common.

    There are tools which can automatically recover mangled indentation in brace languages. This is unpossible in python because the programmer has no way to mark the end of a block, so any whitespace problems will have to be fixed by a human.



  • @created_just_to_disl said:

    No, he would have preferred to write using python...

    I know, that's what I said!



  • How about not using horrible programs that mangle the indentation?
    AFAIC, python is perfect for getting those to shape up or shut up.



  • @tar said:

    There are tools in python because the programmer has no way to be fixed by a human.

    I really have no idea what you're getting at there.



  • @created_just_to_disl said:

    I really at there have no you're getting idea what.

    uh, wat?



  • If you like semantic whitespace, you''re going to love this!



  • @tar said:

    There are tools which can automatically recover mangled indentation in brace languages. This is unpossible in python because the programmer has no way to mark the end of a block, so any whitespace problems will have to be fixed by a human.

    Yes, we know.
    Most C-style language IDEs have automagical whitespace formatting features that you can trivially configure to use any reasonable corporate style. (Including enforcing K&R, ANSI/ISO etc)

    Put simply, whitespace should never have any meaning to the computer beyond "separator", regardless of how many there are.
    The reason is that computers are really good at counting while humans aren't, especially with proportional fonts - is this one space or two?
    Even worse - is it one tab or 2...8 spaces?

    As Discourse strips out 'unnecessary' whitespace, giving whitespace any significance must be Doing It Wrong™



  • Python doesn't count whitespace and nobody would ever like a language that did.
    It just compares amounts of whitespace, just like people are already experts at doing.

    [size=7](Cue trolllets saying it has to count whitespace in order to compare it. This is actually not true, while that's one implementation of comparing whitespace (and probably the implementation used by most python tokenizers), that's just an implementation detail and one could easily use computer vision for this (well minus the easily).)[/size]


Log in to reply