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

add support for combinatory logic in data-if and data-else #17

Open
benzen opened this issue Jan 20, 2018 · 12 comments
Open

add support for combinatory logic in data-if and data-else #17

benzen opened this issue Jan 20, 2018 · 12 comments

Comments

@benzen
Copy link
Contributor

benzen commented Jan 20, 2018

In most template system i've used, if/else/unless operators support some way of combinatory logic.
Do you plan on supporting more complexe expression on data-if and data-else, or is it a choice ?

@caolan
Copy link
Owner

caolan commented Jan 20, 2018

It would be nice to have. I'd also like to compare variables / literals using something like if-equal.

Unfortunately, this could introduce a lot of complexity when building the server-side implementations, and Ideally I want to keep those simple enough that a developer could conceivable build one in a couple of weekends.

On the other hand, keeping the implementation simple pushes complexity out to either side (both in preparing the data for the template server-side, and in handling the events and re-rendering client-side). This means more code duplication in your web application. A smarter template syntax would reduce that.

There is a tension between these two objectives. I think we're still finding the right balance. I suggest we keep the simple syntax we have and highlight cases where it's causing code duplication. Then we should try to come up with the easiest to implement syntax that will solve those. I don't think we should build new syntax for combinatory logic or equality checks without a clear case of difficult to avoid code duplication.

@benzen
Copy link
Contributor Author

benzen commented Jan 20, 2018

Here is the exemple that made me think about this

<template data-tagname="todo-entry">
  <span data-if="todo.done">
    <span data-if="show-done-todos">
      <li>
        <p style="text-decoration: line-through" onclick="toggleDone(todo.id)" >
          {{todo.name}}
        </p>
      </li>
    </span>
  </span>
  <li data-unless="todo.done">
    <p onclick="toggleDone(todo.id)" >
      {{todo.name}}
    </p>
  </li>
</template>

Each todo item has a done flag.
Somewhere else there is also a checkbox that allow the user to show/hide the done todo.
So to show done todo i need to express something like todo.done && showDoneTodos

@benzen
Copy link
Contributor Author

benzen commented Jan 21, 2018

I can see three proposition.
1- Dont do anything more, in code. Juste recommend that thoses kind of computation are made previously into the state.
Eg.

{ 
  todos: [...],
  visibleTodos: [...],
  showDoneTodos: true
}

When the flag showDoneTodos change, we recompute the visible todos.
This way the computation is done outside of magery.
Of course it force the dev to implementation this data, manipulation two time.
In this case it's quite easy, maybe a more complexe case will be a a pain to implement two time.

Another proposition:
Allow data-if and data-unless to call function.

<app-todo data-if="isTodoVisible(todo.id)"></app-todo>

Thoses functions would be a third parameter to rendering (after data, and handlers).
Since thoses function would be called quite often, we can memoise them for performance reason.
It kind of match the purpose of reselect in the react eco-system, since this kind of function will only compute derived data from the state.
The list of function must be implemented both on server and on client by the user of magery.
But again we skip the implementation of support for combinatory logic.

And finally you sayed that implementing this kind of logic can make it a lot harder to implement a server side. But if we limit well enougth the set of operator (e.g. ! == && || and parenthesis) (like angularjs did) it should be quite easy to implement in most C familly language (javascript, c, java) which share most of these operator anyway. I've seen you're building a scheme implementation, maybe on a lisp it will be harder because of the distance between theses expression and the way it's expressed on a lisp.

Anyway, I would be happy to read you thought on this.

@benzen
Copy link
Contributor Author

benzen commented Jan 21, 2018

I still agree with you, we need a strong case before doing anything.
But I still think about this problem.

What if we expose a couple of simple function, like and() not() or(), eq() and those are the only function authorized.

This way it would be way easier to implement, we just need a simple set of function, and combine this with littéral and escaped varaible

@caolan
Copy link
Owner

caolan commented Jan 21, 2018

Ideally, I'd also like us to come up with a solution for if/else and if-equal (or similar). It's difficult to keep the syntax sane though. As you say, the combinatory logic is probably the easiest part.

@benzen
Copy link
Contributor Author

benzen commented Jan 23, 2018

Here is my proposition:
The data-if and data-unless expression become a predicate.
which is composed with only two type of data (which can be combined)

  • escaped varibales,
  • functions calls.

We don't allow any type of function. Just a limited set which are provided by the runtime module (the same that is called to extract value from data). That way we could quickly add new function, without making the compiler more and more complex.

The syntaxe is the normal js function call.
Here is the list of function I propose:

  • or()
  • an()
  • eq() (equality based on value)
  • not() only one argument
  • gt(), gteq(), lt(), lteq() (greater, greater or eq, less, less or eq)

maybe what can be added

  • number literral (integer and float)
  • string litteral

Usage of any other symbol will provoke a compilation error.

@benzen
Copy link
Contributor Author

benzen commented Feb 7, 2018

Why don't we use the hard work done by other.
Somehting like https://github.com/elgs/jsonql seams pretty close to what i'd like to be able to have inside of magery.

Let's say we have a jsonql implementation inside each magery implementation ?
This will keep the implementation of magery server side easy, as long as you have a jsonql implementation in your language.

I don't point you in the direction of this project in particular, just this kind of projet, maybe it's abandonned. I don't kown.
My point is only to define a external standard for the expression.

@caolan
Copy link
Owner

caolan commented Feb 8, 2018

Looking at existing implementations is a good idea and jsonql looks pretty nice. Even though it's more complicated to implement I have to say I like the traditional &&, || style operators.

@benzen
Copy link
Contributor Author

benzen commented Dec 23, 2018

It's been a year, but i still want to help on this one

I've started a projet https://github.com/benzen/simple-el-parser-test-suite.
Which may be a part of the magery regular test suite oneday.

My hope is to define a simple expression language that very implementation of magery could use.
I want to provide a parser for the language i can. I think the parsing module should only produce an ast. The magery runtime would then use this ast to produce a function using the data passed to the template.

Let me know if the Idea seems logical to you, and if the target AST would be suffisiant (as a starting point)

@benzen
Copy link
Contributor Author

benzen commented Jan 4, 2019

Also I've implmented a parser for this very simple expression language:
https://github.com/benzen/groovy-simple-el-parser

In my opinion it will be very straightforward to make an equivalent implementation in javascript

@caolan
Copy link
Owner

caolan commented Jan 4, 2019

This is looking nice. Not too complicated. It will be interesting to see how much code it adds to my python implementation. If it's complicated perhaps we could have it as an optional extra for server-side implementations.

@benzen
Copy link
Contributor Author

benzen commented Jan 4, 2019 via email

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

No branches or pull requests

2 participants