Date: Thu, 17 Nov 2022 17:51:32 +0200
Sorry, not sure how to reply to this thread only (probably because I set my
mailing list subscription to "digest once per day").
> `if constexpr` has explicit rules allowing it to discard statements
> depending on the result of the constant expression. But that is a
> special grammatical construct explicitly designed with this
> functionality in mind.
This is exactly what I'm talking about. Why `if constexpr` can discard
statements but boolean operations cannot?
I would imagine that the behaviour of the following two code snippets is
identical:
```
if constexpr (a)
{
if constexpr (b)
{
//do something
}
}
```
```
if constexpr (a && b)
{
//do something
}
```
But it is not in the case where `a` is true and `b` is not evaluatable.
Of course, `b` should still be checked for basic syntax the same way
templates are checked even before they're instantiated.
You cannot compile a template with broken syntax but you can still write a
template which doesn't make sense for specific types as long as you don't
instantiate the template with those types.
I think the same logic should apply here. `b` should be valid only if it is
instantiated/evaluated. And this instantiation should only happen if the
expression's value is needed (i.e. `a` was true).
This is what I refer to as "short-circuiting".
Think of it as a lazy evaluation.
If `a` is false the compiler should not even consider evaluating `b` and
should not generate any compilation errors if `b` is not a valid expression.
I realize I'm complaining about syntactic sugar but syntactic sugar is
sometimes needed to adhere to the DRY principle and in this case I think it
would make the code more readable and less error-prone. Also, it would make
the generic world look and feel more like the runtime world.
I would go even further and add a constexpr ternary operator, so you can
reduce code duplication even more. But that's a totally different topic.
mailing list subscription to "digest once per day").
> `if constexpr` has explicit rules allowing it to discard statements
> depending on the result of the constant expression. But that is a
> special grammatical construct explicitly designed with this
> functionality in mind.
This is exactly what I'm talking about. Why `if constexpr` can discard
statements but boolean operations cannot?
I would imagine that the behaviour of the following two code snippets is
identical:
```
if constexpr (a)
{
if constexpr (b)
{
//do something
}
}
```
```
if constexpr (a && b)
{
//do something
}
```
But it is not in the case where `a` is true and `b` is not evaluatable.
Of course, `b` should still be checked for basic syntax the same way
templates are checked even before they're instantiated.
You cannot compile a template with broken syntax but you can still write a
template which doesn't make sense for specific types as long as you don't
instantiate the template with those types.
I think the same logic should apply here. `b` should be valid only if it is
instantiated/evaluated. And this instantiation should only happen if the
expression's value is needed (i.e. `a` was true).
This is what I refer to as "short-circuiting".
Think of it as a lazy evaluation.
If `a` is false the compiler should not even consider evaluating `b` and
should not generate any compilation errors if `b` is not a valid expression.
I realize I'm complaining about syntactic sugar but syntactic sugar is
sometimes needed to adhere to the DRY principle and in this case I think it
would make the code more readable and less error-prone. Also, it would make
the generic world look and feel more like the runtime world.
I would go even further and add a constexpr ternary operator, so you can
reduce code duplication even more. But that's a totally different topic.
-- Zamfir Yonchev On Thu, Nov 17, 2022 at 2:00 PM <std-discussion-request_at_[hidden]> wrote: > Send Std-Discussion mailing list submissions to > std-discussion_at_[hidden] > > To subscribe or unsubscribe via the World Wide Web, visit > https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion > or, via email, send a message with subject or body 'help' to > std-discussion-request_at_[hidden] > > You can reach the person managing the list at > std-discussion-owner_at_[hidden] > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Std-Discussion digest..." > > > Today's Topics: > > 1. Re: short-circuiting logical operations on constexpr > predicates (Jason McKesson) > 2. Re: short-circuiting logical operations on constexpr > predicates (Edward Catmur) > 3. Re: short-circuiting logical operations on constexpr > predicates (Thiago Macieira) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Wed, 16 Nov 2022 09:42:58 -0500 > From: Jason McKesson <jmckesson_at_[hidden]> > To: std-discussion_at_[hidden] > Subject: Re: [std-discussion] short-circuiting logical operations on > constexpr predicates > Message-ID: > <CANLtd3UfeDJ53Hm5zJXHUv0hNp-c=Yfn0Q6MTRzm= > OeWiioNUw_at_[hidden]> > Content-Type: text/plain; charset="UTF-8" > > On Wed, Nov 16, 2022 at 5:00 AM Zamfir Yonchev via Std-Discussion > <std-discussion_at_[hidden]> wrote: > > > > Hi, > > > > I was wondering why the language doesn't support short-circuiting on > logical operations in constexpr context. > > It does. The rules of short-circuit evaluation don't change because > something is in a constant expression. Your problem is not a lack of > short-circuit evaluation; your problem is that short-circuit > evaluation doesn't mean what you think it does. > > `std::invoke_result_t<F, T>` is ill-formed if `F` is not invokable. > That is not a matter of expression evaluation; that's a matter of > template instantiation. It's not the result of the evaluation that is > ill-formed; it's the *existence* of the expression itself. The literal > text of the source code makes no sense, as far as the language is > concerned. It is no different than if you wrote `a + - + - + c`. > > The compiler doesn't get to the point where it would even consider > evaluating the expression because the code doesn't make sense. > > `if constexpr` has explicit rules allowing it to discard statements > depending on the result of the constant expression. But that is a > special grammatical construct explicitly designed with this > functionality in mind. > > So the reason why what you wrote doesn't work is because there is no > special expression-level construct that was added to the language to > allow discarding of subexpressions in the same way that `if constexpr` > can discard statements. > > > ------------------------------ > > Message: 2 > Date: Wed, 16 Nov 2022 15:02:26 +0000 > From: Edward Catmur <ecatmur_at_[hidden]> > To: std-discussion_at_[hidden] > Subject: Re: [std-discussion] short-circuiting logical operations on > constexpr predicates > Message-ID: > < > CAJnLdOaTNma9xmW82jtKY0z4XYnBtCn++D5SyzARw37H6eCA1w_at_[hidden]> > Content-Type: text/plain; charset="utf-8" > > On Wed, 16 Nov 2022 at 14:44, Jason McKesson via Std-Discussion < > std-discussion_at_[hidden]> wrote: > > > On Wed, Nov 16, 2022 at 5:00 AM Zamfir Yonchev via Std-Discussion > > <std-discussion_at_[hidden]> wrote: > > > > > > Hi, > > > > > > I was wondering why the language doesn't support short-circuiting on > > logical operations in constexpr context. > > > > It does. The rules of short-circuit evaluation don't change because > > something is in a constant expression. Your problem is not a lack of > > short-circuit evaluation; your problem is that short-circuit > > evaluation doesn't mean what you think it does. > > > > `std::invoke_result_t<F, T>` is ill-formed if `F` is not invokable. > > That is not a matter of expression evaluation; that's a matter of > > template instantiation. It's not the result of the evaluation that is > > ill-formed; it's the *existence* of the expression itself. The literal > > text of the source code makes no sense, as far as the language is > > concerned. It is no different than if you wrote `a + - + - + c`. > > > > The compiler doesn't get to the point where it would even consider > > evaluating the expression because the code doesn't make sense. > > > > `if constexpr` has explicit rules allowing it to discard statements > > depending on the result of the constant expression. But that is a > > special grammatical construct explicitly designed with this > > functionality in mind. > > > > So the reason why what you wrote doesn't work is because there is no > > special expression-level construct that was added to the language to > > allow discarding of subexpressions in the same way that `if constexpr` > > can discard statements. > > > > Ahem. Actually, we do have such a construct in the evaluation of > constraints. You can make use of that mode by wrapping your test in > `requires requires`: > > constexpr bool test = requires { requires std::is_invocable_v<F, T> && > std::is_same_v<std::invoke_result_t<F, T>, int>; }; > > Demo: https://godbolt.org/z/7q5dvKnsn > > https://eel.is/c++draft/expr.prim.req.general#5.sentence-3 > -------------- next part -------------- > HTML attachment scrubbed and removed > > ------------------------------ > > Message: 3 > Date: Wed, 16 Nov 2022 11:17:22 -0800 > From: Thiago Macieira <thiago_at_[hidden]> > To: std-discussion_at_[hidden] > Subject: Re: [std-discussion] short-circuiting logical operations on > constexpr predicates > Message-ID: <1805684.QCnGb9OGeP_at_[hidden]> > Content-Type: text/plain; charset="us-ascii" > > On Wednesday, 16 November 2022 06:42:58 PST Jason McKesson via > Std-Discussion > wrote: > > The literal > > text of the source code makes no sense, as far as the language is > > concerned. It is no different than if you wrote `a + - + - + c`. > > Note, this expression *does* make sense and is allowed. The first + is the > binary addition operator; all the rest are unary prefixes. So this > expression > is > > a + (-(+(-(+c)))) > > If you remove the idempotent unary plus, you get > > a + (-(-c)) > > And two negations is the same as doing nothing (ignoring the UB at > INT_MIN), > resulting in a simple addition > > a + c > > Similarly, both a+++c and a---c are permitted, as are a*/*/*/c and > a/*/*/*c. > > None of those should pass a code review, of course. > > -- > Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org > Software Architect - Intel DCAI Cloud Engineering > > > > > > ------------------------------ > > Subject: Digest Footer > > Std-Discussion mailing list > Std-Discussion_at_[hidden] > https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion > > > ------------------------------ > > End of Std-Discussion Digest, Vol 44, Issue 3 > ********************************************* >
Received on 2022-11-17 15:51:45