Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 17, 2020 "if not" condition check (for data validation) | ||||
---|---|---|---|---|
| ||||
Is there a cleaner way to implement an "if not" condition check? WHY NOT JUST USE "IF"? For data validation, code is cleaner and more intelligible if the condition being checked is written in an affirmative sense; that is, in the same way that `assert` is written. This is especially true when `and` and `or` logic is involved. `if` is not a good substitute, because it works in the opposite sense, often requiring lots of `not`s. As a trivial example: assert( configfile.isFile && configfile.extension == ".conf" ) -vs- if ( !configfile.isFile || configfile.extension != ".conf" ) <handle it> An `if` statement can be written in the affirmative sense, by using an empty `then` statement + an `else` statement: if ( configfile.isFile && configfile.extension == ".conf", message ) { } else <handle it> But then the logic intuitively feels wrong for an `if`, because the handler is always in the `else`. When there are only a few such checks, it might not matter. But when there are a lot of checks, the code gets ugly (lots of `else`s) and the clutter adds up. ORIGINAL SOLUTION The following solution works and the code is very readable. However, it has a couple of notable deficiencies. void unless(T)(T condition, lazy void func ) { if ( !condition ) func(); } : unless( configfile.isFile && configfile.extension == ".conf", handleIt( _ _ )); The most obvious shortcomings are: 1. It only works with a handler function. So `continue` and the like can't be used, for example. 2. It is inefficient, adding an extra function call to every condition check. Inside a loop, this is cumulative. A BETTER SOLUTION ??? I haven't been able to come up with another option that is more efficient yet doesn't sacrifice readability. I would welcome suggestions. Thanks in advance. Denis |
June 18, 2020 Re: "if not" condition check (for data validation) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Denis | On Wednesday, 17 June 2020 at 23:46:54 UTC, Denis wrote: > `if` is not a good substitute, because it works in the opposite sense, often requiring lots of `not`s. As a trivial example: > > assert( configfile.isFile && configfile.extension == ".conf" ) > -vs- > if ( !configfile.isFile || configfile.extension != ".conf" ) > A BETTER SOLUTION ??? > > I haven't been able to come up with another option that is more efficient yet doesn't sacrifice readability. I would welcome suggestions. > > Thanks in advance. > Denis if( ! (configfile.isFile && configfile.extension == ".conf") ) ? |
June 18, 2020 Re: "if not" condition check (for data validation) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stanislav Blinov | On Thursday, 18 June 2020 at 00:43:40 UTC, Stanislav Blinov wrote:
>
> if( ! (configfile.isFile && configfile.extension == ".conf") )
>
> ?
That does indeed clean up the compound logic. One is still left with:
if( !(
if( !
if( !(
if( !
:
I was hoping to get away from all the `not`s too.
|
June 17, 2020 Re: "if not" condition check (for data validation) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Denis | On 6/17/20 4:46 PM, Denis wrote:> Is there a cleaner way to implement an "if not" condition check? > if ( configfile.isFile && configfile.extension == ".conf", message ) { } > else <handle it> if (isConfigFile(name)) { // ... } else { // ... } The following is suitable in many cases: enforce(isConfigFile(name), format!"%s is not a config file"(name)); // ... I shortened that in many occasions: enforceConfigFile(name); // ... Of course, depending on the situation it is assert() or assertConfigFile(). Ali |
June 18, 2020 Re: "if not" condition check (for data validation) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Let me clarify the requirements and rephrase the question -- REQUIREMENTS `assert`, `enforce` and the `unless` function I wrote (above) all allow the condition to be expressed in an affirmative sense, and they also achieve the goal of readability. These are the initial requirements. `unless` improves on `assert` and `enforce` by allowing a custom action to be specified. This might be to write an error message and exit (like `assert` and `enforce`). But it could also be to write a warning message (to console or a log file) but not exit. So the next requirement is to be able to specify a custom action. Unfortunately a function, like the one I wrote, doesn't work because it doesn't allow actions that would skip or repeat some code (`continue`, `goto`, etc) to be specified as the second argument. It also doesn't allow code to be skipped or repeated after executing the function in the second argument. (That is, after writing a warning message or log notice, continue processing at some point.) A conditional operator like `if` is needed, not a function. THE ESSENTIAL QUESTION Is there a way to write an `unless` operator that would allow the condition to be expressed in an affirmative sense? It would be used like `if`, i.e. something like: unless ( <condition> ) { <handle it>; // Or even: <ignore it> continue; } Templates offer a clean syntax, but I can't come up with a way to use them for a conditional operator. Mixins are flexibile, but I suspect the result would not be very readabile (that is, less readable even than "if ( ! (..." ). I was hoping that some feature, or combination of features, in D might allow this to be achieved. |
June 18, 2020 Re: "if not" condition check (for data validation) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Denis | On Thursday, 18 June 2020 at 12:13:21 UTC, Denis wrote:
> THE ESSENTIAL QUESTION
>
> Is there a way to write an `unless` operator that would allow the condition to be expressed in an affirmative sense? It would be used like `if`, i.e. something like:
>
> unless ( <condition> ) {
> <handle it>; // Or even: <ignore it>
> continue; }
>
> Templates offer a clean syntax, but I can't come up with a way to use them for a conditional operator. Mixins are flexibile, but I suspect the result would not be very readabile (that is, less readable even than "if ( ! (..." ). I was hoping that some feature, or combination of features, in D might allow this to be achieved.
No, there isn't a way to write an operator. And yes, with templates you could do something like
auto not(alias cond)() { return !cond(); }
if (not!(() => abra && cadabra)) ...
but that is indeed even less readable.
|
June 18, 2020 Re: "if not" condition check (for data validation) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stanislav Blinov | On Thursday, 18 June 2020 at 12:50:35 UTC, Stanislav Blinov wrote:
>
> auto not(alias cond)() { return !cond(); }
>
> if (not!(() => abra && cadabra)) ...
>
> but that is indeed even less readable.
No reason to use templates here
```
pragma(inline, true) auto not(bool cond) { return !cond(); }
if (not!(abra && cadabra)) ...
//same as above
if (abra.not || cadabra.not) ...
```
|
June 18, 2020 Re: "if not" condition check (for data validation) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dukc | On Thursday, 18 June 2020 at 13:57:39 UTC, Dukc wrote:
> if (not!(abra && cadabra)) ...
if (not(abra && cadabra)) ...
|
June 18, 2020 Re: "if not" condition check (for data validation) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dukc | On Thursday, 18 June 2020 at 13:57:39 UTC, Dukc wrote:
> No reason to use templates here
Pff. Me no think straight. -.-
|
June 18, 2020 Re: "if not" condition check (for data validation) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dukc | On Thursday, 18 June 2020 at 13:58:33 UTC, Dukc wrote:
> On Thursday, 18 June 2020 at 13:57:39 UTC, Dukc wrote:
>> if (not!(abra && cadabra)) ...
> if (not(abra && cadabra)) ...
Which is a quite a complicated way to write
if (!(abra && cadabra)) ...
|
Copyright © 1999-2021 by the D Language Foundation