digitalmars.D - article comparing Rust and Zig, many points relevant to D
- Mark (6/6) Mar 09 2021 "Why I rewrote my Rust keyboard firmware in Zig: consistency,
- IGotD- (12/18) Mar 09 2021 Interesting article and it reaffirms what I originally observed
- H. S. Teoh (55/72) Mar 09 2021 These sound alarming to me, as someone who does not know Rust. Maybe I'm
- Imperatorn (4/5) Mar 09 2021 ๐ก
- tsbockman (52/54) Mar 09 2021 D is my personal language of choice, but it is no mystery to me
- SealabJaster (59/64) Mar 10 2021 And instead people see a bunch of different, incompatible memory
- Max Haughton (5/10) Mar 09 2021 I don't have any hard data to back this up, but people just
- VF (14/19) Mar 10 2021 I think the biggest reasons are bugginess and instability. Those
- H. S. Teoh (16/21) Mar 10 2021 This is not a bug. It's a feature. (Although its value is debatable.)
- Adam D. Ruppe (7/8) Mar 10 2021 You use my jni.d... it uses this to store the java methodIds it
- mw (3/11) Mar 10 2021 What is the exact usage of this feature?
- Adam D. Ruppe (40/41) Mar 10 2021 http://dpldocs.info/experimental-docs/source/arsd.jni.d.html#L1358
- mw (5/25) Mar 10 2021 If there is no optional identifier x2,
- H. S. Teoh (8/23) Mar 10 2021 [...]
- Adam D. Ruppe (26/28) Mar 10 2021 At the top level, it will always use the top-level name. This
- Walter Bright (3/24) Mar 10 2021 You're right, it's quite deliberate. Template mixins would be fairly cri...
- VF (2/11) Mar 12 2021 Oh dear God.
- Adam D. Ruppe (4/8) Mar 10 2021 That's not a bug, it is working by design and it is a very useful
- jmh530 (12/26) Mar 10 2021 I couldn't get this exact thing to run (the A.id.offsetof part
- mw (2/23) Mar 10 2021 I think he mean: A.x.offsetof
- Guillaume Piolat (21/26) Mar 11 2021 There is PL adoption research:
- Imperatorn (3/8) Mar 11 2021 Interesting! Will read ๐
"Why I rewrote my Rust keyboard firmware in Zig: consistency, mastery, and fun" https://kevinlynagh.com/rust-zig/ D is not mentioned, but the article focuses on issues of conditional compilation and compile-time execution, so I thought the D people will find it interesting.
Mar 09 2021
On Tuesday, 9 March 2021 at 16:48:28 UTC, Mark wrote:"Why I rewrote my Rust keyboard firmware in Zig: consistency, mastery, and fun" https://kevinlynagh.com/rust-zig/ D is not mentioned, but the article focuses on issues of conditional compilation and compile-time execution, so I thought the D people will find it interesting.Interesting article and it reaffirms what I originally observed with Rust and decided to look elsewhere. Rust for embedded systems is just too cumbersome due to the nature of embedded programming in my opinion and it gets quickly ugly when you step outside the normal application programming comfort zone. In this particular example, a keyboard controller, is a very simple case of embedded system and despite of that Rust just makes it difficult. Zig as handles that much easier and you can get from A to B without splitting any hairs. BetterC is a little bit what Zig offers and I would assume that BetterC would be able to handle the task in a similar fashion.
Mar 09 2021
On Tue, Mar 09, 2021 at 04:48:28PM +0000, Mark via Digitalmars-d wrote:"Why I rewrote my Rust keyboard firmware in Zig: consistency, mastery, and fun" https://kevinlynagh.com/rust-zig/ D is not mentioned, but the article focuses on issues of conditional compilation and compile-time execution, so I thought the D people will find it interesting.Favorite quotes from the article:Despite all this, I still donโt feel comfortable with Rust. It feels fractally complex โ seemingly every time I use Rust on a new project, I run into some issue that forces me to confront a new corner of the language/ecosystem.Rust has many language features and theyโre all largely disjoint from each other, so knowing some doesnโt help me guess the others.These sound alarming to me, as someone who does not know Rust. Maybe I'm reading too much into it, but it does make me hesitant to try out Rust. While D is far from perfect, I think it does a lot better in the department of guessability. I've found IME D generally does what I thought it would do, except for the occasional hiccups, bugs, or unexpected corner cases. Also, IMO D does much better in avoiding fractal complexity -- the core language features generally integrate well with each other, and things generally work without too much nitpicking. Some of the newer features, however, feel like they're less integrated, and more edging towards fractal complexity territory.I was tempted to conclude that, well, all this complexity must be inherent. Perhaps itโs just hard to do compile-time configuration and to iterate over distinct types efficiently in a safe, compiled language?This was also how I felt in C/C++ before I found D. :-D I'd say that 70-80% of the time I spent writing C++ is spent wrestling with the complexity of the language and peripheral things like memory management concerns. It conditioned me to accept that programming is inherently complex, programming languages are consequently inherently complex, and therefore the act of programming must necessarily also be complex. Then I found D. Suddenly, many things that were complex in the past are now simpler, sometimes by a lot. I found my mental resources freed up to focus on the problem domain rather than wrestling with the language. D hits many of the points of friction with other languages IME: - The tedium of memory management in C/C++: thanks to the GC, my APIs are liberated from memory-management clutter, and my brain is freed from the constant drone of memory-related concerns to actually make progress in the problem domain. (And once in a while when the GC isn't good enough, D is flexible enough to allow me to rewrite select parts of the code with manually-managed memory -- without having to re-architect the entire program from scratch.) - Boilerplate in Java: when writing Java, I find myself fighting with the language more often than actually making progress with the problem domain. A lot of this has to do with metaprogramming features, that let me factor away the endless stacks of boilerplate that I'm forced to write in Java. - Too many (nested) loops: lately I've also been enjoying writing functional-style code with UFCS -- it's been a big time-saver. Instead of writing yet another loop, or worse, N-level-nested loops to express some complex data manipulation, a UFCS one-liner neatly encapsulates all of that complexity into a form not only fast to write, but also easy to read and easy to rearrange, extend, and refactor. - Single paradigm: languages like Java (or Haskell) force you to shoehorn every problem into an OO paradigm (resp. functional paradigm). Sometimes, some code is simply better to write in a different paradigm, but in these languages you're straitjacketed and have no choice, so you end up fighting the language more than making progress in the problem domain. D being multiparadigm is a big boon in this respect. D certainly isn't perfect -- it has its own share of dark corners, WATs, and poorly-interacting corner cases. But it's a lot better than the other alternatives I've tried so far. T -- My program has no bugs! Only unintentional features...
Mar 09 2021
On Tuesday, 9 March 2021 at 20:56:12 UTC, H. S. Teoh wrote:On Tue, Mar 09, 2021 at 04:48:28PM๐ก Great summary! I don't understand why D isn't used more. Maybe it's *too* flexible for some people? ๐ค
Mar 09 2021
On Tuesday, 9 March 2021 at 21:06:46 UTC, Imperatorn wrote:Great summary! I don't understand why D isn't used more.D is my personal language of choice, but it is no mystery to me why it's been so slow to catch on. People always complain about the same (mostly valid) things when asked why they aren't using D (ascending order of importance): 4) Various out-dated criticisms like "the D compiler isn't open source": These complaints are invalid; catching people up on the history of the D project is all that is necessary to deal with them. 3) Small ecosystem: This is valid, but somewhat unfair given that D's lack of popularity is what keeps the ecosystem small. This concern is also mitigated, but not eliminated, by D's excellent interop with C (also Objective-C, Python, and maybe Java?). Getting C++ interop working more fully would help a lot, too, but that's a *very* hard problem. 2) Unsatisfying heap memory management options: D offers an easy to use but inefficient GC, and C-style unsafe manual memory management. However, what many of the people who would even *consider* switching to D really want is reference counting and borrowing (like C++, Rust, Swift, etc.), with as much compiler automation, optimization, and verification as possible. The D project has been pursuing this goal for years through improved RAII, nogc, scope, DIP 1000, live, etc. But, as of today, this subsystem just isn't good enough to replace the GC. No matter how much anyone on the forums claims that the current heap memory management story is good enough, it won't change the fact that many people who really do find D otherwise attractive are turned away by this limitation. Most of the people who only them. 1) Buggy/incomplete/absent tooling: This is the big one. I frequently encounter serious compiler bugs, the GDB debugger crashes or fails to properly inspect and step through my programs more often than not, and the D plugin for my IDE draws red squiggles and yellow highlighting all over my correct, valid, working code. I'm sure my experience in this regard is worse than most, since I make heavy use of various unpopular, incomplete, and new features. But, some of the problems I find and report are in really basic things, too. All of the above issues have improved a lot in the years that I have been using D, and I think these improvements are reflected in D's increasing adoption. I am very thankful for the hard work of all those people and institutions who have contributed to D's increasing quality. But, there is still a *long* way to go to catch up to the polished "it just works" experience of something like Java.Maybe it's *too* flexible for some people? ๐คThere are some people who aren't interested in a complex, multi-paradigm language like D. There are many others who *are* interested, but they're stuck with C++ or have switched to Rust because of the issues with D that I listed above.
Mar 09 2021
On Wednesday, 10 March 2021 at 00:14:18 UTC, tsbockman wrote:3) Small ecosystem ... However, what many of the people who would even *consider* switching to D really want is reference counting and borrowingAnd instead people see a bunch of different, incompatible memory management libraries for things like allocators, non-GC containers, and smart pointers, all of which are in varying states of completeness and buginess, and most of which aren't "standard" to use which makes it off-putting to spend any time at all with them. Not to mention that just in general, D libraries are mostly hit or miss in terms of quality and whether they even function properly at all, or are supported for more than a week after they're released. want, and you'll usually find a well-document, actively-developed/well-tested featureful alternative that has some expectation of doing what you want without too much pain. For example, 3 or so years ago me and a mentor wanted to write something that needed a database, and I thought it'd be a good time to introduce him to D. So after looking over and trying several database connectors on dub to varying levels of success (one couldn't handle SQL Server's nvarchar type; one couldn't connect for unknown reasons; one required external binaries we had trouble finding pre-compiled versions of and didn't want to spend time compiling it ourself, etc.). So in the end, we decided to go with Entity Framework, where everything basically just worked and it could even reverse-engineer our database structure into a EF model. Not to say EF doesn't have its warts, but we were up and going within a fraction of the time spent just finding something in D that could actually function at all. Meanwhile I had a sneaking suspicion that even if we got one of these libraries to work, there'd be some show-stopper bug that we'd run into even in our very simple use case. Not to mention the rich resources and documentation on the internet for EF, while for a dub library the best you usually get is the README, and if you're lucky, some example files, or depressingly, vice-versa. And I feel this is the point I often reach where I think: Is D really worth it for this project? Is D's productivity (as a language) going to be able to offset the un-productivity of its + all the other bells and whistles I need (docs, examples, tutorials, etc.)? I fear this is not uncommon, but I don't think there's any way to really measure this as a metric. However, ecosystem aside we still used D for some mild data processing and generation, which D is really enjoyable to make use of. That being said though, that was also a few years back, so I imagine it's somewhat better now, and there's a project I've been wanting to try to make so I might see for myself soon how things have improved.Buggy/incomplete/absent toolingSlowly but surely. I'm quite happy with code-d now that it doesn't crash every time I make a new line, and that autocomplete doesn't suddenly stop working. But the squiggles, oh dear me the squiggles. Debugging is still annoying though, as you said. I know I'm always quite negative about D in general, but that's due to a desire of wanting it to grow and improve, rather than malice.
Mar 10 2021
On Tuesday, 9 March 2021 at 21:06:46 UTC, Imperatorn wrote:On Tuesday, 9 March 2021 at 20:56:12 UTC, H. S. Teoh wrote:I don't have any hard data to back this up, but people just haven't really heard of D. Even on hackernews most people aren't particularly familiar with the language, and they're the kind of people who go in for that kind of stuffOn Tue, Mar 09, 2021 at 04:48:28PM๐ก Great summary! I don't understand why D isn't used more. Maybe it's *too* flexible for some people? ๐ค
Mar 09 2021
On Tuesday, 9 March 2021 at 21:06:46 UTC, Imperatorn wrote:On Tuesday, 9 March 2021 at 20:56:12 UTC, H. S. Teoh wrote:I think the biggest reasons are bugginess and instability. Those are my reasons for wanting to get out of D, and also feature bloat. I want a simpler language, but am not seeing good options... Speaking of bugginess, here's the latest bug that I noticed (dmd 2.094): mixin template X() { int x; } struct A { mixin X; int x; } // <- that compiles! int main() { import std.stdio; writeln(A.sizeof); // => 8 writeln(A.id.offsetof); // => 4 }On Tue, Mar 09, 2021 at 04:48:28PM๐ก Great summary! I don't understand why D isn't used more. Maybe it's *too* flexible for some people? ๐ค
Mar 10 2021
On Wed, Mar 10, 2021 at 05:59:56PM +0000, VF via Digitalmars-d wrote: [...]Speaking of bugginess, here's the latest bug that I noticed (dmd 2.094): mixin template X() { int x; } struct A { mixin X; int x; } // <- that compiles!This is not a bug. It's a feature. (Although its value is debatable.) Mixins exist in separate namespaces, which can be useful if you have multiple mixins that declare the same identifier. Note that there's an optional identifier after `mixin X` that can be used to disambiguate between the two instances of `x`, e.g.: struct A { mixin X x2; int x; } A.x2.x = 1; a.x = 2; T -- In a world without fences, who needs Windows and Gates? -- Christian Surchi
Mar 10 2021
On Wednesday, 10 March 2021 at 18:08:24 UTC, H. S. Teoh wrote:(Although its value is debatable.)You use my jni.d... it uses this to store the java methodIds it looks up in the generated binding class. This feature makes that very, very easy to implement and use. I'm not sure how I'd do it without that... maybe a string mixin or something, like I'm sure I'd figure it out, but it is really nice when these things actually just work.
Mar 10 2021
On Wednesday, 10 March 2021 at 18:13:09 UTC, Adam D. Ruppe wrote:On Wednesday, 10 March 2021 at 18:08:24 UTC, H. S. Teoh wrote:What is the exact usage of this feature? Can you give an example of your usage?(Although its value is debatable.)You use my jni.d... it uses this to store the java methodIds it looks up in the generated binding class. This feature makes that very, very easy to implement and use. I'm not sure how I'd do it without that... maybe a string mixin or something, like I'm sure I'd figure it out, but it is really nice when these things actually just work.
Mar 10 2021
On Wednesday, 10 March 2021 at 21:51:43 UTC, mw wrote:What is the exact usage of this feature?http://dpldocs.info/experimental-docs/source/arsd.jni.d.html#L1358 That _jmethodID is unique for each method added. So when you follow the example code: http://dpldocs.info/experimental-docs/arsd.jni.html and have like Export void hi(string name) { import std.stdio; writefln("hello from D, %s", name); } // D can also access Java methods Import void printMember(); Then hi and printMember both get their own private copy of the id. No conflict regardless of how many methods you mixin. Notice too how these mixin static constructors too, which are all combined per language rules, allowing me to actually concatenate the lists at startup for a one-go load of metadata at runtime. http://dpldocs.info/experimental-docs/source/arsd.jni.d.html#L1790 For the other side, adrdox uses that: https://github.com/adamdruppe/adrdox/blob/master/doc2.d#L3169 That's a mixin template with semi-specialized implementations of the abstract interface. But there's also cases like here: https://github.com/adamdruppe/adrdox/blob/master/doc2.d#L3028 That override the mixed in override, letting you accept the default implementations in some places, and selectively override them for other methods, without having to create another child class to do it. Now take a look at this line: https://github.com/adamdruppe/adrdox/blob/master/doc2.d#L3158 Notice the explicit usage of `this` there. Without it, it would use the local name inside the mixin template and NOT respect the override; this is good when you want to use a private member like in the jni example. But with it, it looks up one level above which means the user can easily override it and then it respects this, similar to a virtual vs static lookup in oop (which itself can get a bit nuts if you use the curiously-recurring template pattern, which I do here for reflection of a child class inside the base class http://dpldocs.info/experimental-docs/source/arsd.cgi.d.html#L8288 - the mixin template version is kinda the same idea.)
Mar 10 2021
On Wednesday, 10 March 2021 at 18:08:24 UTC, H. S. Teoh wrote:On Wed, Mar 10, 2021 at 05:59:56PM +0000, VF via Digitalmars-d wrote: [...]If there is no optional identifier x2, a.x = 2; will change which x? and how to disambiguate the two x in such case?Speaking of bugginess, here's the latest bug that I noticed (dmd 2.094): mixin template X() { int x; } struct A { mixin X; int x; } // <- that compiles!This is not a bug. It's a feature. (Although its value is debatable.) Mixins exist in separate namespaces, which can be useful if you have multiple mixins that declare the same identifier. Note that there's an optional identifier after `mixin X` that can be used to disambiguate between the two instances of `x`, e.g.: struct A { mixin X x2; int x; } A.x2.x = 1; a.x = 2;
Mar 10 2021
On Wed, Mar 10, 2021 at 09:49:12PM +0000, mw via Digitalmars-d wrote:On Wednesday, 10 March 2021 at 18:08:24 UTC, H. S. Teoh wrote:[...][...] IMO this should generate an ambiguity error. But I don't know the current behaviour. T -- Perhaps the most widespread illusion is that if we were in power we would behave very differently from those who now hold it---when, in truth, in order to get power we would have to become very much like them. -- Unknownstruct A { mixin X x2; int x; } A.x2.x = 1; a.x = 2;If there is no optional identifier x2, a.x = 2; will change which x? and how to disambiguate the two x in such case?
Mar 10 2021
On Wednesday, 10 March 2021 at 22:08:43 UTC, H. S. Teoh wrote:IMO this should generate an ambiguity error. But I don't know the current behaviour.At the top level, it will always use the top-level name. This allows for easy overriding, like with the adrdox `declarationType` method in my previous message. mixin templates seem to be fairly poorly understood in the community. I wrote a little about them here: http://dpldocs.info/this-week-in-d/Blog.Posted_2020_01_20.html#understanding-mixin-templates about a year ago, but perhaps more needs to be written. They are NOT copy/pasted code, that's closer to what string mixin is (and it isn't copy/pasted code either, but rather copy/pasted AST nodes but I digress). The common name "mixin" makes you think they're the same, but they are very different beasts. Template mixins are more like a separate struct that allows name as well as virtual slot forwarding to the surrounding context (but notably operator overloading is NOT considered, and function overloading is not automatic, requiring an `alias` bridge since the mixin template and the parent are two separate contexts with name-based overriding, not signature-based). It is a fairly unique concept but the behaviors are all there for a reason and once you know those reasons, you can do a lot of cool things with them. The biggest worry is overloading constructors, there I'd argue it is a bug / oversight. You can alias in __ctor... sometimes. Otherwise the `this` keyword isn't allowed by the syntax meaning the proper procedure doesn't work. But most everything else works well once you get to know it.
Mar 10 2021
On 3/10/2021 10:08 AM, H. S. Teoh wrote:On Wed, Mar 10, 2021 at 05:59:56PM +0000, VF via Digitalmars-d wrote: [...]You're right, it's quite deliberate. Template mixins would be fairly crippled if it didn't.Speaking of bugginess, here's the latest bug that I noticed (dmd 2.094): mixin template X() { int x; } struct A { mixin X; int x; } // <- that compiles!This is not a bug. It's a feature. (Although its value is debatable.) Mixins exist in separate namespaces, which can be useful if you have multiple mixins that declare the same identifier. Note that there's an optional identifier after `mixin X` that can be used to disambiguate between the two instances of `x`, e.g.: struct A { mixin X x2; int x; } A.x2.x = 1; a.x = 2;
Mar 10 2021
On Wednesday, 10 March 2021 at 18:08:24 UTC, H. S. Teoh wrote:On Wed, Mar 10, 2021 at 05:59:56PM +0000, VF via Digitalmars-d wrote: [...]Oh dear God.Speaking of bugginess, here's the latest bug that I noticed (dmd 2.094): mixin template X() { int x; } struct A { mixin X; int x; } // <- that compiles!This is not a bug. It's a feature.
Mar 12 2021
On Wednesday, 10 March 2021 at 17:59:56 UTC, VF wrote:Speaking of bugginess, here's the latest bug that I noticed (dmd 2.094): mixin template X() { int x; } struct A { mixin X; int x; } // <- that compiles!That's not a bug, it is working by design and it is a very useful design, allowing specialization of public members while keeping state of private members.
Mar 10 2021
On Wednesday, 10 March 2021 at 17:59:56 UTC, VF wrote:[snip] I think the biggest reasons are bugginess and instability. Those are my reasons for wanting to get out of D, and also feature bloat. I want a simpler language, but am not seeing good options... Speaking of bugginess, here's the latest bug that I noticed (dmd 2.094): mixin template X() { int x; } struct A { mixin X; int x; } // <- that compiles! int main() { import std.stdio; writeln(A.sizeof); // => 8 writeln(A.id.offsetof); // => 4 }I couldn't get this exact thing to run (the A.id.offsetof part and using int main instead of void main), but in general if you come across a bug you should file it in bugzilla. You need to be specific about what you think the bug actually is. According to the spec https://dlang.org/spec/template-mixin.html#mixin_scope there is no reason why this shouldn't compile as int x overrides the mixin. A reasonable question might be "if int x overrides what is in X, then why is it still a part of A"? There might be good reasons for why A.sizeof is 8 instead of 4.
Mar 10 2021
On Wednesday, 10 March 2021 at 18:17:19 UTC, jmh530 wrote:On Wednesday, 10 March 2021 at 17:59:56 UTC, VF wrote:I think he mean: A.x.offsetof[snip] I think the biggest reasons are bugginess and instability. Those are my reasons for wanting to get out of D, and also feature bloat. I want a simpler language, but am not seeing good options... Speaking of bugginess, here's the latest bug that I noticed (dmd 2.094): mixin template X() { int x; } struct A { mixin X; int x; } // <- that compiles! int main() { import std.stdio; writeln(A.sizeof); // => 8 writeln(A.id.offsetof); // => 4 }I couldn't get this exact thing to run (the A.id.offsetof part
Mar 10 2021
On Tuesday, 9 March 2021 at 21:06:46 UTC, Imperatorn wrote:On Tuesday, 9 March 2021 at 20:56:12 UTC, H. S. Teoh wrote:There is PL adoption research: https://lmeyerov.github.io/projects/socioplt/papers/oopsla2013.pdf In this study they found the following drivers: 1. Open source libs 2. Extending existing code 3. Already used in group See that "Particular language feature" and "Simplicity" are not really ranked high. It seems over and over the one driver of PL adoption is always availability of "open-source libraries". In pure cynical terms it can be seen is a capital transfert between those maintaining the open source corpus vs those reaping added value with the open-source code ; in that it's code you can rely on, but don't pay for maintenance (or barely). But it can also signal a thriving/collaborating community (like with CPAN Perl). In many of the new "weaponized" languages created by Big Corp, a large corpus of the open-source ecosystem is created/maintained by the Corp ; value is instead seeked in the lockin that language provides.On Tue, Mar 09, 2021 at 04:48:28PM๐ก Great summary! I don't understand why D isn't used more. Maybe it's *too* flexible for some people? ๐ค
Mar 11 2021
On Thursday, 11 March 2021 at 19:01:31 UTC, Guillaume Piolat wrote:On Tuesday, 9 March 2021 at 21:06:46 UTC, Imperatorn wrote:Interesting! Will read ๐[...]There is PL adoption research: https://lmeyerov.github.io/projects/socioplt/papers/oopsla2013.pdf [...]
Mar 11 2021