December 11, 2018
On Tuesday, 11 December 2018 at 10:45:39 UTC, Atila Neves wrote:
> A few things that have annoyed me about writing D lately:
>
> https://atilanevesoncode.wordpress.com/2018/12/11/what-d-got-wrong/

One thing that could be improved in this post is separating things that can't reasonably be either fixed or added as enhancements vs. things that would be big breaking changes. I would think UFCS chain for templates, template lambdas, and eponymous template changes are all things that could be added or changed without breaking any code, whereas @safe by default would break a bunch of code. I'm not sold on immutable by default yet, but I think all the attributes should be able to be used with the block and colon syntax.
December 11, 2018
On Tuesday, 11 December 2018 at 13:42:03 UTC, Guillaume Piolat wrote:
> One could say getters and particularly setters don't really deserve a nicer way to write them. It's a code stink, it deserve a long ugly name.  (10 years ago I would be in the other camp)

Can you please explain it in more detail? I never read such about getters and setters.
December 11, 2018
On Tue, Dec 11, 2018 at 11:50 AM Atila Neves via Digitalmars-d-announce < digitalmars-d-announce@puremagic.com> wrote:

> A few things that have annoyed me about writing D lately:
>
> https://atilanevesoncode.wordpress.com/2018/12/11/what-d-got-wrong/


Eponymous templates - workaround

https://run.dlang.io/is/qIvcVH


December 11, 2018
On Tuesday, 11 December 2018 at 12:57:03 UTC, Atila Neves wrote:
> On Tuesday, 11 December 2018 at 12:52:20 UTC, Adam D. Ruppe wrote:
>> On Tuesday, 11 December 2018 at 10:45:39 UTC, Atila Neves wrote:
>>> A few things that have annoyed me about writing D lately:
>>>
>>> https://atilanevesoncode.wordpress.com/2018/12/11/what-d-got-wrong/
>>
>> If @property worked for a thing to return a delegate, it would be useful.
>>
>> But noooo, we got worked up over syntax and forgot about semantics :(
>
> @property is useful for setters. Now, IMHO setters are a code stink anyway but sometimes they're the way to go. I have no idea what it's supposed to do for getters (nor am I interested in learning or retaining that information) and never slap the attribute on.

My view of getters is that they serve as a contract of between contractor and client stating "You can't modify this value, I however can".
December 11, 2018
On 12/11/18 5:45 AM, Atila Neves wrote:
> A few things that have annoyed me about writing D lately:
> 
> https://atilanevesoncode.wordpress.com/2018/12/11/what-d-got-wrong/

Agree with most of this. UFCS for templates would be awesome, but the syntax is trickier, since instantiation uses ! instead of .

I can't see how you get around the ambiguities, especially when a template could be a UFCS function.

inout: template This doesn't work the same (no guarantee it doesn't mutate the data). And it still generates multiple copies of the same function. As I said in my dconf 2016 presentation and in numerous debates on this forums, the only reason to care about const or inout is if you care about mutability guarantees on the callee. We can make do with templates and immutable without either of those features.

@property: This was almost about to be awesome, but squabbling amongst the D core team killed it. Now, it's only a very obscure difference:

struct S
{
   int _x;
   int x1() { return _x; }
   @property int x2() { return _x; }
}

pragma(msg, typeof(S.x1)); // int()
pragma(msg, typeof(S.x2)); // int


Which is COMPLETELY USELESS, since you have to handle both cases anyway.

-Steve
December 11, 2018
On Tuesday, 11 December 2018 at 14:38:25 UTC, Steven Schveighoffer wrote:
> On 12/11/18 5:45 AM, Atila Neves wrote:
>> A few things that have annoyed me about writing D lately:
>> 
>> https://atilanevesoncode.wordpress.com/2018/12/11/what-d-got-wrong/
>
> Agree with most of this. UFCS for templates would be awesome, but the syntax is trickier, since instantiation uses ! instead of .
>
> I can't see how you get around the ambiguities, especially when a template could be a UFCS function.

I believe a reasonable case can be made for .! for UFCS - it's currently invalid syntax and will not compile, and ! is the symbol we already associate with template instantiation:

alias memberFunctions = __traits(allMembers, T)
    .!staticMap!Member
    .!Filter!(isSomeFunction);

--
  Simen
December 11, 2018
On 11-12-2018 12:10, Atila Neves wrote:
> On Tuesday, 11 December 2018 at 11:08:29 UTC, user1234 wrote:
>> On Tuesday, 11 December 2018 at 10:45:39 UTC, Atila Neves wrote:
>>> A few things that have annoyed me about writing D lately:
>>>
>>> https://atilanevesoncode.wordpress.com/2018/12/11/what-d-got-wrong/
>>
>> I agree about template lambdas. But is something that misses really an error ?
> 
> It's debatable. I thought it was funny that it was an oversight given the fact that D had lambdas to avoid the problems that C++ used to have, then went and made the "same" mistake again.

It isn't as bad as the example in the blog post, this also works:

```
range.map!(fun).filter!(gun).join;
```

-- 
Mike Wey
December 11, 2018
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
December 11, 2018
On Tue, Dec 11, 2018 at 12:57:03PM +0000, Atila Neves via Digitalmars-d-announce wrote:
> On Tuesday, 11 December 2018 at 12:52:20 UTC, Adam D. Ruppe wrote:
> > On Tuesday, 11 December 2018 at 10:45:39 UTC, Atila Neves wrote:
> > > A few things that have annoyed me about writing D lately:
> > > 
> > > https://atilanevesoncode.wordpress.com/2018/12/11/what-d-got-wrong/
> > 
> > If @property worked for a thing to return a delegate, it would be useful.
> > 
> > But noooo, we got worked up over syntax and forgot about semantics :(
> 
> @property is useful for setters. Now, IMHO setters are a code stink anyway but sometimes they're the way to go. I have no idea what it's supposed to do for getters (nor am I interested in learning or retaining that information) and never slap the attribute on.

You don't need @property for setters. This works:

	struct S {
		void func(int x);
	}
	S s;
	s.func = 1;

Of course, it's generally not a good idea to call it `func` when the intent is to emulate a member variable. :-D

I agree setters are a code stink, but only when they are trivial:

	struct S {
		private int _x;

		// This is a code smell: just make _x public, dammit!
		void x(int val) { _x = val; }
	}

But they can be very useful for non-trivial use cases.  Recently I wrote code that auto-generates a nice D API for setting GLSL inputs. So instead of writing:

	FVec position;
	glUniform3fv(myshader.u_dirLightId_pos, 1, position[].ptr);

I write:

	FVec position;
	myshader.position = position; // much more readable and less error prone!

with myshader.position defined as a setter function that does that ugly glUniform3fv call for me. Plus, I can hide away that ugly internal detail of attribute position IDs and make it private, instead of exposing it to the world and adding a needless GL dependency to client code. (E.g., now I have the possibility of substituing a Direct3D backend for the OpenGL just by emitting a different implementation for myshader.position. The calling code doesn't need to be touched.)


T

-- 
If you think you are too small to make a difference, try sleeping in a closed room with a mosquito. -- Jan van Steenbergen
December 11, 2018
On Tue, Dec 11, 2018 at 03:03:19PM +0100, Daniel Kozak via Digitalmars-d-announce wrote:
>    On Tue, Dec 11, 2018 at 11:50 AM Atila Neves via Digitalmars-d-announce
>    <[1]digitalmars-d-announce@puremagic.com> wrote:
> 
>      A few things that have annoyed me about writing D lately:
> 
>      [2]https://atilanevesoncode.wordpress.com/2018/12/11/what-d-got-wrong/
> 
>    Eponymous templates - workaround
>    [3]https://run.dlang.io/is/qIvcVH
[...]

Clever!

Perhaps this should be proposed as the lowering in a DIP for eponymous templates improvement.


T

-- 
Тише едешь, дальше будешь.
1 2 3 4 5 6 7 8 9