Thread overview | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 07, 2018 guard clause style static if | ||||
---|---|---|---|---|
| ||||
It appears not to be possible to use static if in "guard clause style" as in void bar (T ...) (T args) { static if (args.length == 0) return; writeln (args [0]); return bar (args [1 .. $]); } Is this intended? |
July 07, 2018 Re: guard clause style static if | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On 07/07/2018 11:28 PM, kdevel wrote: > It appears not to be possible to use static if in "guard clause style" as in > > void bar (T ...) (T args) > { > static if (args.length == 0) > return; else { > > writeln (args [0]); > return bar (args [1 .. $]); } > } |
July 07, 2018 Re: guard clause style static if | ||||
---|---|---|---|---|
| ||||
Posted in reply to rikki cattermole | On Saturday, 7 July 2018 at 11:29:35 UTC, rikki cattermole wrote: >> static if (args.length == 0) >> return; > > else { > >> >> writeln (args [0]); >> return bar (args [1 .. $]); > > } That's not guard clause style [1][2]. [1] https://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html [2] http://wiki.c2.com/?GuardClause |
July 07, 2018 Re: guard clause style static if | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On 07/07/2018 11:44 PM, kdevel wrote:
> On Saturday, 7 July 2018 at 11:29:35 UTC, rikki cattermole wrote:
>>> static if (args.length == 0)
>>> return;
>>
>> else {
>>
>>>
>>> writeln (args [0]);
>>> return bar (args [1 .. $]);
>>
>> }
>
> That's not guard clause style [1][2].
>
> [1] https://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html
>
> [2] http://wiki.c2.com/?GuardClause
Neither was your original example.
"A method has conditional behavior that does not make clear what the normal path of execution is"
void bar (T ...) (T args) if (T.length == 0)
{
return;
writeln (args [0]);
return bar (args [1 .. $]);
}
void bar (T ...) (T args) if (T.length > 0)
{
writeln (args [0]);
return bar (args [1 .. $]);
}
(you meant T I suspect, as args is a runtime thing, but T is compile time, just like static if).
|
July 07, 2018 Re: guard clause style static if | ||||
---|---|---|---|---|
| ||||
Posted in reply to rikki cattermole | On Saturday, 7 July 2018 at 11:56:40 UTC, rikki cattermole wrote: > On 07/07/2018 11:44 PM, kdevel wrote: >> On Saturday, 7 July 2018 at 11:29:35 UTC, rikki cattermole wrote: >>>> static if (args.length == 0) >>>> return; >>> >>> else { >>> >>>> >>>> writeln (args [0]); >>>> return bar (args [1 .. $]); >>> >>> } >> >> That's not guard clause style [1][2]. >> >> [1] https://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html >> >> [2] http://wiki.c2.com/?GuardClause > > Neither was your original example. My example was void bar (T ...) (T args) { static if (args.length == 0) // 3 return; // 4 writeln (args [0]); return bar (args [1 .. $]); } The guard clause is in lines 3 and 4. > "A method has conditional behavior that does not make clear what the normal path of execution is" In my example one immediately spots the "normal path of execution". Your proposal void bar (T ...) (T args) { static if (args.length == 0) return; else { writeln (args [0]); return bar (args [1 .. $]); } } leads to unreadable arrow code [3]. > void bar (T ...) (T args) if (T.length == 0) > { > return; >[removed] > } > > void bar (T ...) (T args) if (T.length > 0) > { > writeln (args [0]); > return bar (args [1 .. $]); > } Interesting alternative but using template constraints introduces code repetition: If you want to add another special case, say length == 4, you have to repeat the logical complement in the "else" branch: void bar (T ...) (T args) if (T.length == 0) { return; } void bar (T ...) (T args) if (T.length == 4) { // some code } void bar (T ...) (T args) if (T.length > 0 && T.length != 4) { writeln (args [0]); return bar (args [1 .. $]); } [3] https://blog.codinghorror.com/flattening-arrow-code/ |
July 08, 2018 Re: guard clause style static if | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On 08/07/2018 12:40 AM, kdevel wrote:
> Interesting alternative
That was not an alternative.
That is what your code was doing.
|
July 07, 2018 Re: guard clause style static if | ||||
---|---|---|---|---|
| ||||
Posted in reply to rikki cattermole | On Saturday, 7 July 2018 at 12:46:08 UTC, rikki cattermole wrote:
> On 08/07/2018 12:40 AM, kdevel wrote:
>> Interesting alternative
>
> That was not an alternative.
> That is what your code was doing.
What my original code was supposed to do. But it did not compile.
Error: array index [0] is outside array bounds [0 .. 0]
Error: string slice [1 .. 0] is out of bounds
My question is if it is intentionally failing to compile a static if guard clause.
|
July 08, 2018 Re: guard clause style static if | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On 08/07/2018 12:54 AM, kdevel wrote:
> On Saturday, 7 July 2018 at 12:46:08 UTC, rikki cattermole wrote:
>> On 08/07/2018 12:40 AM, kdevel wrote:
>>> Interesting alternative
>>
>> That was not an alternative.
>> That is what your code was doing.
>
> What my original code was supposed to do. But it did not compile.
>
> Error: array index [0] is outside array bounds [0 .. 0]
> Error: string slice [1 .. 0] is out of bounds
>
> My question is if it is intentionally failing to compile a static if guard clause.
There is no such thing as a static if guard clause.
static if does not exist at runtime, only compile time. So when you erase it (CT -> RT)...
void func() {
static if(true) {
return;
}
func2();
}
becomes:
void func() {
return;
func2();
}
Which is clearly an error. Hence why you need to add else block.
|
July 07, 2018 Re: guard clause style static if | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On Saturday, 7 July 2018 at 12:54:03 UTC, kdevel wrote: > On Saturday, 7 July 2018 at 12:46:08 UTC, rikki cattermole wrote: >> On 08/07/2018 12:40 AM, kdevel wrote: >>> Interesting alternative >> >> That was not an alternative. >> That is what your code was doing. > > What my original code was supposed to do. But it did not compile. > > Error: array index [0] is outside array bounds [0 .. 0] > Error: string slice [1 .. 0] is out of bounds > > My question is if it is intentionally failing to compile a static if guard clause. The site you cited for the guard clause above (c2.com) works at runtime. The intention is to shorten the paths inside a function, I think. Therefore, a static "guard clause" is a contradiction, if I understand it correctly. The constraint in form fun(...)(...) if(...) is a static construct. Therefore, all parts should be mentioned statically. And by https://dlang.org/spec/version.html#staticif paragraph: 24.5.4.2 a static if does not introduce a new scope. So, the argument about arrow code is not valid here. |
July 09, 2018 Re: guard clause style static if | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On 7/7/18 7:28 AM, kdevel wrote:
> It appears not to be possible to use static if in "guard clause style" as in
>
> void bar (T ...) (T args)
> {
> static if (args.length == 0)
> return;
>
> writeln (args [0]);
> return bar (args [1 .. $]);
> }
>
> Is this intended?
Yes.
Try just a normal if -- it will have the same effect (the optimizer will eliminate the dead code), but will compile.
Of course, you have to fix your second part to only return bar if args.length > 0!
-Steve
|
Copyright © 1999-2021 by the D Language Foundation