-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
do we want variable-arity operators? #451
Comments
My current preferences (ordered most to least preferred): 1: d[same direction of comparison only] c b d[any direction] a For 1: I don't really want to support |
1: d[same direction of comparison only] b c d[any direction] 2: a b 3: b c a |
Another possible use case for variable-arity operators is that it would let us support I don't feel like any of the variable-arity options discussed above offers a good cost/benefit tradeoff. 1d might come close, but it would still add some nontrivial complexity to the language, while addressing only a fairly specialized set of use cases. |
QQ about 1d Given: |
Happy to hear arguments either way. My intention was that it is -- I think that's the less surprising behavior, even though it results in unnecessary computations. |
I find it unfortunate that a seemingly inviting and attractive syntax results in suboptimal performance. I would find it equally unfortunate if a short-circuiting "and" was implicit. So I think on balance I'd probably prefer to just make everything ill-formed, and make people spell out what they mean using parentheses. |
I would have assumed that it short circuits left to right as it can because that is what conditional expressions have trained me to expect. |
That said, I'm not sure how much anyone's intuition is trained on expecting short circuiting in |
Regardless of the rest of this, I have a strong preference for (2a) and (3b). I feel like tuples should be a language syntax feature, and not rely on operators. Similarly, I think assignment should be a language feature and we should not try to get into chained assignment. I struggle with (1d) because it seems hard to generalize and invites short circuiting ambiguities as discussed here. Fundamentally, I think if we want any variable arity operators we should make it a general facility and not try to desugar things. So for me, the real question is around a general purpose variable-arity operator. It would give us at least same-operator cases when handling comparisons, as well as lots of other use cases like streaming, concatenation, etc. It also makes the short circuiting and such very explicit and obvious (none). And the I'm mildly in favor of having this general facility and defining our binary operators in terms of variadics for this purpose as long as it doesn't slow us down. |
How would a general facility provide anything akin to |
Looks like Python short-circuits evaluation in that case: |
Actually that's what I expected from Python and that's what I would expect
from a language that is designed around performance.
…On Mon, Apr 26, 2021, 6:42 PM Richard Smith ***@***.***> wrote:
That said, I'm not sure how much anyone's intuition is trained on
expecting short circuiting in a < b < c!
Looks like Python short-circuits evaluation in that case: c is only
evaluated if a < b evaluates to True. But I'm not sure whether many
practicing Python programmers know this, let alone rely on it!
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#451 (comment)>,
or unsubscribe
<https:/notifications/unsubscribe-auth/ADUNHVYTARMPMLUMZEEE6JLTKYJADANCNFSM42Z77ZSA>
.
|
A slighty more tangential observation on maths and operators. Let me set the scene first. I was once convnicingly advised to write interval checks in "maths order", such as Now, a similar argument can be made in other relational situations. Therefore, one might well be tempted to reorder comparison statements according to such mathematical tastes. If there is short-circuiting among relational (!) operators, then such seemingly innocent, style-only edits potentially change the meaning of code. So, I think it's perfectly natural and "familiar" for logical operators to short-cicruit, but I find it rather novel and inventive for relational operators to do so. And it's not because it wouldn't be a good optimization/performance choice, but because I worry about requring readers to know about and preserve this! Or, in other words, short-circuiting relational operators would need strong justification in light of the Goal of "Familiarity for experienced C++ programmers". |
I think we've reached consensus on some of the questions here. Partial decision: The question regarding chained comparisons is still open. |
We triage inactive PRs and issues in order to make it easier to find active work. If this issue should remain active or becomes active again, please comment or remove the |
We triage inactive PRs and issues in order to make it easier to find active work. If this issue should remain active or becomes active again, please comment or remove the |
It seems we have in practice adopted 1B, for example in #702 . I recommend affirming that decision and closing this issue. |
Yep, leads have consensus on #451 (comment) |
In (at least) three cases, we may wish to consider treating traditionally infix binary operators as variable-arity operators. The cases are:
Options:
a) We pick a precedence and associativity rule, and compare the
Bool
result of one operator with the operand of another operator. [This is the traditional / C++ choice.]b) We treat these operators as being non-associative / having incomparable precedence, and reject these examples unless parentheses are added. [This is the current approach in #168.]
c) We treat comparison operators as being variable-arity (with the same operator), so the above are desugared into something like:
The third
if
statement would be ill-formed.d) We treat comparison operators as being variable-arity, and desugar them into chained binary operators, so the above are desugared into something like:
... except that the operands are each evaluated once before any comparisons are performed. [This is the Python choice.]
Note in particular that the variable-arity option is not the same as treating
<=
and friends as operators with a funny return type with a custom<=
operator. For example, these are not equivalent:We can consider allowing an unparenthesized comma expression to form a tuple, and thereby uniformly use parentheses only for grouping. For example:
Then
,
would be a variable-arity operator that forms tuples of arity >= 2.()
and(a,)
would be syntactic special cases that require parentheses.a) Don't do this; the parentheses are part of the tuple syntax. [This is the Haskell choice.]
b) Do this; the parentheses surrounding
(a, b, c)
are optional. [This is the Python choice.]There are multiple ways this could work:
a) This is two uses of a right-associative binary
=
operator. This code convertsz
to the type ofy
and stores toy
, then [loads fromy
and] converts the result to the type ofx
and stores tox
. [This is the traditional choice; C++ reloadsy
whereas C does not. This is also the current approach in #168.]b) This is ill-formed. We don't support chained assignment.
c) This is one use of a variable-arity
=
operator. The valuez
is stored to bothx
andy
. [This is the Python choice.]The text was updated successfully, but these errors were encountered: