1. 49
  1.  

  2. 28

    Possibly unpopular opinions (and a large block of text) incoming:

    C++, Go, Swift, D and Rust all fail to adequately replace C for me. When given the choice, I would likely choose to just stick with C (for the moment; I’ll talk about what I’m considering at the end).

    C++ has so much historical baggage and issues, it’s already an immediate turn-off. More than that, it’s explicitly understood that you should carve out a subset of C++ to use as your language because trying to use the whole thing is a mess of sadness (given that it’s massive at this point). I appreciate the goal of zero-cost abstraction and having pleasant defaults in the standard library, but there are just too many problems for me to take it as a serious choice. Plus, I still have to deal with much of the unfortunate UB from C (not all of it, and honestly, I don’t mind UB in some cases; but a lot of the cases of UB in C that just make no reasonable sense come across to C++). It should be noted that I do still consider C++ occasionally in a C-with-templates style, but it’s still definitely not my preference.

    Despite how often people place it here, I do not believe Go belongs in this group of candidates The garbage collection alone makes it unfit for systems programming. I see Go as a very reasonable choice to replace Java (but I don’t use Java whenever I have the choice, so I might not be the best person to ask). There are many other parts of this language that rub me the wrong way, but mostly, I just think it’s not a good systems language (but is instead a great intro language for higher-level stuff).

    Swift is really easy to rule out: It’s not cross-platform. Even if it were, it has all sorts of terrible issues (have they fixed the massive compile times yet?) that make it a no-go.

    D, as far as I can tell, manages to be C++ without the warts in a really lovely way. Having said that, it seems like we’re talking about good replacements for C, not C++, and D just doesn’t cut it for me. GC by-default (being able to turn that off is good, but I’ll still have to do it every time), keeping name mangling by-default, etc. -betterC helps with some of this, but at that point, there’s just not enough reason for me to switch (especially with all the weirdness of there being two de facto standard libraries from different organizations, one of which I think is still closed-source? sounds like I might need to take another look at D; though, again, its emulation of C++ still suggests to me that it won’t quite cut it).

    Rust is the only language in this list that I think is actually a reasonable contender. Sadly, it still bites a lot of these issues: names are still mangled by-default, the generated binaries are huge (I’m still a little bugged that C’s hello-world with glibc dynamically links to 6KB), et al.

    But more than all of these things I’ve listed, the problems I have with these languages is that they all have a pretty big agenda (to borrow a term from Jon Blow). They all (aside from C++ which has wandered in the desert for many years) have pretty specific goals with how they are designed to try and carve out their ideal of what programming should be instead of providing tools that allow for people to build what they need.

    So, as for languages that I think might (someday, not soon really) actually replace C (for me):

    Zig strikes a balance between C (plus compile-time execution to replace the preprocessor) and LLVM IR internals which allow for incredibly fine-grained control (Hello arbitrarily-sized, fixed-width integers, how are you doing?). It also manages to have the best C interop story I have ever seen in a language so far (you can import from C header files no problem, and zig libraries can have their code called from C also no problem; astounding).

    Myr is still really new (so is Zig really), and has a lot left to figure out (e.g., its C interop story is not quite so nice yet). However, it manages to be incredibly simple and terse for a braced language. My guess is that, in the long run, myr will actually replace shell languages for me, but not C.

    Jai looks incredibly cool and embraces a lot of what I’ve mentioned above in that it is not a big agenda language, but provides a lot of really useful tools so that you can use what you make of it. However, it’s been in development for four years and there is no publicly available implementation (and I am worried that it may end up being closed-source when it is released, if ever). I’m hoping for the best here, but am expecting dark storms ahead.

    Okay, sorry for the massive post; let me just wrap up a few things. I do not mean to imply with this post that any of the languages above are inherently bad or wrong, only that they do not meet my expectations and needs in replacing C. For a brief sampling of languages that I love which suffer from all the problems I mentioned above and more, see here:

    • Haskell and Idris, but really Agda
    • Ada
    • Lua
    • APL (specifically, the unicode variants)
    • Pony

    They are all great and have brilliant ideas; they’re just not good for replacing C. :)

    Now then, I’ll leave you all to it. :)

    1. 15

      (especially with all the weirdness of there being two de facto standard libraries from different organizations, one of which I think is still closed-source?)

      That was resolved a few years ago. D just has one stdlib, it’s fairly comprehensive, and keeps getting better with each release.

      1. 12

        a few years ago

        a bit of an understatement! The competing library was dropped in 2007.

      2. 10

        Despite how often people place it here, I do not believe Go belongs in this group of candidates The garbage collection alone makes it unfit for systems programming. I see Go as a very reasonable choice to replace Java (but I don’t use Java whenever I have the choice, so I might not be the best person to ask). There are many other parts of this language that rub me the wrong way, but mostly, I just think it’s not a good systems language (but is instead a great intro language for higher-level stuff).

        Agreed with this. Go is my go-to when I need to introduce dependencies to a Python script (and thus fuck with pip --user or virtualenv or blah blah blah) for high level glue code between various systems (e.g. AWS APIs, etc.)

        I think there’s a reason Go is dominating the operations/devops tooling world - benefits of static compilation, high level, easy to write.

        Look at the amount of hacks Docker needs to do things like reexec etc. to work properly in Go, that would be trivial to do in C.

        1. 3

          Note that Zig is x86-only at the moment. Check “Support Table” on Zig’s README.

          For that matter, Rust is x86-only too, if you want Tier-1 support.

          1. 3

            I’m a big d fan, but I agree that it’s the wrong thing to replace c. Betterc doesn’t really help in this respect, because it doesn’t address the root reason of why d is the wrong thing to replace c (which being that the language itself is big, not that the runtime or standard library are). Personally, I think zig is the future, but rust has a better shot at ‘making it’, and the most likely outcome is that c stays exactly where it currently is (which I’m okay with). I haven’t looked at myr (yet), and afaik isn’t jai targeted at game development? It might be used for systems programming, but I think it might not necessarily do well there.

            It also manages to have the best C interop story I have ever seen in a language so far (you can import from C header files no problem, and zig libraries can have their code called from C also no problem; astounding)

            I think nim does this, and d for sure does, with d++ (I think this may also help with the c++ emulation? Also, I’m not sure why you’re knocking it for its lack of quality c++ emulation when it’s afaik the only language that does even a mediocre job at c++).

            1. 1

              I agree!

              As for knocking D for emulating C++, I did not mean to suggest that doing so is a count against D as a language, but rather just as a count against replacing C. I already ruled out C++, if a given language is pretty close to C++, it’s probably also going to be ruled out.

              It’s been a long time since I looked at nim, but generating C code leaves a really poor taste in my mouth, especially because of some decisions made in the language design early on (again, I haven’t looked in a while, perhaps some of those are better now).

              As for Jai, yes it’s definitely targeted at game development; however, the more I look at it, the more it looks like it might be reasonable for a lot of other programming tasks. Again though, at the moment, it’s just vaporware, so I offer no guarantee on that point. :)

            2. 2

              However, it’s been in development for four years and there is no publicly available implementation

              I’m amazed that behind the project is Jonathan Blow, he is a legend programming original video games.

            3. 30

              I enjoyed the author’s previous series of articles on C++, but I found this one pretty vacuous. I think my only advice to readers of this article would be to make up your own mind about which languages to learn and use, or find some other source to help you make up your mind. You very well might wind up agreeing with the OP:

              Programmers spend a lot of time fighting the borrow checker and other language rules in order to placate the compiler that their code really is safe.

              But it is not true for a lot of people writing Rust, myself included. Don’t take the above as a fact that must be true. Cognitive overheads come in many shapes and sizes, and not all of them are equal for all people.

              A better version of this article might have went out and collected evidence, such as examples of actual work done or experience reports or a real comparison of something. It would have been a lot more work, but it wouldn’t have been vacuous and might have actually helped someone answer the question posed by the OP.

              Both Go and Rust decided to special case their map implementations.

              Rust did not special case its “map implementation.” Rust, the language, doesn’t have a map.

              1. 16

                Hi burntsushi - sorry you did not like it. I spent months before this article asking Rust developers about their experiences where I concentrated on people actually shipping code. I found a lot of frustration among the production programmers, less so among the people who enjoy challenging puzzles. They mostly like the constraints and in fact find it rewarding to fit their code within them. I did not write this sentence without making sure it at least reflected the experience of a lot of people.

                1. 20

                  I would expect an article on the experience reports of production users to have quite a bit of nuance, but your article is mostly written in a binary style without much room for nuance at all. This does not reflect my understanding of reality at all—not just with Rust but with anything. So it’s kind of hard for me to trust that your characterizations are actually useful.

                  I realize we’re probably at an impasse here and there’s nothing to be done. Personally, I think the style of article you were trying to write is incredibly hard to do so successfully. But there are some pretty glaring errors here, of which lack of nuance and actual evidence are the biggest ones. There’s a lot of certainty expressed in this article on your behalf, which makes me extremely skeptical by nature.

                  (FWIW, I like Rust. I ship Rust code in production, at both my job and in open source. And I am not a huge fan of puzzles, much to the frustration of my wife, who loves them.)

                  1. 4

                    I just wanted to say I thought your article was excellent and well reasoned. A lot of people here seem to find your points controversial but as someone who programs C++ for food, Go for fun and Rust out of interest I thought your assessment was fair.

                    Lobsters (and Hacker News) seem to be very favourable to Rust at the moment and that’s fine. Rust has a lot to offer. However my experience has been similar to yours: the Rust community can sometimes be tiresome and Rust itself can involve a lot of “wrestling with the compiler” as Jonathan Turner himself said. Rust also provides some amazing memory safety features which I think are a great contribution so there are pluses and minuses.

                    Language design is all about trade-offs and I think it’s up to us all to decide what we value in a language. The “one language fits all” evangelists seem to be ignoring that every language has strong points and weak points. There’s no one true language and there never can be since each of the hundreds of language design decisions involved in designing a language sacrifices one benefit in favour of another. It’s all about the trade-offs, and that’s why each language has its place in the world.

                    1. 10

                      I found the article unreasonable because I disagree on two facts: that you can write safe C (and C++), and that you can’t write Rust with fun. Interpreted reasonably (so for example, excluding formally verified C in seL4, etc.), it seems to me people are demonstrably incapable of writing safe C (and C++), and people are demonstrably capable of writing Rust with fun. I am curious about your opinion of these two statements.

                      1. 8

                        I think you’re making a straw man argument here: he never said you can’t have fun with Rust. By changing his statement into an absolute you’ve changed the meaning. What he said was “Rust is not a particularly fun language to use (unless you like puzzles).” That’s obviously a subjective statement of his personal experience so it’s not something you can falsify. And he did say up front “I am very biased towards C++” so it’s not like he was pretending to be impartial or express anything other than his opinion here.

                        Your other point “people are demonstrably incapable writing safe C” is similarly plagued by absolute phrasing. People have demonstrably used unsafe constructs in Rust and created memory safety bugs so if we’re living in a world of such absolute statements then you’d have to admit that the exact same statement applies to Rust.

                        A much more moderate reality is that Rust helps somewhat with one particular class of bugs - which is great. It doesn’t entirely fix the problem because unsafe access is still needed for some things. C++ from C++11 onwards also solves quite a lot (but not all) of the same memory safety issues as long as you choose to avoid the unsafe constructs, just like in Rust.

                        An alternative statement of “people can choose to write safe Rust by avoiding unsafe constructs” is probably matched these days with “people can choose to write safe C++17 by avoiding unsafe constructs”… And that’s pretty much what any decent C++ shop is doing these days.

                        1. 5

                          somewhat with one particular class of bugs

                          It helps with several types of bugs that often lead to crashes or code injections in C. We call the collective result of addressing them “memory safety.” The extra ability to prevent classes of temporal errors… easy-to-create, hard-to-find errors in other languages… without a GC was major development. Saying “one class” makes it seem like Rust is knocking out one type of bug instead of piles of them that regularly hit C programs written by experienced coders.

                          An alternative statement of “people can choose to write safe Rust by avoiding unsafe constructs” is probably matched these days with “people can choose to write safe C++17 by avoiding unsafe constructs”

                          Maybe. I’m not familiar with C++17 enough to know. I know C++ was built on top of unsafe language with Rust designed ground-up to be safe-as-possible by default. I caution people to look very carefully for ways to do C++17 unsafely before thinking it’s equivalent to what safe Rust is doing.

                  2. 13

                    I agree wholeheartedly. Not sure who the target survey group was for Rust but I’d be interested to better understand the questions posed.

                    Having written a pretty large amount of Rust that now runs in production on some pretty big systems, I don’t find I’m “fighting” the compiler. You might fight it a bit at the beginning in the sense that you’re learning a new language and a new way of thinking. This is much like learning to use Haskell. It isn’t a good or bad thing, it’s simply a different thing.

                    For context for the author - I’ve got 10 years of professional C++ experience at a large software engineering company. Unless you have a considerable amount of legacy C++ to integrate with or an esoteric platform to support, I really don’t see a reason to start a new project in C++. The number of times Rust has saved my bacon in catching a subtle cross-thread variable sharing issue or enforcing some strong requirements around the borrow checker have saved me many hours of debugging.

                    1. 0

                      I really don’t see a reason to start a new project in C++.

                      Here’s one: there’s simply not enough lines of Rust code running in production to convince me to write a big project in it right now. v1.0 was released 3 or 4 years ago; C++ in 1983 or something. I believe you when you tell me Rust solves most memory-safety issues, but there’s a lot more to a language than that. Rust has a lot to prove (and I truly hope that it will, one day).

                      1. 2

                        I got convinced when Rust in Firefox shipped. My use case is Windows GUI application, and if Firefox is okay with Rust, so is my use case. I agree I too would be uncertain if I am doing, say, embedded development.

                        1. 2

                          That’s fair. To flip that, there’s more than enough lines of C++ running in production and plenty I’ve had to debug that convinces me to never write another line again.

                          People have different levels of comfort for sure. I’m just done with C++.

                    2. 15

                      Rust meanwhile notes that you can’t safely write a performant data structure in Rust, so they urge you not to do that.

                      The interesting thing to me is the linked FAQ (https://www.rust-lang.org/en-US/faq.html#can-i-implement-linked-lists-in-rust) literally doesn’t say that.

                      It says:

                      1. Efficient implementations of many data structures are provided by the standard library.
                      2. Most data structures can be done in safe Rust, but for comparable performance, some would be better implemented using unsafe Rust. Not that it is impossible.
                      3. Goes on to provide a specific example of how to do a doubly linked list in safe Rust, and describes how to do it also with unsafe Rust for better performance.

                      I wonder if this was an oversight or misunderstanding?

                      1. 10

                        As a follow-up, in the conclusion you say:

                        I think that in practice they may not be making real life shipped code a lot more secure - also because not that much actual Rust code is shipping.

                        While just one of the undoubtedly many examples which could be brought up, I hadn’t realized the Quantum CSS engine from Firefox was so short! More seriously, the achievements in Firefox are remarkable and inspiring, and is a large amount of code shipping to real users, and used every day.


                        One thing I like very much about the borrow checker is it took memory access problems and turned it in to a generic resource safety problem. Using the simple primitives available I’m able to easily encode usage requirements, limitations, and state changes through borrows and Drops and have them checked at compile time. This is really powerful, and I very much appreciate it.

                        For whatever it is worth, I’m a rubbish C dev – not to be trusted to write a single line – who has found Rust to be an comfortable and pleasant experience in only a few weeks of free-time practice.

                        1. 2

                          Hi - I worded this incorrectly. What I meant to say was that the FAQ says performance will disappoint unless you go into unsafe mode. “For example, a doubly-linked list requires that there be two mutable references to each node, but this violates Rust’s mutable reference aliasing rules. You can solve this using Weak, but the performance will be poorer than you likely want. With unsafe code you can bypass the mutable reference aliasing rule restriction, but must manually verify that your code introduces no memory safety violations.”. I’ve updated the wording a bit. Apologies for the confusion.

                          1. 6

                            It is improved, but they don’t urge you to not do it. However, still, unsafe Rust is still safer than C.

                            1. 3

                              Oh boy, what a quote.

                              1. 4

                                It definitely is in context of bigger picture. The default in C for doing Rust’s level of safety is separation logic with tools like VCC. Hard to learn, slow to develop (2loc/day at one point), and solvers likely slower than compiler checks. Rust brought that level of safety to most apps using a simplified model and checker. Both the checker and resulting code usually perform well. The quote indicates it can’t handle some optimized, low-level, data structures. Those atypical cases will need verification with external tool or method.

                                In light of that, Rust gets safer code faster than C in most verification cases but maybe equivalent labor in some. Rust still seems objectively better than C on being safe, efficient, and productively so.

                                1. 2

                                  there are languages in which linked lists are primitives or maybe even invisible. But if you are going to specify a language for writing programs that include linked lists, you should not have to use pragmas. This is a characteristic computer science trope: “we have a rigorous specification of this which cannot ever be violated unless you push the magic button”. It’s a way of acting as if you have solved a problem that you have simply hidden.

                          2. 13

                            As a programmer with plenty of C experience I have two problems with this article. The first is that venn diagram. It implies that skilled programmers, for some measure of “skilled”, are not writing unsafe code. I thought everyone took it for granted that even the most skilled programmers will write segfaults. Certainly, even the most skilled programmers have shipped segfaults in the past.

                            I also take issue with the description of the experience of Rust as being “fighting the borrow checker”. Bear in mind here that while I enjoy Rust, I’m by no means an evangelist; bear in mind also that I’m also coming at this from a formal languages / programming language design standpoint. I think it’s common experience to have to go through several rounds of revision before passing the Rust compiler. What isn’t common, and what I don’t understand, is why people see that as fighting the compiler. To me, this is the mark of a fantastic compiler: the compiler is there to help me write correct code. When rustc yells at me 7 ways ‘till Sunday, I know I need to rethink my code. It’s taught me more than a few things about systems programming.

                            1. 22

                              After writing Go for 5 years, I’d recommend Rust for C developers. It’s more complicated than Go for sure, but also has more to offer. The lack of garbage collection and support of generics are definitely a plus compared to Go.

                              Go is a better language for junior devs, but I wouldn’t call C programmers junior. They should be able to digest Rust’s complexity.

                              1. 9

                                They should be able to digest Rust’s complexity.

                                Non trivial amount of C programmers are still doing C to avoid additional complexity. Not everyone wants a kitchen & sink programming language.

                                1. 6

                                  Rust can definitely get overly complex if the developers show no constraint (i.e. type golf), but the control afforded by manual memory management makes up for it, IMHO. Unless it’s a one-run project, performance will eventually matter, and fixing bad allocation practices after the fact is a lot harder than doing it right from the beginning.

                                  1. 1

                                    Couldn’t they just start with a C-like subset of Rust adding from there to their arsenal what extra features they like? It’s what I was going to recommend to those trying it for safety-critical use since they likely know C.

                                    1. 9

                                      I think it’s rather difficult to write rust in a C like manner. This contrasts with go, where you can basically write C code and move the type declarations around and end up with somewhat unidiomatic but working go.

                                      1. 3

                                        I think C++ as a better C works because you still have libc besides the STL, etc. The Rust standard library uses generics, traits, etc. quite heavily and type parameters and lifetime parameters tend to percolate to downstream users.

                                        Though I think a lot of value in Rust is in concepts that may initially add some complexity, such the borrow checker rules.

                                        1. 3

                                          The problem with C++ is its complexity at the language level. I have little hope of teams of people porting various tools for static analysis, verification, and refactoring to it that C and Java already have. Certifying compilers either. C itself is a rough language but smaller. The massive bandwagon behind it caused lots of tooling to be built, esp FOSS. So, I now push for low-level stuff either safer C or something that ties into C’s ecosystem.

                                        2. 4

                                          You could argue the same for C++ (start with C and add extra features). Complexity comes with the whole ecosystem from platform support (OS, arch), compiler complexity (and hence subtle difference in feature implementations) to the language itself (C++ templates, rust macros). It’s challenging to limit oneself to a very specific subset on a single person project, it’s exponentially harder for larger teams to agree on a subset and adhere to it. I guess I just want a safer C not a new C++ replacement which seems to be the target for newer languages (like D & Rust).

                                          1. 4

                                            It’s challenging to limit oneself to a very specific subset on a single person project, it’s exponentially harder for larger teams to agree on a subset and adhere to it.

                                            I see your overall point. It could be tricky. It would probably stay niche. I will note that, in the C and Java worlds, there’s tools that check source code for compliance with coding standards. That could work for a Rust subset as well.

                                            “I guess I just want a safer C not a new C++ replacement which seems to be the target for newer languages (like D & Rust).”

                                            I can’t remember if I asked you what you thought about Cyclone. So, I’m curious about that plus what you or other C programmers would change about such a proposal.

                                            I was thinking something like it with Rust’s affine types and/or reference counting when borrow-checking sucks too much with performance acceptable. Also, unsafe stuff if necessary with the module prefixed with that like Wirth would do. Some kind of module system or linking types to avoid linker errors, too. Seemless use of existing C libraries. Then, an interpreter or REPL for the productivity boost. Extracts to C to use its optimizing and certifying compilers. I’m unsure of what I’d default with on error handling and concurrency. First round at error handling might be error codes since I saw a design for statically checking their correct usage.

                                            1. 3

                                              I can’t remember if I asked you what you thought about Cyclone. So, I’m curious about that plus what you or other C programmers would change about such a proposal.

                                              I looked at it in the past and it felt like a language built on top of C similar to what a checker tool with annotations would do. It felt geared too much towards research versus use and the site itself states:

                                              Cyclone is no longer supported; the core research project has finished and the developers have moved on to other things. (Several of Cyclone’s ideas have made their way into Rust.) Cyclone’s code can be made to work with some effort, but it will not build out of the box on modern (64 bit) platforms).

                                              However if I had to change Cyclone I would at least drop exceptions from it.

                                              I am keeping an eye on zig and that’s closest to how I imagine a potentially successful C replacement - assuming it takes up enough community drive and gets some people developing interesting software with it.

                                              That’s something Go had nailed down really well. The whole standard library (especially their crypto and http libs) being implemented from scratch in Go instead of being bindings were a strong value signal.

                                              1. 2

                                                re dropping exceptions. Dropping exceptions makes sense. Is there another way of error handling that’s safer or better than C’s that you think might be adoptable in a new, C-like language?

                                                re Zig. It’s an interesting language. I’m watching it at a distance for ideas.

                                                re standard library of X in X. Yeah, I agree. I’ve been noticing that pattern with Myrddin, too. They’ve been doing a lot within the language despite how new it is.

                                                1. 4

                                                  Dropping exceptions makes sense. Is there another way of error handling that’s safer or better than C’s that you think might be adoptable in a new, C-like language?

                                                  Yes, I think Zig actually does that pretty well: https://andrewkelley.me/post/intro-to-zig.html#error-type

                                                  edit: snippet from the zig homepage:

                                                  A fresh take on error handling that resembles what well-written C error handling looks like, minus the boilerplate and verbosity.

                                                  1. 2

                                                    Thanks for the link and tips!

                                      2. 7

                                        Short build/edit/run cycles are appreciated by junior and senior developers alike. Go currently has superior compilation times.

                                        1. 10

                                          Junior and senior developers also enjoy language features such as map, reduce, filter, and generics. Not to mention deterministic memory allocation, soft realtime, forced error checking, zero-cost abstractions, and (of course) memory safety.

                                          1. 3

                                            Junior and senior developers also enjoy language features such as map, reduce, filter, and generics.

                                            Those are great!

                                            deterministic memory allocation, soft realtime, forced error checking, zero-cost abstractions, and (of course) memory safety.

                                            Where are you finding juniors who care about this stuff? (no, really - I would like to know what kind of education got them there).

                                            1. 8

                                              I cared about those things, as a junior. I am not sure why juniors wouldn’t care, although I suppose it depends on what kind of software they’re interested in writing. It’s hard to get away with not caring, for a lot of things. Regarding education, I am self-taught, FWIW.

                                            2. 1

                                              Map, reduce and filter are easily implemented in Go. Managing memory manually, while keeping the GC running, is fully possible. Turning off the GC is also possible. Soft realtime is achievable, depending on your definition of soft realtime.

                                              1. 1

                                                Map, reduce and filter are easily implemented in Go

                                                How? Type safe versions of these, that is, without interface{} and hacky codegen solutions?

                                                1. 1

                                                  Here are typesafe examples for Map, Filter etc: https://gobyexample.com/collection-functions

                                                  Implementing one Map function per type is often good enough. There is some duplication of code, but the required functionality is present. There are many theoretical needs that don’t always show up in practice.

                                                  Also, using go generate (which comes with the compiler), generic versions are achievable too. For example like this: https://github.com/kulshekhar/fungen

                                                  1. 9

                                                    When people say “type safe map/filter/reduce/fold” or “map, reduce, filter, and generics” they are generally referring to the ability to define those functions in a way that is polymorphic, type safe, transparently handled by the compiler and doesn’t sacrifice runtime overhead compared to their monomorphic analogs.

                                                    Whether you believe such facilities are useful or not is a completely different and orthogonal question. But no, they are certainly not achievable in Go and this is not a controversial claim. It is by design.

                                                    1. 1

                                                      Yes, I agree, Go does not have the combination of type safety and generics, unless you consider code generation.

                                                      The implementation of generics in C++ also works by generating the code per required type.

                                                      1. 5

                                                        The implementation of generics in C++ also works by generating the code per required type.

                                                        But they are not really comparable. In C++, when a library defines a generic type or function, it will work with any conforming data type. Since the Go compiler does not know about generics, with go generate one can only generate ‘monomorphized’ types for a set of predefined data types that are defined an upstream package. If you want different monomorphized types, you have to import the generic definitions and run go generate for your specific types.

                                                        unless you consider code generation

                                                        By that definition, any language is a generic language, there’s always Bourne shell/make/sed for code generation ;).

                                                        1. 1

                                                          That is true, and I agree that go does not have support for proper generics and that this can be a problem when creating libraries.

                                                        2. 3

                                                          That’s why I said “transparently handled by the compiler.” ;-)

                                                          1. 0

                                                            I see your point, but “go generate” is provided by the go compiler, by default. I guess it doesn’t qualify as transparent since you have to type “go generate” or place that command in a build file of some sort?

                                                            1. 1

                                                              Yes. And for the reasons mentioned by @iswrong.

                                                              My larger point here really isn’t a technicality. My point is that communication is hard and not everyone spells out every point is precise detail, but it’s usually possible to infer the meaning based on context.

                                                              1. -1

                                                                I think the even larger point is that for a wide range of applications, “proper” and “transparent” generics might not even be needed in the first place. It would help, yes, but the Go community currently thrives without it, with no lack of results to show for.

                                                                1. 1

                                                                  I mean, I’ve written Go code nearly daily since before it was 1.0. I don’t need to argue with you about whether generics are “needed,” which is a pretty slimy way to phrase this.

                                                                  Seems to me like you’re trying to pick a fight. I already said upthread that the description of generics is different from the desire for them.

                                                                  1. -2

                                                                    You were the first to change the subject to you and me instead of sticking to the topic at hand. Downvoting as troll.

                                              2. 1

                                                By superior, I guess you meant shorter?

                                                1. 2

                                                  Compiling a very large go project with a cold cache might take a minute (sub-second once the cache is warm).

                                                  Compiling a fairly small rust app with a warm cache has taken me over a minute (I think it’s a little better than that now).

                                                  1. 1

                                                    Yes, and superior to Rust in that regard. Also the strict requirement to not have unused dependencies contributes to counteract dependency rot, for larger projects.

                                              3. 11

                                                I think part of it depends on what kind of work one wants to do. Go is really strong in network connected server spaces. Rust is a good future for low level systems programming. C++ is widely used, and has a lot of legacy codebase around. Don’t pick the tool, pick the industry/area and see what tools they are using.

                                                1. 18

                                                  I suppose I know why, but I hate that D is always left out of discussions like this.

                                                  1. 9

                                                    and Ada, heck D has it easy compared to Ada :)

                                                    1. 5

                                                      Don’t forget Nim!

                                                    2. 3

                                                      Yeah, me too. I really love D. Its metaprogramming alone is worth it.

                                                      For example, here is a compile-time parser generator:

                                                      https://github.com/PhilippeSigaud/Pegged

                                                      1. 4

                                                        This is a good point. I had to edit out a part on that a language without major adoption is less suitable since it may not get the resources it needs to stay current on all platforms. You could have the perfect language but if somehow it failed to gain momentum, it turns into somewhat of a risk anyhow.

                                                        1. 4

                                                          That’s true. If I were running a software team and were picking a language, I’d pick one that appeared to have some staying power. With all that said, though, I very much believe D has that.

                                                        2. 3

                                                          And OCaml!

                                                          1. 11

                                                            In my opinion, until ocaml gets rid of it’s GIL, which they are working on, I don’t think it belongs in this category. A major selling point of Go, D, and rust is their ability to easily do concurrency.

                                                            1. 6

                                                              Both https://github.com/janestreet/async and https://github.com/ocsigen/lwt allow concurrent programming in OCaml. Parallelism is what you’re talking about, and I think there are plenty of domains where single process parallelism is not very important.

                                                              1. 2

                                                                You are right. There is Multicore OCaml, though: https://github.com/ocamllabs/ocaml-multicore

                                                            2. 1

                                                              I’ve always just written of D because of the problems with what parts of the compiler are and are not FOSS. Maybe it’s more straightforward now, but it’s not something I’m incredibly interested in investigating, and I suspect I’m not the only one.

                                                              1. 14
                                                            3. 9

                                                              Most people have a fixed supply of discipline for tasks which are not intrinsically fun but still important. This is the kind of discipline that is needed to create secure code. Robert M. Pirsig wrote great words on this in Zen and the art of Motorcycle Maintenance where he describes ‘Gumption’. Recommended.

                                                              However - we can deplete our supply of gumption easily enough by fighting our language. We run out of discipline that way. The result may be code that is memory safe but executes plugins from a globally writable directory.

                                                              In this sense, the Rust memory security features may not be a net positive for writing safe code.

                                                              I don’t follow this reasoning. To me it’s completely backwards.

                                                              First, I’ll admit there may be something to this for people new to the language if learning new things costs gumption. However, I don’t think it’s fair to compare how someone feels when they program in a language they’ve been using for decades vs a language they’re still learning. (Sorry ahu, I’m not aware of what your experience is with rust and since you didn’t state it I’m assuming it’s not much.) Otherwise we’d all still be using assembly because ‘C is too complicated and forces you to think about too much irrelevant’.

                                                              I’ve been programming Rust for years and doing it professionally for > 1 year now. I don’t fight the borrow checker any more, instead I know that it will catch me when I do something I shouldn’t have. That means that I don’t have to even think about it any more. To some extent the patterns that I’ve learned mean it’s just right the first time, but if I introduce something that isn’t safe I immediately get an error to pop up in the terminal next to me. Only then do I have to think about how what I did could be violating some rule elsewhere. Then as soon as I fix it, I can promptly forget about it.

                                                              In the end my brain is limited, the more I can offload to the computer the more I have space for the interesting things. Or as the author puts it: I have to spend less gumption on writing Rust because the compiler brings more of its own gumption.

                                                              1. 4

                                                                Right. We develop the resilience to fight through those “not intrinsically fun” problem-solving tasks. In fact, it’s something every single one of us did when we first began learning how to code.

                                                                1. 1

                                                                  (Grumpy C programmer who’s dabbled with Rust)

                                                                  I think you are both right. :) Most of the “fighting the borrow checker” happens when one doesn’t have much experience with Rust. As one gets better, I can only assume that one gets better at coming up with designs which lend themselves to fewer borrow checker fights.

                                                                  I think this is very similar to the pain experienced by a C programmer (really any procedural language) trying something radically different - e.g., common lisp. From my own experience, writing lisp was a pain at first because I just tried to write the code just as I would in C - because that’s just what I’m used to. With time and practice, one gets better at the new language and dealing with its quirks. (For the record, I lost interest in common lisp not long after my first aha moment.)

                                                                  So, I guess one can define two points in time for a Rust developer: the novice and the expert. For the novice, I think ahu’s statement is more or less correct. For the expert, you are correct. On that note, the steepness of the learning curve for Rust is interesting - if it is too steep, not enough novices will have the gumption to take the hit in productivity to practice enough to become experts.

                                                                2. 7

                                                                  Interesting this was written by a powerDNS person, they are a very smart and helpful group of people and the PowerDNS codebase is a good read.

                                                                  1. 1

                                                                    Thanks Shane! We try :-) blush

                                                                  2. 7

                                                                    One thing that is clear to me: the author hasn’t actually written much (or perhaps any) Rust. This is clear to me because I think one of the traps that the merely Rust-curious fall into is a disproportional fear and loathing of the borrow checker. This is disproportional because it ignores many of the delightful aspects of Rust – for example, that algebraic types in a non-GC’d language represent a revolution in error handling. (I also happen to love the macro system, Cargo, the built-in testing framework, and a bunch of other smaller things.) Yes, the lack of things like non-lexical lifetimes can make for some wrestling with the borrow checker, but once one is far enough into Rust to encounter these things, they are also far enough in to appreciate the value it brings to systems programming.

                                                                    To sum, the author shouldn’t weigh in on Rust (or any language, really) so definitively without having written any – or at least make clear that his perspective is informed by reading blog entries, not actual experience…

                                                                    1. 1

                                                                      One thing that is clear to me: the author hasn’t actually written much (or perhaps any) Rust. This is clear to me because …

                                                                      To sum, the author shouldn’t weigh in on Rust (or any language, really) so definitively without having written any – or at least make clear that his perspective is informed by reading blog entries, not actual experience…

                                                                      I believe it wasn’t your intent, but your commentary reads a bit like “Only true Rustaceans should be allowed to talk about Rust”.

                                                                      1. 3

                                                                        Everyone should be allowed to talk about Rust. There is no authority that deserves to have the power to decide which people can or cannot talk about Rust.

                                                                        That said, it’s also fine to say that the author’s opinion about Rust is untrustworthy because it bears the hallmarks of someone who has read about Rust but not actually used it themselves in any meaningful way. I myself agree that it’s possible to write lots of useful rust code without running into situations where the borrow checker trips you up, and that some of Rust’s best innovations are the “small” things like the algebraic types, macros, Cargo, etc. that are now available in a non-GC systems language.

                                                                        1. 1

                                                                          it bears the hallmarks of someone who has read about Rust but not actually used it themselves in any meaningful way

                                                                          I still use rustlang but share the same opinion as the author. Did I write enough of it to be trustworthy? :)

                                                                          Rust’s best innovations are the “small” things like the algebraic types, macros, Cargo, etc. that are now available in a non-GC systems language

                                                                          Nothing on that list was rustlang’s innovation.

                                                                    2. 4

                                                                      A lot of people bring up really good technical points. Here’s a ‘rainbow and smiley faces’ comment!

                                                                      One thing to remember- any of those choices is better than no language! Sure, keep getting better at C, etc. If you want to learn a new one, make sure you PICK one. Don’t stop learning!

                                                                      1. [Comment removed by author]

                                                                        1. 4

                                                                          Why? Go has a lot going for it.

                                                                          1. 1

                                                                            I doubt your comment help anyone in the community… A little why would be probably enough to help others understand your point of view!

                                                                          2. -4

                                                                            Honestly, they should retire. Open up some positions for everyone else.