-
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
Conditional expressions #911
Conditional expressions #911
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reworked how we handle symmetrizing; there is now both a not-necessarily-symmetric interface and a guaranteed-symmetric constraint.
Co-authored-by: josh11b <[email protected]>
Co-authored-by: josh11b <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here are a few preliminary comments. I'm going to look at this again in more detail since it looks a bit complicated at the moment, particularly the implicit conversion stuff.
Co-authored-by: josh11b <[email protected]>
Co-authored-by: josh11b <[email protected]>
appear. Don't allow `if` expressions as operands of any operator, as if they are themselves a very low precedence operator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of random drive-by comments and digging into one thread. Will try to do more thorough pass soon.
The converted _condition_ is evaluated. If it evaluates to `true`, then the | ||
converted _value1_ is evaluated and its value is the result of the expression. | ||
Otherwise, the converted _value2_ is evaluated and its value is the result of | ||
the expression. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find the phrasing "[t]he converted expression is evaluated" a bit awkward or confusing... The conversion happens after the evaluation?
Maybe phrase this as _condition_ is evaluated and then implicitly converted to bool.
... Dunno, its awkward. But I think it would be good to make it unambiguous that the conversion happens after evaluation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a distinction between operationally thinking of conversion as something you do to a value, and denotationally thinking of it as something you do to an expression. In the language of https://github.com/carbon-language/carbon-lang/tree/trunk/docs/design/expressions#conversions-and-casts, we take the latter view: implicit conversion is a process applied to an expression of one type to produce an expression of another type, as part of type-checking. As such, it happens before any evaluation is considered: first we transform cond
into cond.(ImplicitAs(bool).Convert)()
as part of type-checking, to form the converted condition expression, and then later whenever we evaluate the if
expresssion, we evaluate that converted condition expression. (And similarly for the value1
and value2
: type-checking converts those, and during evaluation we evaluate the converted version of whichever expression we select.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think my challenge as a reader is that the phrase "a converted X is evaluated ..." is very ambiguous between "an X of the 'converted' kind is evaluated" and "after converting X, it is evaluated". They both seem quite plausible interpretations, and there are contexts in which either one would make more sense, and so I often end up confused which one is the one I should be using.
Maybe as a follow-up both here and in the "Conversions and Casts" section the language could switch to some construct that is less ambiguous when read if that makes sense (and such a formulation could be found)?
To be clear, this isn't blocking anything, just a lingering confusion for me as a reader.
proposals/p0911.md
Outdated
Another way of viewing this is that `if` is a very low-precedence form of | ||
expression, and is lower precedence than is permitted in an expression-statement | ||
-- that is, as the "operand" of a `;`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW I find this more confusing than clarifying -- if
has a higher precedence than parentheses and commas, so this perspective would imply that we don't allow tuple expressions or paren expressions to be expression-statements, which I don't think is (or should be) the case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The inside and outside of parentheses (and grammar constructs involving commas) will typically be different precedence levels, which I think is probably part of the confusion here. A parenthesized expression lives at a very high precedence level, so it can be used pretty much anywhere, but the context of the inside of it is a very low precedence context, so pretty much anything can appear within it. (I would predict that we won't have a C++-like comma operator, but I suppose only time will tell.)
But... given that this attempted clarification isn't helping, I'll just remove it.
- Don't specify how to convert the condition of an `if` expression; just defer to whatever `if` statements do. - Remove attempted clarification of `if` expression positioning in terms of precedence, since it seems to be more confusing than helpful.
Given the current direction for #821, it doesn't seem to be necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me. I have a few small comments, but they are not blocking concerns, just small cleanups to the text.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very simple language feature that turns out (for good reasons) to be quite difficult and require an impressive amount of care and detail. Really amazing proposal walking through all of it and navigating the tradeoffs.
I've left a bunch if pending comments, but these is only one real change that I think is just clarifying something. The rest are totally optional readability tweaks. Happy for this to go in with these addressed or skipped, whatever makes sense. Thanks (and huge thanks to all the other reviews here to get this into such good shape).
The converted _condition_ is evaluated. If it evaluates to `true`, then the | ||
converted _value1_ is evaluated and its value is the result of the expression. | ||
Otherwise, the converted _value2_ is evaluated and its value is the result of | ||
the expression. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think my challenge as a reader is that the phrase "a converted X is evaluated ..." is very ambiguous between "an X of the 'converted' kind is evaluated" and "after converting X, it is evaluated". They both seem quite plausible interpretations, and there are contexts in which either one would make more sense, and so I often end up confused which one is the one I should be using.
Maybe as a follow-up both here and in the "Conversions and Casts" section the language could switch to some construct that is less ambiguous when read if that makes sense (and such a formulation could be found)?
To be clear, this isn't blocking anything, just a lingering confusion for me as a reader.
This proposal introduces a conditional operator of the form: ``` if cond then value1 else value2 ``` Co-authored-by: josh11b <[email protected]> Co-authored-by: Chandler Carruth <[email protected]>
This proposal introduces a conditional operator of the form: