On Tue, Dec 11, 2018 at 10:45:39AM +0000, Atila Neves via Digitalmars-d-announce wrote: > A few things that have annoyed me about writing D lately: > > https://atilanevesoncode.wordpress.com/2018/12/11/what-d-got-wrong/
About UFCS chains for templates: totally agree! I found myself wishing for exactly that, many times. I'd even venture to say we should cook up a DIP for it. To prevent confusion and potential ambiguity with non-template UFCS chains, I propose using a separate operator, perhaps `.!`: alias blah = AliasSeq!(...) .!firstTemplate!(...) .!secondTemplate!(...) ...; Template lambdas have also been an annoyance for me. But again, there's a need to distinguish between a template lambda and a non-template lambda. And yes, I've also run into the eponymous template renaming problem. But I think it will be a pretty small and safe change to use `this` instead of repeating the template name? And while we're at it, might as well use `this` for recursive templates too. So we'd have something like: template Eponymous(T...) { static if (T.length == 0) enum this = 1; else enum this = 1 + 2*this!(T[1 .. $]); } Now we can freely rename Eponymous without also having to rename the occurrences of `this`, which in current syntax would also have to be spelt out as `Eponymous`. Though we probably have to write it as `This` instead, in order to prevent ambiguity when working with class templates. @property getters... I've pretty much given up on @property by this point, except for the few places (primarily isInputRange and its ilk) where @property is explicitly tested for. Optional parens and the equivalence of `func(1)` vs. `func = 1` have made the distinction between @property and non-@property more-or-less irrelevant except for language lawyers and corner cases that nobody uses. Dmd's -property flag is a flop that nobody uses anymore. There have been a few efforts in the past for reviving @property, but nothing has come of it, and in the recent years nobody has even bothered to talk about it anymore. So, tl;dr: @property is moribund, if not completely dead. As far as I'm concerned, it belongs only in the history books of D now. inout... it's still useful for reducing template bloat in certain cases. But yeah, it has some not-very-pretty corner cases that I don't really want to talk about right now. But for the most part, the niche cases for which it's intended still work pretty well. It can be a life-saver when you try to be (slightly) const-correct in your code. Of course, const is a giant bear to work with -- it's an all-or-nothing deal that can require refactoring your *entire* codebase -- and generally I don't bother with it except for leaf modules that don't affect too much else. Trying to be const-correct in your core application logic can quickly turn into a nightmare -- and inout is also implicated in such cases. And yeah, ref as a storage class rather than part of the type is a strange concept that seems incongruous with much of the rest of the language. Its asymmetry with type qualifiers makes it hard to reason about (you have to shift mental gears when parsing it, which hampers easy understanding of code). I generally avoid it except in quick-hack cases, e.g., to make opIndex work with assignment without actually writing a separate opIndexAssign, or to grant by-reference semantics to struct parameters (but in the latter case I've often found it better to just change the struct to a class instead). So it's a *necessary* part of the language, but it feels a lot like a square peg jammed in a round hole sometimes. If I were to redesign ref, I'd do it a lot differently. As for attribute soup... I've mostly given up on writing attributes. I just stick () in front of every function parameter list to turn them into templates, and let the compiler do auto-inference for me. The only time I'd spell out attributes is in unittests, or in the rare case where I want to ensure a certain attribute is in effect. But seriously, in the grand scheme of things, attributes are an added annoyance that nobody wants to deal with (and do so only grudgingly when it cannot be helped). Attributes need to be auto-inferred everywhere. Nothing else is scalable. Of course, I realize that it's a bit too late to have auto inference in non-template functions, but I fully applaud Walter's move to apply inference to auto functions. The wider the scope of auto inference, the less attribute soup needs to be visible in your code, and the better it will be. In an ideal world, attributes would be completely invisible, and completely inferred and propagated by the compiler via static analysis. (Yes I know this doesn't work with separate compilation. But in theory, it *should*. The compiler should just store attributes in a special section in the object file and load them upon import. The user shouldn't even see them except when you need to specify them explicitly for clarity or for enforcement.) T -- Never trust an operating system you don't have source for! -- Martin Schulze