February 28, 2014 Re: Safe Navigation Operator “?.” for D2 ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Friday, 28 February 2014 at 11:11:28 UTC, Dicebot wrote:
> On Friday, 28 February 2014 at 09:24:23 UTC, John Colvin wrote:
>>> Chaining . operation is a code smell to begin with
>>
>> It is? Why?
>
> If a system is well-designed, then "null" state either means something (and needs to be explicitly handled) or is not possible.
>
> ?. provides simple and easy way to write a sloppy code that does not tell the reader if resulting code flow for null case was intentional. Also it is very easy to get accustomed to use ?. everywhere instead of . and get broken logic instead of NullPointerException for cases when pointer is wrongly assumed to never be null.
I sometimes come across situations like this:
writeln_or_whatever(person ? person.name : "");
(This is a case of "means something".)
Using `person?.name` is a bit shorter and DRYer. But it would be more useful if I could specify the default value it returns. With an explicit `maybe` this would be possible:
person.maybe("<n/a>").name;
|
February 28, 2014 Re: Safe Navigation Operator “?.” for D2 ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Friday, 28 February 2014 at 11:11:28 UTC, Dicebot wrote:
> On Friday, 28 February 2014 at 09:24:23 UTC, John Colvin wrote:
>>> Chaining . operation is a code smell to begin with
>>
>> It is? Why?
>
> If a system is well-designed, then "null" state either means something (and needs to be explicitly handled) or is not possible.
>
> ?. provides simple and easy way to write a sloppy code that does not tell the reader if resulting code flow for null case was intentional. Also it is very easy to get accustomed to use ?. everywhere instead of . and get broken logic instead of NullPointerException for cases when pointer is wrongly assumed to never be null.
Do you mean:
Chaining operations that can return null (or some other known-to-be-invalid state) is a code-smell.
That's quite different to saying:
Chaining operations using . is a code-smell.
which is what deadalnix said.
Either way, a do-this-if-you-can pattern is quite reasonable IMO. However, I do question whether it's common enough to justify syntax sugar.
|
February 28, 2014 Re: Safe Navigation Operator “?.” for D2 ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | On Friday, 28 February 2014 at 11:21:47 UTC, Marc Schütz wrote:
>
> I sometimes come across situations like this:
>
> writeln_or_whatever(person ? person.name : "");
>
> (This is a case of "means something".)
>
> Using `person?.name` is a bit shorter and DRYer. But it would be more useful if I could specify the default value it returns. With an explicit `maybe` this would be possible:
>
> person.maybe("<n/a>").name;
With C#, you can't use 'person' to imply 'person !is null'.
So instead you have
var name = person != null ? person.name : null;
Which is less nice than
var name = person?.name
So this feature is a bit more useful there than here. It also ties in well with the ?? operator, for something like:
var name = person?.name ?? "Unknown";
|
February 28, 2014 Re: Safe Navigation Operator “?.” for D2 ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Friday, 28 February 2014 at 12:28:22 UTC, John Colvin wrote:
> Do you mean:
>
> Chaining operations that can return null (or some other known-to-be-invalid state) is a code-smell.
>
> That's quite different to saying:
>
> Chaining operations using . is a code-smell.
>
> which is what deadalnix said.
Chaining . for non-nullables should be OK, I don't know what issue deadlnix sees here (or it is just a typo?)
|
February 28, 2014 Re: Safe Navigation Operator “?.” for D2 ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Friday, 28 February 2014 at 09:24:23 UTC, John Colvin wrote: > On Thursday, 27 February 2014 at 20:49:59 UTC, deadalnix wrote: >> On Thursday, 27 February 2014 at 13:27:14 UTC, Remo wrote: >>> >>> Apparently C# will get it in the next version. >>> http://blogs.msdn.com/b/jerrynixon/archive/2014/02/26/at-last-c-is-getting-sometimes-called-the-safe-navigation-operator.aspx >>> >>> What do you think how well would this work in D2 ? >> >> Chaining . operation is a code smell to begin with > > It is? Why? Long story : http://c2.com/cgi/wiki?LawOfDemeter Short story : It tends to make a lot of code dependent of the structure of your project, which affect evolution and maintenance negatively. |
February 28, 2014 Re: Safe Navigation Operator “?.” for D2 ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Friday, 28 February 2014 at 12:28:22 UTC, John Colvin wrote: > Do you mean: > > Chaining operations that can return null (or some other known-to-be-invalid state) is a code-smell. > That is the worse. > That's quite different to saying: > > Chaining operations using . is a code-smell. > > which is what deadalnix said. > Yes. That must not be understood as a hard rule, but something that is true most of the time. You want to look up "Law of Demeter". The problem when you chain is that you make a lot of code dependent on the structure of the project, which makes it hard to evolve or maintain the project, as any change in the structure will impact more code than it should. Obviously, this idea may be in tension with other principle, and good judgement is always welcome. As a general rule, unless you have some really good reason to, avoid chaining. > > Either way, a do-this-if-you-can pattern is quite reasonable IMO. However, I do question whether it's common enough to justify syntax sugar. This pattern exist. That is called the maybe monad. To take previous example: writeln(person ? person.name : ""); Can become Maybe!Person person; writeln(person.name.get("")); If person is a Maybe!Person, the person.name is a Maybe!string (assuming name is a string) and the get method will provide a default value if nothing is present in the Maybe monad. That ensure that null is checked consistently and provide what you want, a do-this-if-you-can pattern. |
March 01, 2014 Re: Safe Navigation Operator “?.” for D2 ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | On Friday, 28 February 2014 at 11:21:47 UTC, Marc Schütz wrote:
> On Friday, 28 February 2014 at 11:11:28 UTC, Dicebot wrote:
>> On Friday, 28 February 2014 at 09:24:23 UTC, John Colvin wrote:
>>>> Chaining . operation is a code smell to begin with
>>>
>>> It is? Why?
>>
>> If a system is well-designed, then "null" state either means something (and needs to be explicitly handled) or is not possible.
>>
>> ?. provides simple and easy way to write a sloppy code that does not tell the reader if resulting code flow for null case was intentional. Also it is very easy to get accustomed to use ?. everywhere instead of . and get broken logic instead of NullPointerException for cases when pointer is wrongly assumed to never be null.
>
> I sometimes come across situations like this:
>
> writeln_or_whatever(person ? person.name : "");
>
> (This is a case of "means something".)
>
> Using `person?.name` is a bit shorter and DRYer. But it would be more useful if I could specify the default value it returns. With an explicit `maybe` this would be possible:
>
> person.maybe("<n/a>").name;
I am also on the opinion that chaining on nullable objects
encourages sloppy code and should therefore be avoided. Because
the null case should often be handled. Chaining skips handling
the null case. Thus this syntaxic sugar is a bad idea.
The chaining pattern is okay to make code more expressive, but it
is always assumed that the objects on which it's applied are
non-nullable.
|
March 01, 2014 Re: Safe Navigation Operator “?.” for D2 ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | > Yes. That must not be understood as a hard rule, but something that is true most of the time. You want to look up "Law of Demeter". No, it's not true "most of the time". It's just another piece of arbitrary crap from the object oriented cargo cult that has no scientific basis. > The problem when you chain is that you make a lot of code dependent on the structure of the project, which makes it hard to evolve or maintain the project, as any change in the structure will impact more code than it should. > Even if that would be true, the "refactoring über alles" OO crowd couldn't care less... You refactor. Problem solved. Massive code restructuring is embraced in the OO world because OO encourages bad design like no other paradigm. |
March 01, 2014 Re: Safe Navigation Operator “?.” for D2 ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to SomeDude | >> I sometimes come across situations like this:
>>
>> writeln_or_whatever(person ? person.name : "");
>>
>> (This is a case of "means something".)
>>
>> Using `person?.name` is a bit shorter and DRYer. But it would be more useful if I could specify the default value it returns. With an explicit `maybe` this would be possible:
>>
>> person.maybe("<n/a>").name;
>
> I am also on the opinion that chaining on nullable objects
> encourages sloppy code and should therefore be avoided. Because
> the null case should often be handled. Chaining skips handling
> the null case. Thus this syntaxic sugar is a bad idea.
The null case _is_ handled, because you're explicitly specifying "maybe()". I can agree that it might lead to problems if it happens automatically and you don't see what's going on, but that isn't the case here.
|
March 01, 2014 Re: Safe Navigation Operator “?.” for D2 ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Araq | On 3/1/14, 4:10 AM, Araq wrote:
> Even if that would be true, the "refactoring über alles" OO crowd
> couldn't care less... You refactor. Problem solved. Massive code
> restructuring is embraced in the OO world because OO encourages
> bad design like no other paradigm.
Araq: could you list the problems you see in the OO world?
|
Copyright © 1999-2021 by the D Language Foundation