-
-
Notifications
You must be signed in to change notification settings - Fork 407
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
Adding Logical Operators to Templates #562
Adding Logical Operators to Templates #562
Conversation
|
||
## Unresolved questions | ||
|
||
- Consider following Javascript's definition of truthiness. This would also help with the transition from `ember-truth-helpers`. |
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.
Probably belongs under “Alternatives” 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'd argue that it belongs here. The way I understand RFCs, alternatives is where you list alternative options to implementing the RFC, not so much about doubts regarding what the best implementation is.
If anyone can confirm that I got it wrong, I'm happy to change it.
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 an exact implementation of ember-truth-helpers logical operators (except maybe not) is not what anyone wants, given the desire for short circuit logic. But alternatives sections are not always fully specced out, so I think with just a little more detail, you could write an alternative.
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.
Being someone who believes that the lack of logical operators is the main benefit that handlebars provides, and one who has never had a need to install this addon in the many ember apps i have built, simply assuming that this is something that is required to be installed does not sit well with me. I would like somewhere in this process to highlight the benefits that not having these be a part of the framework provides.
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.
@webark You can certainly live without those helpers, but I'll add some examples of things that are much nicer with helpers like those:
Default Values in template-only components
Imagine a template only component that wants to have a default value for say, @name
<img class="avatar" src={{or @user.avatar "/imgs/default-avatar.png">
Perform an operation on each iteration of a loop without extracting another component
{{#each @users as |user|}}
Name: {{user.name}}
{{#if (and session.hasAdminPrivileges user.inactive)}}
<button {{on "click" this.activate}}>Delete</button>
{{/if}}
{{/each}}
In both situation you can find a way to do the same things without using any of those helpers, but it involve either create a JS file for a component only to put a computed property on it, or to extract a new component to call it on each iteration of a loop, just to perform a very simple logical operation.
It's a matter of convenience and as any tool it can be abused, but the popularity of ember-truth-helpers proves that devs really find it convenient.
I think that Ember providing just the most basic and used ones (and
, or
, not
, eq
are the main 4 for me, but this RFC focuses on the first 3) and optimized at the VM level we are alleviating a pain.
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.
call me a curmudgeon (and i’ll postpone my “at this point we might as well be using jsx” rant for another day) I just feel it should be mentioned why this was never in core to begin with. Your examples, to me, are the base examples of why. Just a brief “handlebars was originally meant to be “logic-less” but it has grown, and the community has pushed it, past that for sometime now” blurb would be helpful, at least for a historical sense.
Co-Authored-By: Chris Krycho <[email protected]>
I think this needs more discussion in the other helpers, but for these particular helpers, we can't build short circuit versions without direct core support. Would it be possible to build some primitives to make short circuiting possible while keeping the helpers (and actual semantics) in an addon? |
@Gaurav0 I'll add it as a note, but even if it was possible and short-circuiting was possible in user-land, I still think those helpers are useful regardless of any optimization we may add, so I don't want to focus the RFC on the possible performance improvements. Probably on the big picture the perf improvements we may squeeze from short-circuiting will be rather small in anything but pretty contrived examples. |
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.
yes, please! 🙏
Co-Authored-By: Godfrey Chan <[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.
We discussed this at todays core team meeting, and the team broadly agreed with the detailed design here. However, we believe that we need to flesh out the how we teach this a bit more (I left an inline comment with some reasoning here). I think with some tweaks there to address that concern, we should be able to move forward here.
text/0000-add-logical-operators.md
Outdated
## How we teach this | ||
|
||
The introduction of these helpers does not impact the current mental model for Ember applications. | ||
|
||
In addition to API and Guides documentation with illustrative examples of usage of the various helpers, stressing out | ||
where the definition of truthiness of handlebars is different from the one in Javascript. |
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 we need to beef this section a bit more. Specifically, I do think this changes some of the mental models. For example, commonly we punt folks into JS-land instead of using ember-truth-helpers in the guides/tutorial (e.g. we might suggest using computed.not
). This would definitely change if we introduce these helpers.
@rwjblue I updated the How we teach section, check it out. |
Any updates on this? Given that the need for these helpers is quite ubiquitous I believe and trivial to implement (except for the short-circuiting maybe), advancing this RFC seems like a very low-hanging fruit to me! I would like to add one thing though: has another helper like <img class="avatar" src={{or @user.avatar "/imgs/default-avatar.png"}}> Tbh, I don't like this pattern that much, because
<Modal @open={{or @modalOpen true}}/> (The modal would always be open here, no matter what you pass as That's why I am so happy about the nullish coalescing ( Side node: you see I am not a fan of JavaScript's loose interpretation of boolean logic in general. Maybe because of the stronger mathematical education I enjoyed in school and university. I just find that boolean logic is soo easy to reason about when constrained to functions that take one or more booleans and return a boolean (truth tables!). As it was supposed to be! But JS semantics are obviously not going to change. But let's move on, and sorry for my slightly off-topic rant here! 😆 So I would propose to add something like You could argue that this can be added in its own RFC, however I would argue that once you add |
We chatted about this in todays core team meeting, and are in favor of moving forward here. One thing to call out explicitly, this RFC does not propose import paths (which helpers would require see the strict mode RFC for details). At the time of authoring, that distinction was not present (which is why it isn't discussed here), but after discussion with the core team we think that making these keywords (which do not need imports) is the correct path anyways (therefore no changes are required to the RFC). Additionally, landing this in Ember will require a small deprecation when using All of that being said, we are moving this into final comment period (finally 😉). |
Great. I think that making them keywords (so they don't have to be imported all the time) makes sense for such basic operators. Let's have it merged! |
The RFC proposes that The main motivation that I have seen for returning the value rather than a boolean is using I fear not returning a boolean from keywords called Let's assume a
A consumer would need to cast the value returned by |
@jelhan these are all wholly valid points… but they’re also fundamental to how JavaScript works, and one of the things I see quite consistently as a challenge for folks working with Glimmer/Handlebars templates vs. working in React, Svelte, etc. is the points where the semantics of these kinds of things differ. They're surprising, and needlessly so, at least in context. let value = 1 || false; // 1
let flipped = false || 1; // 1
let anded = 1 && 2; // 2
let flipThat = 2 && 1; // 2 etc. If we give function or([a, b]) {
return a || b;
});
export default<template>
<div>{{or @something this.someOtherValue}}</div>
</template> More/worse, there are times when you might need to switch from the built-ins to something slightly more complicated, and then you have to keep the differences in your head: refactoring from |
This is indeed not how it should be used and too complicated anyway. If you want strict Boolean values, you can just do |
The missing hole is |
@chriskrycho Thanks a lot for explaining the motivation. Wasn't clear to me that it should work as I guess definition of truthiness is only exception for consistency within the template? To avoid a situation in which |
Honestly, I think its a great idea to include all these by default but this is the same issue for me. Usually I add So that means I would still probably need to add it anyway and then this difference in behaviour...
I guess would change subtlety and so require some care not to introduce bugs after the install? |
Ya, that is being proposed in #560. Hopefully we can finalize our thoughts there (I made a comment explaining the current mental state of the core team recently) and release these two features roughly together. |
Extracted from RFC #388
Rendered