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

$boolean(arg) when arg is no-match #433

Closed
andrwo opened this issue Apr 17, 2020 · 7 comments · Fixed by #437
Closed

$boolean(arg) when arg is no-match #433

andrwo opened this issue Apr 17, 2020 · 7 comments · Fixed by #437

Comments

@andrwo
Copy link

andrwo commented Apr 17, 2020

Just a query. I wanted something that returns "true" if a arg path evaluates to truthy, and "false" if falsey or not found (no match).

data:

{
  "_formValues": {
    "test": true
  }
}

Jsonata expressiosn:

$not(_formValues.test) returns false
$not(_formValues.test2) returns true

But:

$boolean(_formValues.test) returns true
$boolean(_formValues.test2) returns *no match*

I found it a bit inconsistent that a $boolean(arg) can return *no match*. Should it be returning false instead when hit against a no match? Or perhaps someone can explain why this is perfectly good and logical :)

Using: Jsonata 1.8.2 (as in the exerciser)

@andrwo andrwo changed the title $boolean(arg) on no-match arg is no-match $boolean(arg) when arg is no-match Apr 17, 2020
@jhorbulyk
Copy link
Contributor

I wanted something that returns "true" if a arg path evaluates to truthy, and "false" if falsey or not found (no match).

Using a double not (e.g. $not($not((expression))) is usually how this is done in most programing languages.

I found it a bit inconsistent that a $boolean(arg) can return no match. Should it be returning false instead when hit against a no match? Or perhaps someone can explain why this is perfectly good and logical :)

Most JSONata functions are designed so that when evaluated against an unset/undefined value, they also return unset/undefined. $not() and $exists() are two major exceptions. The function $boolean() follows this pattern. Potentially we should also add $boolean() to this list.

@andrwo
Copy link
Author

andrwo commented Apr 18, 2020

Ok thanks for your reply. I guess then it will be consistent with Jsonata behaviour of other coercive (typecast) functions like $string(undefined) = undefined and $number(undefined) = undefined. Though I would think it is better for coercive functions to be coercive also on undefined. In Javascript, Boolean(undefined) evaluates to false (though technically that is a Boolean constructor and so should behave that way).

At the very least, the (already excellent, I must add) documentation should be updated to add to note that $boolean( undefined ) = undefined, and $not ( undefined ) = true.

@andrew-coleman
Copy link
Member

Hmm, I think you're right, there is an inconsistency here. I think that $not() should return the empty sequence (no match/undefined) for non existent input in the same way as every other function (except $exists() which is explicitly testing for the existence of the input).

@twosdai
Copy link

twosdai commented Apr 24, 2020

I think this introduces a breaking change with how the sift function is working correct me if I am wrong.

Since before the change we can write something like:

$sift(
                λ($v,$k) {
                    $not($k ~> /^lineItem|^packages/ )
                }
            )

And now we need to have an additional check:

$sift(
                λ($v,$k) {
                    $not($k ~> /^lineItem|^packages/ ? true: false)
                }
            )

I am also making the assumption that jsonata is following semantic versioning conventions.

@andrew-coleman
Copy link
Member

Sorry this is breaking your expression, but I consider the previous inconsistent behaviour of the $not function with undefined inputs to be a bug, and so was fixed in a patch release.
In general I try to keep the language as stable as possible, but there have been a few cases (like this) where I have fixed up behavioural 'edge cases' for improved consistency. In your example, you were relying on this behaviour and subsequently have to change your code. Apologies for that!

@twosdai
Copy link

twosdai commented Apr 28, 2020

Thanks for the response! Just wanted to make sure you were aware of some of the differences.

@andrew-coleman
Copy link
Member

Thanks. I'd probably remove the $not from your expression and use this:

$sift(  λ($v,$k) { $k ~> /^lineItem|^packages/ ? false: true }  )

Alkarex added a commit to alexandrainst/node-red-contrib-json-multi-schema that referenced this issue Jun 19, 2020
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 a pull request may close this issue.

4 participants