Skip to content
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

[Feat]: equality operators #1277

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

snewcomer
Copy link
Contributor

@snewcomer snewcomer commented Feb 28, 2021

RFC: emberjs/rfcs#560

  • eq
  • neq

Related pkg - https://github.com/jmurphyau/ember-truth-helpers/blob/master/addon/helpers/equal.js

  • These keyword helpers will only be enabled in strict mode.

Some outstanding questions:

  • Will loose mode will compile this keyword into a helper, calling the existing (addon such as ember-truth-helpers or other) if present. Should we add a deprecation at this point. feature flag strictOnly added
  • change neq to not-eq. Happy to open an another RFC or amendment to resolve. This would also align us and allow us to deprecate ember-truth-helpers as well.

Other upstream PRs to be merged first are here, starting with logical operators. - snewcomer#1 snewcomer#3

@rwjblue
Copy link
Member

rwjblue commented Feb 28, 2021

We need to determine who will "win" in the case a user has ember-truth-helpers installed as well

The resolved helper must win (we can't assume that a resolved helper named eq is from ember-truth-helpers and therefore make assumptions about its internal implementation), but I am not 100% we want to issue a deprecation in all cases where a helper is resolved from user land for one of these names.

and how to throw a deprecation warning.

RE: when to issue a deprecation: I think we would only want to issue a deprecation if our implementation returns a different result than the resolved helper version.

RE: how to issue a deprecation: there is a nice deprecation system already built out, you import the deprecate function from global context and then invoke it. Ember has a hook into those deprecations and can augment the deprecation options (e.g. to add for/since/until/etc).

@@ -34,7 +34,8 @@ class KeywordImpl<
constructor(
protected keyword: S,
type: KeywordType,
private delegate: KeywordDelegate<KeywordMatches[K], Param, Out>
private delegate: KeywordDelegate<KeywordMatches[K], Param, Out>,
private options?: { strictOnly: boolean }
Copy link
Contributor Author

@snewcomer snewcomer Apr 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't sure if this anonymous type was ok with you. (we could share an actual interface in multiple spots)

Comment on lines 9 to 19
function assertEqualKeyword(node: GenericKeywordNode): Result<ASTv2.PositionalArguments> {
let {
args: { named, positional },
} = node;

if (named && !named.isEmpty()) {
return Err(generateSyntaxError(`(eq) does not take any named arguments`, node.loc));
}

return Ok(positional);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we also need to assert if you use more than two positional arguments

https://github.com/emberjs/rfcs/blob/master/text/0560-add-equality-operators.md#eq

{{eq}}
Binary operation. Throws an error if not called with exactly two arguments. Equivalent of === This is identical to the eq helper in ember-truth-helpers

Comment on lines 39 to 49
function assertNotEqualKeyword(node: GenericKeywordNode): Result<ASTv2.PositionalArguments> {
let {
args: { named, positional },
} = node;

if (named && !named.isEmpty()) {
return Err(generateSyntaxError(`(neq) does not take any named arguments`, node.loc));
}

return Ok(positional);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to assert RE: more than two positional params

{{neq}}
Binary operation. Throws an error if not called with exactly two arguments. Equivalent of !== This is identical to the not-eq helper in ember-truth-helpers, except for the name.

Copy link
Member

@rwjblue rwjblue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


@test
['it works multiple arguments eq']() {
const AComponent = defineComponent({}, '{{eq 1 1 1}}');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is not supposed to work

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

emberjs/rfcs#560 (comment)

@rwjblue easy enough to support multiple I imagine. What do you think?

@snewcomer snewcomer requested a review from rwjblue April 27, 2021 19:18
@MelSumner
Copy link

What else does this PR need to land? I would love love love to see this land. <3 Thank you all for working on it!

@pzuraq
Copy link
Member

pzuraq commented Jul 30, 2021

@MelSumner part of the reason this has been blocked is because of v4 prep, we didn't want to land more changes in the VM before the last 3.x LTS was fully stable, in case we had to backport more fixes (there have been a few already).

Once that's done, I think the biggest issue is we need to actually change the way this is implemented so that in loose mode the resolved helpers win. That is a bit of a bigger change overall, because IIRC keywords always win in loose mode, so we need to implement these as "fallback helpers". I believe we were talking about doing both implementations, because ultimately we do want these to be keywords, and then having the compiler choose which one to use depending on whether or not the template was in loose mode. Also, the outstanding comments need to be addressed.

@MelSumner
Copy link

@pzuraq perfect, thanks for clarifying!

@snewcomer
Copy link
Contributor Author

snewcomer commented Aug 1, 2021

this is implemented so that in loose mode the resolved helpers win

It has been a while so I may have this wrong but I I think one workaround that we talked about and I put into this PR was a flag strictModeOnly. Then in ember.js, I would implement the flags again (for loose mode?). We can chat on Monday about it though!

RE: comments
I believe {{eq 1 1 1}} was asked for in a comment. But happy to change to two params. More than two is easy enough? - emberjs/rfcs#560 (comment)

@NullVoxPopuli
Copy link
Contributor

What's left here? It's been a couple months

@snewcomer
Copy link
Contributor Author

@NullVoxPopuli I believe nothing. I'm excited about this but I'll need some help from either @chancancode and/or @rwjblue to review. I've addressed the comments so far...

@NullVoxPopuli
Copy link
Contributor

I'll ping them

@snewcomer snewcomer mentioned this pull request Jan 29, 2022
5 tasks
@chancancode
Copy link
Contributor

@wycats has thoughts on the strict vs loose difference (he don't think it is correct that we should have to handle them differently). He'll comment later.

As for neq vs not-eq, that was already considered during the RFC and I would not be inclined to reopen it yet again, especially if we are looking to expedite things.

Regarding >2 arguments for eq, I don't have a problem with it personally, but landing the error now following the RFC and removing it later wouldn't be a breaking change either, that would be the easy thing to do. But since this is already implemented someone could also go ahead an open an amendment PR and try to get it through pretty quickly. Either way is fine with me.

@NullVoxPopuli
Copy link
Contributor

does anything need to be done?
can this be merged?

@snewcomer
Copy link
Contributor Author

Sounds like we have a few steps.

  1. Just to note, there is a leaf PR that would need to be merged - [Feat]: logical keywords snewcomer/glimmer-vm#3. I could merge them all down to this branch if we are generally comfortable with the implementation. Sounds like we might be but...
  2. Pending wycats comments
  3. And adding an error for > 2 arguments seems like a safe approach. I'd be happy to add that to this PR unless somebody has a strong feeling.

@chancancode
Copy link
Contributor

And adding an error for > 2 arguments seems like a safe approach. I'd be happy to add that to this PR unless somebody has a strong feeling.

Sounds good to me, pretty easy to change/fix later

@snewcomer
Copy link
Contributor Author

This has been updated with strict 2 arguments to eq and neq!

Copy link
Contributor

@bertdeblock bertdeblock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking forward to this 👍

return Err(
generateSyntaxError(
`(eq) must receive two positional parameters. Received ${
positional?.size ?? 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
positional?.size ?? 0
positional.size ?? 0

Since we already do positional.size on line 18?

return Err(
generateSyntaxError(
`(neq) must receive two positional parameters. Received ${
positional?.size ?? 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
positional?.size ?? 0
positional.size ?? 0

Since we already do positional.size on line 59?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants