Skip to content

Would you be interested in collaborating to develop a JSON Logic Specification? #34

Description

@TotalTechGeek

Hey @Viicos,

I stumbled across your implementation of JSON Logic and saw that it had some recent active development!

I'm trying to reach out to maintainers of JSON Logic implementations to try to consolidate differences, and perhaps collaborate to develop a more cohesive specification.

For example, I noticed that your project implements var differently. Honestly not a bad idea, though I'm a bit nervous about it not being backwards compatible.

EDIT - I think there might be an error in the Resolving variables documentation, and your proposal might be perfect. Assuming / refers to the 2 in { "": 2 }.

I wanted to reach out and see if you'd be interested in being a part of a community effort to try to reconcile some of the differences between JSON Logic implementations, and put together a more comprehensive specification and test suite?

I maintain json-logic-engine (JavaScript), and I'm currently communicating with the authors of datalogic-rs (Rust) and json-everything's (.NET) implementation of json-logic.


EDIT - I figured I'd also throw in my two cents about how I handled the variable resolution & scope.

JLE and some other modules implemented escaping from dot-prop notation to try to maintain backwards compatibility.

If there's a variable with a dot in it, we escape it with \, so someone can write { var: 'hello\\.world' } to escape the separator.

To access an empty string { "": 1 }, you can use { var: '.' }, and if you needed to access { "": { "": 2 } }, you'd use { "var": ".." }.

If you needed to access { ".": 3 } you'd use { var: "\\." }. Admittedly, it is a little awkward and less ideal than an existing RFC, but is backwards compatible with the implementation most engines use.

To handle scopes in iterators, JLE's approach was to implement Handlebars style data traversal.

So let's assume your data is stored as { x: 5 }

Let's say you wanted to add each element of an array to the x value, and to the index of the iterator, you'd write:

{ 
  map: [
      [1,2,3], 
      { '+': [{ var: '' }, { var: '../index' }, { var: '../../x' }] }
   ]
}

Anyway, this isn't an attempt to prescribe a solution -- I believe that the fact that folks have tried to identify different solutions indicates the need for discussion and a more rigid specification


Examples of issues I think need discussed & spec'd:

  • Data: How do you access { '': 1 }?
  • Data: How do you access { 'hello.world': 1 }
  • Truthiness: straightforward, but a compat table might be helpful
  • How do you handle { "!": [0] } vs { "!": 0 } -- this one is more straightforward; but a common compat issue.
  • How do you handle { "!": { "var": "data" } } where data resolves to [0], is it treated like [[0]] or [0]?
  • How do you access context in iterators? {filter: [{var: 'arr'}, {'===': [{var: 'item'}, {var: '../../choice'}]}]}; explanation: In most implementations, you're unable to access above context in your iterator, so you can't use data to add numbers together, or filter things out.
  • .length, should var in JSON Logic have a dedicated handle to allow a user to fetch .length if the property does not exist on the object naturally? This makes logic incompatible in between interpreters; so should .length be treated as a special path, or be given a reserved operator 😉

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions