-
-
Notifications
You must be signed in to change notification settings - Fork 408
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
Update Glimmer Template Truthiness Semantics #861
base: master
Are you sure you want to change the base?
Conversation
Modify title Co-authored-by: Chris Krycho <[email protected]>
I'm confused, is this connected to this issue? Isn't updating these semantics going to break billions of apps? |
|
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.
Looks great overall. Beyond my comments, I think there's a bit more minor editing work than can be done, mainly around consistent capitalization of JavaScript and TypeScript.
Co-authored-by: Peter Wagenet <[email protected]>
Co-authored-by: Peter Wagenet <[email protected]>
Co-authored-by: Peter Wagenet <[email protected]>
We talked a little bit about this at a high level at the Framework team meeting today (everyone is excited), and I'll review it early next week with the input from that! |
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.
Thanks a lot for this RFC! I'm very much in favor of following native JavaScript more closely.
### Migration Plan | ||
1. Ship comparison helpers `and`, `or`, `not` with existing equality and truthiness semantics (they currently match `if` and `unless` truthiness semantics) | ||
2. Ship types which match that and document why they work they way they do. Acknowledge that this wont work for TS users in they way they would expect and why. | ||
3. Ship ability to opt into new behavior for `and`, `or`, `not`, `if` and `unless` (Following JS truthiness semantics) |
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.
How would that opt-in look like? Would be great if you could do more in detail for the migration story in general.
Takes at least two positional arguments. Raises an error if invoked with less than two arguments. It evaluates arguments left to right, returning the first one that is truthy (by javascript's definition of truthiness) or the right-most argument if all evaluate to falsy. This is equivalent to the {{or}} helper from ember-truth-helpers. Doing this would allow `{{or}}` to compile down to `||` and give us the correct type safety and narrowing that users would expect. | ||
|
||
### {{not}} | ||
Unary operator. Raises an error if invoked with more than one positional argument. If the given value evaluates to a truthy value (by javscript's definition of truthiness), the false is returned. If the given value evaluates to a falsy value (by javascript's definition of truthiness) then it returns true. This is equivalent to the {{not}} helper from ember-truth-helpers. Doing this would allow `{{not}}` to compile down to `!` and give us the correct type safety and narrowing that users would expect. |
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.
Should {{not}}
also error when invoked with no arguments?
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.
Not that this means anything, but according to the original RFC no? https://rfcs.emberjs.com/id/0562-add-logical-operators.
But that does bring about the question of what they were expecting to happen in that case? In my opinion, it would make sense to error there.
Edit: After playing around in a console I might have changed my mind. !undefined
= true. And since we want to keep the semantics equal to Javascript - it might make sense to return true in this 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.
Maybe still strange? I'm unsure. We definitely should support {{not undefined}}
but I'm not sure about {{not}}
.
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 would tend to not throw if invoked without arguments ({{(not)}}
). But from typing perspective the argument should be required. And we might want to have a linting rule forbidding argumentless {{(not)}}
.
I don't see much value in throwing. Implementation complexity should be the same. But we should use types and linting to push people towards {{false}}
instead.
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 like @jelhan's solution here.
Co-authored-by: Jon Johnson <[email protected]>
Co-authored-by: Bert De Block <[email protected]>
Co-authored-by: Bert De Block <[email protected]>
Co-authored-by: Bert De Block <[email protected]>
Template truthiness tweaks
We should discuss what it takes for us to accept this at the next RFC Review. |
Two main bits of feedback:
I have to say, I've been working in Glint quite a lot already and I've yet to hit a realistic example where this semantic gap actually came up. I would be curious to see people's examples. That doesn't mean I don't care about closing it, but I do think it's relevant to how we teach this and how we prioritize the migration. |
The places it's likely to come up are exceptionally rare, but likely to be very annoying for people when they do happen, just insofar as they're a case where TS/Glint tells you they're safe and then you get a runtime error from it. Implicit in @ef4's comment is that Glint does let folks opt in (and our docs will better reflect that hopefully this week!). That said, using a JS-expression-syntax would also solve this, and has the possibility a clear and straightforward opt-in at a template authoring level (e.g. a |
We should hash through this at the next feature design meting. |
Rendered
Provide a path for Glimmer templates to switch away from classic Handlebars truthiness to JavaScript’s truthiness. This will align our templating language with users' expectations and make teaching easier. It will also allow TypeScript features like type narrowing to work as users would expect it to with keywords like
{{and}}
or{{or}}
.