1. 29

  2. 13

    In short, my experience is that if a feature is not present in the language, D is powerful enough that the feature can be implemented in a library.

    This is D’s killer feature in my opinion. Its metaprogramming is really flexible, almost lisp-like. One of my favourite things with D is to bend it to my will and make it do what I want. I don’t often get this sense of freedom with other programming languages.

    1. 4

      The feature selection for the detailed comparison looks quite odd. All features get the same weight e.g. calling assembly code is as important as speed (!).

      There’s no mention of compile times, memory efficiency, readability and expressiveness, macros / programmability, target platforms, memory safety, binary size, community, documentation…

      1. 1

        There’s no mention of compile times, memory efficiency, readability and expressiveness, macros / programmability, target platforms, memory safety, binary size, community, documentation…

        I’m not very familiar with pascal and ada, but perhaps in some (most?) of those cases they didn’t want to flood the chart ties? For readabilities sake they only included what they felt were the most relevant for them.

      2. 6

        Rust was eliminated for lack of nested functions, which is entirely fair. Although I understand why it was not included in Rust (because of safety problems), I sometimes miss it.

        Clueless people on HN are arguing why closures are not sufficient. Well, because it’s a different feature.

        1. 6

          How is it different? Other than the lack of mutual exclusion enforcement in D, Rust closures seem the same to me. What am missing?

          1. -2

            A nested function can modify a variable in the enclosing scope. I don’t think Rust can do that.


            Edit: Whoa, whoa, RESF, just one of you was enough.

            1. 2

              A closure can. A fn can’t.

              1. 2

                Rust can do that: http://play.rust-lang.org/?gist=cbedf929dc6ee3a45b8e5fa5787460a4&version=stable&mode=debug

                I wrote it a little differently than D’s example because of the borrow checker. It’s just an example after all, so I don’t feel that bad about it, but if you want to be a stickler to match D’s example more precisely, I’d probably just use interior mutability: http://play.rust-lang.org/?gist=16d817b9a819518d2c51436730b48e75&version=stable&mode=debug

                Go can also do this as well.

                1. 1

                  Man, I really have a hard time reading Rust. Why did they have to pick such a weird syntax that looks like nothing else?

                  1. 4

                    Looks fine to me. I was never bothered by it, even when I first started, when the syntax was considerably noisier (before 1.0).

                    But then again, I can’t remember the last time I ever bothered to complain about the syntax of anything. I realize people disagree with me, but as long as it’s reasonableish, I don’t think it matters very much.

                    I also think discussions about syntax are mildly annoying, primarily because most of it probably isn’t going to change. Either you’re willing to live with it or you’re not.

                    edited to soften my language

                    1. 1

                      So it turns out that OCaml is a strong inspiration for Rust and that’s why it looks foreign to me. I didn’t know that.

                      1. 1

                        I don’t know OCaml either, but I have done a fair amount of work in Standard ML. That got me used to the tick marks used as lifetime parameters (type parameters in SML).

                        Types after names I think is in Go, which I’ve also done a fair amount of work in. I don’t know if Go originated that though. I’d guess not.

                        Most of the rest of the syntax is pretty standard IMO. Some things are too abbreviated for some folks’ taste, but I don’t really mind, because once you start writing code, those sorts of things just disappear. They are really only weird to virgin eyes. Some other oddities include using ! in macros and perhaps the different syntaxes for builtin pointer types, e.g., &mut T. (Probably defining macros themselves looks really strange too, but there are a relatively small amount of rules.)

                        Maybe the closure syntax is weird too, I don’t know. I think it’s similar to Ruby’s syntax? I definitely appreciate the terseness, as found in SML, Haskell and heck, even Javascript’s arrow functions, particularly when compared to Python’s or Lua’s longer syntax. Go’s is also mildly annoying because there’s no type inference, and you need to write out the return keyword. But, you don’t use closures as much in Go as you do in Rust as parameters to higher order functions (in my experience) because of the lack of generics. It’s for loops all the way down.

                        As long as it’s within a broad realm of reasonableness, syntax mostly just bleeds into the background for me.

                        It’s also worth mentioning that the use of interior mutability can lead to more noise in the code, especially in an example as terse as the one up-thread.

                2. 2

                  You can if the closure borrows a reference to the value (which is necessarily how it works in D). Sharing a mutable reference requires an explicit Cell/RefCell/UnsafeCell, though. UnsafeCell would presumably have the same semantics as in D.

                  1. 2

                    Edit: Whoa, whoa, RESF, just one of you was enough.

                    Instead of being a troll about it, you might consider that we all started responding around the same time and didn’t know others had already done so. (e.g., When I clicked post, Steve’s comment wasn’t on my page.)

                    1. 1

                      Well, the RESF is pretty strong. I make one off-hand wrong comment and three of you, whether intentionally or not, jump on it. I practically never get that many comments in quick succession in Lobsters. I obviously struck a nerve by speaking a falsehood that must be corrected immediately.

                      I’m also slightly unhappy that we can’t ever talk about D without “I would like to interject for a moment, what you are referring to as D is in fact Rust or as I’ve taken to calling it, CRATE+Rust”.

                      1. 3

                        I called out the RESF effect here. Hit Twitter immediately haha. Ive been keeping an eye out since. Ive seen no evidence of an active RESF here or on HN. Just looks like a mainstream language with a lot of fans, areas of usefulness, and therefore lot of comments. I see more comments about Go than Rust.

                        And then there’s Pony. Now, that one comes across as having an evangelism team present. ;)

                        1. 1

                          that one comes across as having an evangelism team present

                          Where? :) I’d like to read more actual articles about Pony, but all I’ve seen so far are links to minor release announcements…

                          1. 3

                            It was an inside joke about the Pony fan club we have here on Lobsters. Sometimes I see more Pony articles than those for mainstream languages. They usually have plenty of detail to be interesting enough for the site. Only exceptions are release submissions. I’m against release submissions in general being on this site since people that care about that stuff will likely find the release anyway. Might as well use that slot for something that can teach us something or otherwise enjoyable.

                        2. 3

                          The OP mentions Rust, and you were talking about it too. Scanning the posts tagged with D, I see exactly one substantive discussion involving Rust other than this thread. So I’m going to have to call shenanigans.

                          Well, the RESF is pretty strong.

                          Just stop. If you have an issue, then address it head on instead passive aggressively trolling.

                          D and Rust are used to solve similar sets of problems. This invites comparisons, not just on the Rust side but on the D side too. A lot of people who haven’t used Rust get their claims mixed up or are just outright wrong. I see nothing bad about politely correcting them. That’s what I did for your comment. What do I get in exchange? Whining about syntax and some bullshit about being attacked by the RESF. Please. Give me a break.

                          Do you want to know why you don’t see me talking about D? Because I don’t know the language. I try not to talk about things that I don’t know about. And if I did, and I got something wrong, I’d hope someone would correct me, not just for me, but for anyone else who read what I said and got the wrong idea.

                3. 3

                  So I know very little of C and C++. I fell into Go around the time they released v1.0, and I only tried to learn Rust around the same time, when it was still a moving target. At least that’s how I perceived it. Anyway, that’s the long preamble to my question:

                  I’d like to pick up a new language, and Rust and D both look like interesting candidates. Is there any massive advantage to either one that would make the other a poorer choice?

                  1. 6

                    Rust has a large and active open source community with over 16,000 “crates” available on crates.io. I’m not familiar with D, but it looks like it’s open source package manager, DUB, has ~1,300 packages.

                    Rust is actively improving with some major improvements (e.g. non-lexical lifetimes, generators, improved procedural macros) currently nearing stabilization, and others (e.g. const generics) planned for the next couple of years.

                    There’s also a considerable push to make Rust THE language for WebAssembly development, with seemless integration into existing front-end work flows being actively developed by Mozilla engineers.

                    1. 1

                      Is it less of a moving target to learn Rust nowadays?

                      1. 5

                        If you tried to learn Rust when Go 1.0 was released… then the answer to your question is emphatically yes. I was writing Rust before 1.0 came out, and it was intense. It’s nothing even remotely like that these days.

                        1. 3

                          Absolutely. Stable rust is stable. Breaking changes are not allowed except in extreme circumstances, e.g. something very clearly broken. There are features being added fairly regularly, but you can choose to ignore them.

                          As a side note, there are plans to introduce “epochs” in the release cycle which will be opt-in and allow breaking changes. There’s plans to keep this from fragmenting the community, though. See https://github.com/rust-lang/rfcs/pull/2052 to learn more about epochs.

                          Edit: I should mention that there are many popular crates awaiting one feature or another before stabilization (1.0 release), but these can also be avoided. The standard library provides enough core functionality for many projects, and you can easily link to C libraries if you need something stable that doesn’t exist as a Rust crate.

                      2. 4

                        I dont use either but read lots of comments. I’m guessing Rust is harder to learn, has slow compiles, and improved safety guarantees w/out performance impact in some hard areas. D lacks that key advantage of no-cost, temporal safety but compiles really fast and may be easier to learn. This is ignoring advanced features in each: Im just saying moving from C, Java, or something to either bringing your existing knowledge. I expect people to be more productive in D with Rust code running faster if it messes with memory a lot.

                        Any people who know either feel free to corroborate or counter any of that.

                      3. 2

                        I’d really like to write more D. In my particular case, I couldn’t have a GC in play (self-imposed memory constraints), but there’s a lot about it that’s attractive to me. I don’t have any desire to choose Go over it - power of the language is considerably greater from my limited experience.

                        That said, Go does have a big package community behind it like Rust.

                        1. 14

                          Stick a @nogc on your main function and you have a compile-time guarantee that no GC allocations will happen in your program.

                          1. 6

                            Neat - I didn’t realize this. Too late now for the current project, but good to know for the future. I’m particularly interested in its C++ FFI story. There’s a couple of specialized C++ libraries I’d like to use without having to write flat-C style wrappers just to call them sanely from Rust.

                            Thanks for that!

                            1. 3

                              That’s exactly the kind of tip I was hoping for in the comments. Thanks!

                              1. 5

                                It always the same arguments with D discussions:

                                • I don’t like D that has a GC!
                                • Just use @nogc!
                                • But then some stuff from the standard library does not work anymore!
                                • How much of the standard library?
                                • Nobody knows and how would you measure it anyway?
                                1. 1

                                  It’s at least a pattern that’s solvable. Someone just has to attempt to compile the whole standard library with no GC option. Then, list the breakage. Then, fix in order of priority for the kind of apps that would want no-GC option. Then, write this up into a web page. Then, everyone shares it in threads where pattern shows up. Finally, the pattern dies after 10-20 years of network effects.

                                  1. 2

                                    People are doing that. Well, except for the “write this up into a web page” part. I guess you are thinking of web pages like http://www.arewewebyet.org/

                                    1. 1

                                      Yeah, some way for people to know that they’re doing it with what level of progress. Good to know they’re doing it. That you’re the first to tell me illustrates how a page like that would be useful in these conversations. People in D camp can just drop a link and be done with it.

                            2. 3

                              I find D has a lot of packages too. Not an explosive smörgåsbord, but sufficient for my purposes.


                              The standard library by itself is fairly rich already.


                              1. 1

                                I guess the question would be whether unsafe or smart pointers are about as easy to use in D as C or C++. If so, the GC might not be a problem. In some languages, GC is really hard to avoid.

                                Maybe @JordiGH, who uses D, can tell us.

                                1. 5

                                  I write D daily. Unsafe pointers work the same as in C or C++. I wrote a GC-less C++-like smart pointer library for D. It’s basically std::unique_ptr and std::shared_ptr, but no std::weak_ptr because 1) I haven’t needed it and 2) One can, if needed, rely on the GC to break cycles (although I don’t know how easy that would be do to currently in practice.

                                  1. 1

                                    D is a better C++, so pointers easier to use than C++. As I understand, the main problem is that it used to be the case that the standard library used GC freely, making GC hard to avoid if you used the standard library. I understand there is an ongoing effort to clear this but I don’t know the current status.

                                    1. 3

                                      It depends on which part of the standard library. These days, the parts most often used have functions that don’t allocate. In any case it’s easy to avoid by using @nogc.

                                2. [Comment removed by author]

                                  1. 1

                                    Accidental double post?