October 20, 2017
On Friday, 20 October 2017 at 02:20:31 UTC, Adam D. Ruppe wrote:
> On Friday, 20 October 2017 at 00:26:19 UTC, bauss wrote:
>
> In dom.d, since I use this kind of thing somewhat frequently, I wrote a function called `optionSelector` which returns a wrapper type that is never null on the outside, but propagates null through the members. So you can do
>
> foo.optionSelector("x").whatever.you.want.all.the.way.down
>
> and it handles null automatically.
>


That's pretty interesting.
October 19, 2017
On Friday, October 20, 2017 02:20:31 Adam D. Ruppe via Digitalmars-d wrote:
> On Friday, 20 October 2017 at 00:26:19 UTC, bauss wrote:
> > return foo ? foo : null;
> >
> > where
> >
> > return foo ?? null; would be so much easier.
>
> return getOr(foo, null);
>
> That's really easy to do generically with a function. I wouldn't object to the ?? syntax, but if it really is something you write all over the place, you could just write the function.
>
> > return foo ? foo.bar ? foo.bar.baz ? foo.bar.baz.something : null;
> >
> > Which could just be:
> >
> > return foo?.bar?.baz?.something;
>
> In dom.d, since I use this kind of thing somewhat frequently, I wrote a function called `optionSelector` which returns a wrapper type that is never null on the outside, but propagates null through the members. So you can do
>
> foo.optionSelector("x").whatever.you.want.all.the.way.down
>
> and it handles null automatically.
>
>
> You can do that semi-generically too with a function if it is something you use really frequently.

For better or worse, solutions like this are the main reason that a number of things folks ask for don't get added to the language. It's frequently the case that what someone wants to do can already be done using the language as-is; it just may not be as syntactically pleasing as what the person wants, and they may not know D well enough yet to have come up with the solution on their own.

- Jonathan M Davis

October 20, 2017
On Friday, 20 October 2017 at 04:26:24 UTC, Jonathan M Davis wrote:
> On Friday, October 20, 2017 02:20:31 Adam D. Ruppe via Digitalmars-d wrote:
>> On Friday, 20 October 2017 at 00:26:19 UTC, bauss wrote:
>> > return foo ? foo : null;
>> >
>> > where
>> >
>> > return foo ?? null; would be so much easier.
>>
>> return getOr(foo, null);
>>
>> That's really easy to do generically with a function. I wouldn't object to the ?? syntax, but if it really is something you write all over the place, you could just write the function.
>>
>> > return foo ? foo.bar ? foo.bar.baz ? foo.bar.baz.something : null;
>> >
>> > Which could just be:
>> >
>> > return foo?.bar?.baz?.something;
>>
>> In dom.d, since I use this kind of thing somewhat frequently, I wrote a function called `optionSelector` which returns a wrapper type that is never null on the outside, but propagates null through the members. So you can do
>>
>> foo.optionSelector("x").whatever.you.want.all.the.way.down
>>
>> and it handles null automatically.
>>
>>
>> You can do that semi-generically too with a function if it is something you use really frequently.
>
> For better or worse, solutions like this are the main reason that a number of things folks ask for don't get added to the language. It's frequently the case that what someone wants to do can already be done using the language as-is; it just may not be as syntactically pleasing as what the person wants, and they may not know D well enough yet to have come up with the solution on their own.
>
> - Jonathan M Davis

Yeah, but if it can be done by stuff like you said it's not reason to not implement syntactic sugar for it.

array[0 .. 42] can be substituted by array.slice(0, 42) too, but it's not.

it's more handy to write
void foo(int? a, string? b);

than
void foo(Maybe!int a, Maybe!string b);


same for
return a ?? null;

than
return getOr(a, null);


foo.optionSelector("x").whatever.you.want.all.the.way.down
it's not clear if you are able or not to able to hit the null.

foo?.x?.whatever?.you?.want;
is more clear and doesn't need any boilerplate.
it doesn't need to be implemented in code.
October 20, 2017
On Friday, October 20, 2017 08:09:59 Satoshi via Digitalmars-d wrote:
> On Friday, 20 October 2017 at 04:26:24 UTC, Jonathan M Davis
>
> wrote:
> > On Friday, October 20, 2017 02:20:31 Adam D. Ruppe via
> >
> > Digitalmars-d wrote:
> >> On Friday, 20 October 2017 at 00:26:19 UTC, bauss wrote:
> >> > return foo ? foo : null;
> >> >
> >> > where
> >> >
> >> > return foo ?? null; would be so much easier.
> >>
> >> return getOr(foo, null);
> >>
> >> That's really easy to do generically with a function. I wouldn't object to the ?? syntax, but if it really is something you write all over the place, you could just write the function.
> >>
> >> > return foo ? foo.bar ? foo.bar.baz ? foo.bar.baz.something : null;
> >> >
> >> > Which could just be:
> >> >
> >> > return foo?.bar?.baz?.something;
> >>
> >> In dom.d, since I use this kind of thing somewhat frequently, I wrote a function called `optionSelector` which returns a wrapper type that is never null on the outside, but propagates null through the members. So you can do
> >>
> >> foo.optionSelector("x").whatever.you.want.all.the.way.down
> >>
> >> and it handles null automatically.
> >>
> >>
> >> You can do that semi-generically too with a function if it is something you use really frequently.
> >
> > For better or worse, solutions like this are the main reason that a number of things folks ask for don't get added to the language. It's frequently the case that what someone wants to do can already be done using the language as-is; it just may not be as syntactically pleasing as what the person wants, and they may not know D well enough yet to have come up with the solution on their own.
> >
> > - Jonathan M Davis
>
> Yeah, but if it can be done by stuff like you said it's not reason to not implement syntactic sugar for it.
>
> array[0 .. 42] can be substituted by array.slice(0, 42) too, but
> it's not.
>
> it's more handy to write
> void foo(int? a, string? b);
>
> than
> void foo(Maybe!int a, Maybe!string b);
>
>
> same for
> return a ?? null;
>
> than
> return getOr(a, null);
>
>
> foo.optionSelector("x").whatever.you.want.all.the.way.down it's not clear if you are able or not to able to hit the null.
>
> foo?.x?.whatever?.you?.want;
> is more clear and doesn't need any boilerplate.
> it doesn't need to be implemented in code.

Yes, there is syntactic sugar in the language, and yes, there could be more, but it reached the point a while ago where Walter and Andrei seem to have decided that additional syntactic sugar isn't worth it. For something to be added the language, it generally has to add actual capabilities or solve a problem that is just unreasonable or impossible to solve with a library solution.

And honestly, where to draw the line on syntactic sugar is highly subjective. Something that one person might think makes the code nicely concise might seem annoyingly crpytic to someone else. And obviously, not everything can have syntactic sugar. Not everything can be built into the language. A line has to be drawn somewhere. It's just a question of where it makes the most sense to draw it, and that's not at all obvious. There's bound to be disagreement on the matter.

D is an extremely powerful language, and for now at least, the conclusion seems to be that its power is being underutilized and that it simply isn't worth adding things to the language if they can be easily done with a library solution. Obviously, there are things that some folks would like to be in the language that aren't, but there's always going to be something that someone wants to be in the language but isn't, and the guys in charge seem to have decided that D is now featureful enough and powerful enough that it's not getting new features unless it actually needs them. Simply making some syntax look prettier isn't enough. A feature has to actually add capabilities that we're missing. There may be exceptions to that, but that's generally where things sit.

And honestly, they were going to have to take this stance at some point. We can't keep adding syntactic sugar forever. They just happen to have stopped adding syntactic sugar before they added some syntactic sugar that you'd like D to have.

If you can make a really good argument in a DIP as to why D really needs a feature that you want, then it may yet get added (even if it's only syntactic sugar), but it's going to have to be a really compelling argument that is likely going to need to show why the feature is objectively better and thus worth having rather than simply saving you a bit of typing or making the code look prettier. It's probably going to have to clearly reduce bugs or provide capabilities that can't reasonably be done with a library.

D is long past the point where the language was in flux and we were constantly adding new features. Features do still get added, but they really have to pull their own weight rather than being a nice-to-have.

- Jonathan M Davis

October 20, 2017
On Friday, 20 October 2017 at 08:32:36 UTC, Jonathan M Davis wrote:
> On Friday, October 20, 2017 08:09:59 Satoshi via Digitalmars-d wrote:
>> On Friday, 20 October 2017 at 04:26:24 UTC, Jonathan M Davis
>>
>> wrote:
>> > On Friday, October 20, 2017 02:20:31 Adam D. Ruppe via
>> >
>> > Digitalmars-d wrote:
>> >> On Friday, 20 October 2017 at 00:26:19 UTC, bauss wrote:
>> >> > [...]
>> >>
>> >> return getOr(foo, null);
>> >>
>> >> That's really easy to do generically with a function. I wouldn't object to the ?? syntax, but if it really is something you write all over the place, you could just write the function.
>> >>
>> >> > [...]
>> >>
>> >> In dom.d, since I use this kind of thing somewhat frequently, I wrote a function called `optionSelector` which returns a wrapper type that is never null on the outside, but propagates null through the members. So you can do
>> >>
>> >> foo.optionSelector("x").whatever.you.want.all.the.way.down
>> >>
>> >> and it handles null automatically.
>> >>
>> >>
>> >> You can do that semi-generically too with a function if it is something you use really frequently.
>> >
>> > For better or worse, solutions like this are the main reason that a number of things folks ask for don't get added to the language. It's frequently the case that what someone wants to do can already be done using the language as-is; it just may not be as syntactically pleasing as what the person wants, and they may not know D well enough yet to have come up with the solution on their own.
>> >
>> > - Jonathan M Davis
>>
>> Yeah, but if it can be done by stuff like you said it's not reason to not implement syntactic sugar for it.
>>
>> array[0 .. 42] can be substituted by array.slice(0, 42) too, but
>> it's not.
>>
>> it's more handy to write
>> void foo(int? a, string? b);
>>
>> than
>> void foo(Maybe!int a, Maybe!string b);
>>
>>
>> same for
>> return a ?? null;
>>
>> than
>> return getOr(a, null);
>>
>>
>> foo.optionSelector("x").whatever.you.want.all.the.way.down it's not clear if you are able or not to able to hit the null.
>>
>> foo?.x?.whatever?.you?.want;
>> is more clear and doesn't need any boilerplate.
>> it doesn't need to be implemented in code.
>
> Yes, there is syntactic sugar in the language, and yes, there could be more, but it reached the point a while ago where Walter and Andrei seem to have decided that additional syntactic sugar isn't worth it. For something to be added the language, it generally has to add actual capabilities or solve a problem that is just unreasonable or impossible to solve with a library solution.
>
> And honestly, where to draw the line on syntactic sugar is highly subjective. Something that one person might think makes the code nicely concise might seem annoyingly crpytic to someone else. And obviously, not everything can have syntactic sugar. Not everything can be built into the language. A line has to be drawn somewhere. It's just a question of where it makes the most sense to draw it, and that's not at all obvious. There's bound to be disagreement on the matter.
>
> D is an extremely powerful language, and for now at least, the conclusion seems to be that its power is being underutilized and that it simply isn't worth adding things to the language if they can be easily done with a library solution. Obviously, there are things that some folks would like to be in the language that aren't, but there's always going to be something that someone wants to be in the language but isn't, and the guys in charge seem to have decided that D is now featureful enough and powerful enough that it's not getting new features unless it actually needs them. Simply making some syntax look prettier isn't enough. A feature has to actually add capabilities that we're missing. There may be exceptions to that, but that's generally where things sit.
>
> And honestly, they were going to have to take this stance at some point. We can't keep adding syntactic sugar forever. They just happen to have stopped adding syntactic sugar before they added some syntactic sugar that you'd like D to have.
>
> If you can make a really good argument in a DIP as to why D really needs a feature that you want, then it may yet get added (even if it's only syntactic sugar), but it's going to have to be a really compelling argument that is likely going to need to show why the feature is objectively better and thus worth having rather than simply saving you a bit of typing or making the code look prettier. It's probably going to have to clearly reduce bugs or provide capabilities that can't reasonably be done with a library.
>
> D is long past the point where the language was in flux and we were constantly adding new features. Features do still get added, but they really have to pull their own weight rather than being a nice-to-have.
>
> - Jonathan M Davis

OK, you are right, except one thing.
I think, saving a bit of typing and making the code look prettier is acceptable reason to add syntactic sugar. Actually, it's definition of syntactic sugar.

I accept that the authors of D have their own line on s. sugar, but ideal opensource project should fulfills the requirements of the majority not represent subjective opinion of one.


Personally, I had 3 options:
1. Use D and be angry every time when I must write getOne(foo, null) instead of foo ?? null and similar stuff.
2. Use different language, like C#
3. Fork D and implement the stuff by myself

Actually, I chose C# just because I need to get project done ASAP and don't have time to implement the missing things by myself.

Personally, I prefer user friendliness over fast performance because performance can be upgraded by upgrading hardware, but development speed cannot.


If you need reason why is writing less code better just calculate the time of it.
getOne(foo, null)  // costs 3 sec.
foo ?? null // cost 1 sec.

if you need to write it for 10 times per day and you have company with 100 developers it costs 2000 sec (33 min) per day.

It's 132 hours per year. And still, you are writing ugly code.
October 20, 2017
On 10/20/17 01:32, Jonathan M Davis wrote:
> On Friday, October 20, 2017 08:09:59 Satoshi via Digitalmars-d wrote:
>> On Friday, 20 October 2017 at 04:26:24 UTC, Jonathan M Davis
>>
>> wrote:
>>> On Friday, October 20, 2017 02:20:31 Adam D. Ruppe via
>>>
>>> Digitalmars-d wrote:
>>>> On Friday, 20 October 2017 at 00:26:19 UTC, bauss wrote:
>>>>> return foo ? foo : null;
>>>>>
>>>>> where
>>>>>
>>>>> return foo ?? null; would be so much easier.
>>>>
>>>> return getOr(foo, null);
>>>>
>>>> That's really easy to do generically with a function. I
>>>> wouldn't object to the ?? syntax, but if it really is
>>>> something you write all over the place, you could just write
>>>> the function.
>>>>
>>>>> return foo ? foo.bar ? foo.bar.baz ? foo.bar.baz.something :
>>>>> null;
>>>>>
>>>>> Which could just be:
>>>>>
>>>>> return foo?.bar?.baz?.something;
>>>>
>>>> In dom.d, since I use this kind of thing somewhat frequently,
>>>> I wrote a function called `optionSelector` which returns a
>>>> wrapper type that is never null on the outside, but propagates
>>>> null through the members. So you can do
>>>>
>>>> foo.optionSelector("x").whatever.you.want.all.the.way.down
>>>>
>>>> and it handles null automatically.
>>>>
>>>>
>>>> You can do that semi-generically too with a function if it is
>>>> something you use really frequently.
>>>
>>> For better or worse, solutions like this are the main reason
>>> that a number of things folks ask for don't get added to the
>>> language. It's frequently the case that what someone wants to
>>> do can already be done using the language as-is; it just may
>>> not be as syntactically pleasing as what the person wants, and
>>> they may not know D well enough yet to have come up with the
>>> solution on their own.
>>>
>>> - Jonathan M Davis
>>
>> Yeah, but if it can be done by stuff like you said it's not
>> reason to not implement syntactic sugar for it.
>>
>> array[0 .. 42] can be substituted by array.slice(0, 42) too, but
>> it's not.
>>
>> it's more handy to write
>> void foo(int? a, string? b);
>>
>> than
>> void foo(Maybe!int a, Maybe!string b);
>>
>>
>> same for
>> return a ?? null;
>>
>> than
>> return getOr(a, null);
>>
>>
>> foo.optionSelector("x").whatever.you.want.all.the.way.down
>> it's not clear if you are able or not to able to hit the null.
>>
>> foo?.x?.whatever?.you?.want;
>> is more clear and doesn't need any boilerplate.
>> it doesn't need to be implemented in code.
>
> Yes, there is syntactic sugar in the language, and yes, there could be more,
> but it reached the point a while ago where Walter and Andrei seem to have
> decided that additional syntactic sugar isn't worth it. For something to be
> added the language, it generally has to add actual capabilities or solve a
> problem that is just unreasonable or impossible to solve with a library
> solution.
>
> And honestly, where to draw the line on syntactic sugar is highly
> subjective. Something that one person might think makes the code nicely
> concise might seem annoyingly crpytic to someone else. And obviously, not
> everything can have syntactic sugar. Not everything can be built into the
> language. A line has to be drawn somewhere. It's just a question of where it
> makes the most sense to draw it, and that's not at all obvious. There's
> bound to be disagreement on the matter.
>
> D is an extremely powerful language, and for now at least, the conclusion
> seems to be that its power is being underutilized and that it simply isn't
> worth adding things to the language if they can be easily done with a
> library solution. Obviously, there are things that some folks would like to
> be in the language that aren't, but there's always going to be something
> that someone wants to be in the language but isn't, and the guys in charge
> seem to have decided that D is now featureful enough and powerful enough
> that it's not getting new features unless it actually needs them. Simply
> making some syntax look prettier isn't enough. A feature has to actually add
> capabilities that we're missing. There may be exceptions to that, but that's
> generally where things sit.
>
> And honestly, they were going to have to take this stance at some point. We
> can't keep adding syntactic sugar forever. They just happen to have stopped
> adding syntactic sugar before they added some syntactic sugar that you'd
> like D to have.
>
> If you can make a really good argument in a DIP as to why D really needs a
> feature that you want, then it may yet get added (even if it's only
> syntactic sugar), but it's going to have to be a really compelling argument
> that is likely going to need to show why the feature is objectively better
> and thus worth having rather than simply saving you a bit of typing or
> making the code look prettier. It's probably going to have to clearly reduce
> bugs or provide capabilities that can't reasonably be done with a library.
>
> D is long past the point where the language was in flux and we were
> constantly adding new features. Features do still get added, but they really
> have to pull their own weight rather than being a nice-to-have.
>
> - Jonathan M Davis
>

Here is the thing that bothers me about that stance. You are correct, but I don't think you've considered the logical conclusion of the direction your argument is headed. Pray tell, why must we stop adding syntactic sugar? Why does their need to be an (by your own admission) arbitrary limit?

If we look at any moderately successful language (C++/C#/Java/Python/etc.) you will find that all of them have accumulated syntax sugar over the years at a fairly constant rate. For example, C# has added point releases to it's release schedule for which the express purpose is adding syntax sugar.

I think the purpose of syntax sugar has been fundamentally misunderstood by grammando's the world over. The purpose of syntax sugar is to give the most commonly used idioms an expressive short-hand. Some examples of syntax sugar in the D language are: lambdas, virtual functions, ternary, I could go on. Some examples of syntax sugar is C# are obvious and have been previously been mentioned here, for example the ?? operator. Others are less obvious, for example, async/await is syntax sugar for a collection of Task-based idioms in C#.

The logical conclusion (reductio ad absurdum) of your argument is coding in binary. Everything else is just syntax sugar.

Grammando's suffer from a particularly pernicious cognitive bias called "Functional fixedness" or the inability to use a device in any way other than it is traditionally used. Grammando's believe that a grammar has always been a certain way, and that nothing need be added, removed, or modified. This bias is often enforced by The Curse of Knowledge (I know, so everyone else must know as well).

The reality is that grammars, like any other social construct, change, often very rapidly. For example, in English, "ain't" used to be considered a "high class" word. Within the space of a few short years, as the low-born began to use it, the high-born rejected it and deemed it "low-class" and thus you have the situation we have today with that word.

Contractions are the Syntax Sugar of the English language. You use them everyday without even thinking about it. And the ones you use today are quite different than the ones you used 10 or 20 years ago. And even the regional use can vary widely at any given point in time.

Syntax sugar is no different in D than it is in English. For example: a ?? b is a contraction of: a !is null ? a : b which itself is a contraction of: if (a !is null) { return a; } else { return b; } Indeed, the CPU only ever sees the last one.

Syntax sugar simply takes the common idioms that the culture around D has collected and then distills them into expressive forms. As with spoken language, to declare an "end" to syntax sugar is to declare an end to the culture that surrounds it. If the language cannot adapt to the culture changing around it, the language will die, and the culture will move on.

-- 
Adam Wilson
IRC: LightBender
import quiet.dlang.dev;
October 20, 2017
On Friday, October 20, 2017 02:49:34 Adam Wilson via Digitalmars-d wrote:
> Here is the thing that bothers me about that stance. You are correct, but I don't think you've considered the logical conclusion of the direction your argument is headed. Pray tell, why must we stop adding syntactic sugar? Why does their need to be an (by your own admission) arbitrary limit?
>
> If we look at any moderately successful language (C++/C#/Java/Python/etc.) you will find that all of them have accumulated syntax sugar over the years at a fairly constant rate. For example, C# has added point releases to it's release schedule for which the express purpose is adding syntax sugar.

It simply doesn't make sense to add every stray feature that folks ask for. Maybe some additional syntactic sugar will be added to D in the future, but there are way too many feature requests for it to make sense to implement even a small fraction of them. Some things are worth adding, but many really aren't. We have to say no frequently, or we'll be drowned in stray features to implement. And only so much can be added to a language before it becomes completely unwieldy. For instance, how many people are actually experts on C++ and understand all of its ins and outs? _Very_ few people. It's simply too complicated a language. Other languages aren't necessarily as bad off in that regard, but if you add enough to any language, it will get there. Every time you add something to the language, you stand the chance of improving some aspect of the language, but it comes at the cost of additional complexity. Sometimes the addition is worth that complexity, and sometimes it isn't.

Knowing when to add something and when not to is often a tough question, but it's still true that you can't add everything. And inevitably, some of the things you leave out will annoy some people by their absence, just as some of the things you add will annoy some folks by being there.

For better or worse, Walter and Andrei's current stance is essentially that if something can be reasonably done already in the language as it is, they're not adding a feature to do it. D is already insanely powerful as it is, and too often folks are looking to add a feature to the language when it's trivial to do it with a library solution. That certainly doesn't mean that nothing new is going to be added, but we have far more important features to worry about than saving someone from having to type a few extra characters because they want to use a couple of ?'s instead of typing out the code themselves or using a function call to encapsulate the behavior - e.g. finishing sorting out stuff like scope, @safety, and shared are far more critical.

If someone has a really strong argument for why something is worth adding, then they're free to create a DIP for it, and if they can convince Walter and Andrei, it can make it into the language. But at this point in D's development, syntactic sugar really isn't high on the list of things that they consider to be of value. That doesn't mean that they're always right, but on the whole, I agree with them.

- Jonathan M Davis

October 20, 2017
On Friday, 20 October 2017 at 09:40:26 UTC, Satoshi wrote:
> If you need reason why is writing less code better just calculate the time of it.
> getOne(foo, null)  // costs 3 sec.
> foo ?? null // cost 1 sec.


Note that I do NOT object to these additions. I think they'd be trivial, backward compatible, and familiar to C# and even some Javascript coders. We could probably patch the compiler in under an hour to support them since they are such simple constructs and if you did that, I'd vote yes to merge them.


But at the same time, be realistic. The time difference is actually insignificant, and the function is even more flexible (it can do things like type conversions too) and I'd choose a function over the sugar in many cases.

We shouldn't be arguing about this, we should either be implementing it or just using the easily-written function.
October 20, 2017
On Friday, 20 October 2017 at 00:26:19 UTC, bauss wrote:
> On Wednesday, 18 October 2017 at 08:56:21 UTC, Satoshi wrote:
>> conditional dereferencing and stuff about that (same as in C#)
>> foo?.bar;
>> foo?[bar];
>> return foo ?? null;
>
> Tbh. these are some I really wish were in D, because it becomes tedious having to write something like this all the time:
>
> return foo ? foo : null;
>
> where
>
> return foo ?? null; would be so much easier.
>
> It especially becomes painful when you have something with multiple member accesses.
>
> Like:
>
> return foo ? foo.bar ? foo.bar.baz ? foo.bar.baz.something : null;
>
> Which could just be:
>
> return foo?.bar?.baz?.something;
>
>>
>> async/await (vibe.d is nice but useless in comparison to C# or js async/await idiom)
>> I want to create function returning Promise/Task and await where I want to.
>> e.g.
>> auto result = device.start(foo, bar); // This is RPC to remote server returning Task!Bar
>> // do some important stuff
>> return await result; // wait for RPC finish, then return it's result
>
> I don't think this is much necessary, because the fiber implementations already are able to let you write code close to this.
>
> The only difference is you have to import the modules, but it's such a small thing I don't think you really need this.
>
>>
>> implement this thing from C# (just because it's cool)
>> new Foo() {
>>   property1 = 42,
>>   property2 = "bar"
>> };
>>
>>
>>
>> Thanks for your time.
>> - Satoshi
>
> I really wish this was implemented for classes too! Currently it exist for structs and it completely baffles me why it has never been implemented for structs.

http://forum.dlang.org/post/mailman.2562.1403196857.2907.digitalmars-d@puremagic.com

From that thread:

Here's a slightly improved version that collapses nested wrappers into a
single wrapper, so that Maybe!(Maybe!(Maybe!...Maybe!T)...) == Maybe!T:

	/**
	 * A safe-dereferencing wrapper resembling a Maybe monad.
	 *
	 * If the wrapped object is null, any further member dereferences will simply
	 * return a wrapper around the .init value of the member's type. Since non-null
	 * member dereferences will also return a wrapped value, any null value in the
	 * middle of a chain of nested dereferences will simply cause the final result
	 * to default to the .init value of the final member's type.
	 */
	template SafeDeref(T)
	{
	    static if (is(T U == SafeDeref!V, V))
	    {
	        // Merge SafeDeref!(SafeDeref!X) into just SafeDeref!X.
	        alias SafeDeref = U;
	    }
	    else
	    {
	        struct SafeDeref
	        {
	            T t;

	            // Make the wrapper as transparent as possible.
	            alias t this;

	            // This is the magic that makes it all work.
	            auto opDispatch(string field)()
	                if (is(typeof(__traits(getMember, t, field))))
	            {
	                alias Memb = typeof(__traits(getMember, t, field));

	                // If T is comparable with null, then we do a null check.
	                // Otherwise, we just dereference the member since it's
	                // guaranteed to be safe of null dereferences.
	                //
	                // N.B.: we always return a wrapped type in case the return
	                // type contains further nullable fields.
	                static if (is(typeof(t is null)))
	                {
	                    return safeDeref((t is null) ? Memb.init
	                                                 : __traits(getMember, t,
	                                                            field));
	                } else {
	                    return safeDeref(__traits(getMember, t, field));
	                }
	            }
	        }
	    }
	}

	/**
	 * Wraps an object in a safe dereferencing wrapper resembling a Maybe monad.
	 *
	 * If the object is null, then any further member dereferences will just return
	 * a wrapper around the .init value of the wrapped type, instead of
	 * dereferencing null. This applies recursively to any element in a chain of
	 * dereferences.
	 *
	 * Params: t = data to wrap.
	 * Returns: A wrapper around the given type, with "safe" member dereference
	 * semantics.
	 */
	auto safeDeref(T)(T t)
	{
	    return SafeDeref!T(t);
	}

	unittest
	{
	    class Node
	    {
	        int val;
	        Node left, right;

	        this(int _val, Node _left=null, Node _right=null)
	        {
	            val = _val;
	            left = _left;
	            right = _right;
	        }
	    }

	    auto tree = new Node(1,
	        new Node(2),
	        new Node(3,
	            null,
	            new Node(4)
	        )
	    );

	    import std.stdio;
	    writeln(safeDeref(tree).right.right.val);
	    writeln(safeDeref(tree).left.right.left.right);
	    writeln(safeDeref(tree).left.right.left.right.val);
	}

	// Static test of monadic composition of SafeDeref.
	unittest
	{
	    {
	        struct Test {}
	        alias A = SafeDeref!Test;
	        alias B = SafeDeref!A;

	        static assert(is(B == SafeDeref!Test));
	        static assert(is(SafeDeref!B == SafeDeref!Test));
	    }

	    // Timon Gehr's original test case
	    {
	        class C
	        {
	            auto foo = safeDeref(C.init);
	        }

	        C c = new C;

	        //import std.stdio;
	        //writeln(safeDeref(c).foo); // SafeDeref(SafeDeref(null))

	        import std.string;
	        auto type = "%s".format(safeDeref(c).foo);
	        assert(type == "SafeDeref!(C)(null)");
	    }
	}
October 20, 2017
On Thursday, 19 October 2017 at 06:50:12 UTC, Fra Mecca wrote:
> We miss a build system that is tailored towards enterprises

Anything more specific on that?