TomFrost / Jexl

Javascript Expression Language: Powerful context-based expression parser and evaluator
MIT License
573 stars 93 forks source link

Defining functions? #43

Closed mercmobily closed 4 years ago

mercmobily commented 6 years ago

Is there any way to define functions in Jexl? Thank you for the hard work!

TomFrost commented 5 years ago

Hi @mercmobily! Apologies for the late response.

At this point, no functions can be defined from within a Jexl expression. I've been constantly revisiting the line of how powerful Jexl should be, and at the moment, that line is "Jexl is for safe expression evaluation, and is not meant to be Turing-complete". If you need a scripting language that allows functions to be defined and called, that's what Javascript is ;-)

With that said, functions can be pre-defined as transforms, and there are two outstanding feature request that I'm still chewing on. One is related to allowing functions to be passed to the expression in the context and called directly, and the other is related to allowing short lambda functions to be defined inline for the purposes of filtering/mapping/reducing. If you share more about your use case, that could assist my decision!

mercmobily commented 5 years ago

Our use case was allowing software customisation -- to a pretty extreme point. The user wants to be able to write calculators for tariffs; these calculators can be pretty wild and need to be effectively coded. They are basically functions that receive a "job" object as input, and work out (for example) the berthing fee for that job based on that job's information (port, tonnage, etc.)

I used to use evals, but -- since these calculators are run on the server -- you can clearly see the security implications if a hacker manages to write records on the DB.

I ended up using this: https://github.com/NeilFraser/JS-Interpreter (sorry, I don't mean to be disrespectful, feel free to ask me to edit the link out).

I would have preferred jexl though, especially because you seem to provide much better error reports.

I hope this helps!

TomFrost commented 4 years ago

It's been a long time coming, but functions support is working in the functions branch. No docs there yet, but it works exactly as you might expect:

jexl.addFunction('hello', (arg) => `Hello, ${arg}!`)
jexl.evalSync('hello("world")') // "Hello, world!"

Getting this documented and teed up for the next release!

TomFrost commented 4 years ago

Actually just realized this is a dupe -- closing in favor of #25 .