[HN Gopher] JsonLogic
___________________________________________________________________
JsonLogic
Author : sebmellen
Score : 186 points
Date : 2021-05-27 18:16 UTC (4 hours ago)
(HTM) web link (jsonlogic.com)
(TXT) w3m dump (jsonlogic.com)
| millerm wrote:
| Seems like a really silly lisp with string operators and is
| incredibly hard to read when not trivial. This will probably be
| the first and last time I ever ask this question, but why not
| just use something like clojurescript?
| joshlemer wrote:
| ClojureScript does not complete in a deterministic amount of
| time, on account of it being a turing-complete programming
| language.
| eevilspock wrote:
| Thank you. I'm going to take a look at this for the project I
| mentioned in my other comment.
| [deleted]
| sebmellen wrote:
| I'm trying to define a matrix for the conditions under which a
| given "credential" can be accepted/is valid. The goal is to
| embed that matrix within the credential schema itself, such
| that it's almost self-verifying, depending on the context of
| the credential's usage/presentation. (A bit hard to explain
| without diagrams.)
|
| Using JSON to do this would allow schema portability throughout
| the different languages in our stack, but of course it's an
| imperfect solution. Open to hearing any other options (I have
| looked into YAML as well but that's a whole other ball of
| wax)...
| renewiltord wrote:
| I might be misunderstanding, of course, but would you be able
| to use the JSON protobuf serializers and just define your
| conditions as Protocol Buffers?
|
| Might be heavyweight.
| jimsimmons wrote:
| This is not a bad idea. But coupling with protocol buffers
| is an issue and JSON doesn't have a standardised way to
| parse expressions
| sebmellen wrote:
| I think it's best to direct your attention here as the
| comment is rather lengthy and takes up a lot of vertical
| space: https://news.ycombinator.com/item?id=27307631.
| mixedCase wrote:
| S-expressions do all of this, which is why everyone is
| suggesting you've reinvented Lisp. They're trivial to parse
| and easier to read than JSON for this use case.
| sebmellen wrote:
| The problem with s-expressions is that you can't include
| them within an already extant JSON schema.
| eevilspock wrote:
| Essentially JSON s-expressions.
|
| I'm doing something similar in a side-project of mine as a
| temporary stop-gap to avoid writing (or generating) a parser for
| a proper s-expression syntax.
| rendall wrote:
| For some reason, this project seems to be drawing rather nasty
| comments. I'd like to remind everyone of the guidelines:
|
| _Be kind. Don 't be snarky...
|
| Please don't post shallow dismissals, especially of other
| people's work. A good critical comment teaches us something._
| commandlinefan wrote:
| "This is a bad idea" is neither nasty nor snarky.
| ktpsns wrote:
| And this is how LISP is invented.
|
| _Any sufficiently complicated program contains an ad hoc,
| informally-specified, bug-ridden, slow implementation of half of
| Common Lisp._ (Greenspun 's tenth rule)
| pydry wrote:
| It's Turing incomplete. Like HTML.
|
| LISP is, on the other hand, a programming language. It's rather
| famous for it.
| [deleted]
| adamkl wrote:
| Here's some great instructions on how to use JSON to do just
| that:
|
| https://stopa.io/post/265
| joshlemer wrote:
| Are there any competing dialects of Lisp which have
| deterministic runtime? If people are reimplementing half of
| Common Lisp, then they are not implementing something that
| competes with this project because their language is probably
| turing complete. From the JsonLogic website:
|
| > JsonLogic has no setters, no loops, no functions or gotos.
| One rule leads to one decision, with no side effects and
| deterministic computation time.
| jsd1982 wrote:
| The logo is pretty clever
| sheminusminus wrote:
| At Routable we use this to power a significant portion of our
| dynamic UI (super complex forms with interwoven dependencies,
| etc). Super cool and useful library with a surprisingly low
| number of gotchas for what it's doing.
|
| We did a little write-up about our experience with it here if
| anybody is interested:
|
| https://blog.routable.com/tablematic-a-tale-of-server-driven...
| sebmellen wrote:
| Thank you, this kind of real-world experience and feedback is
| exactly what I was looking for when making this post! I will
| take a read through that blog :).
| AcerbicZero wrote:
| I am firmly on team "anything but YAML" so perhaps I'll give this
| a try next chance I get.
| dvt wrote:
| This is a fun project and a cute reinvention of Lisp, as people
| have already mentioned. I think people are snarky because if this
| was just a fun project, that would be the end of it. But it seems
| like JsonLogic is trying to be an actual _thing_.
|
| And this latter point is why it's just a monumentally terrible
| idea. I mean.. just look at the Custom Operations wiki[1]. It's
| honestly just horrible -- _horrible_ -- and may actually even
| summon Zalgo[2]. This is exactly how we ended up with the XML
| nightmare of the late 90s /early 2000s. JSON is not meant to be
| programmable. Please, for the love of all that is holy, stop.
|
| [1] https://github.com/jwadhams/json-logic-js/wiki/Custom-
| Operat...
|
| [2] https://stackoverflow.com/a/1732454/243613
| vesinisa wrote:
| > Please, for the love of all that is holy, stop.
|
| Yes! Oh my god, this. I remember how XML ended up being abused
| to express Turing complete logic in too many instances. Then
| they even specified an XML format to transform other XML
| documents, called XSLT, which is itself Turing complete. It
| really makes my head hurt.
|
| I think why people gravitated away from XML was because it had
| become a convoluted mess. The JSON specification is terse on
| purpose, famously enough so to fit on a business card. If you
| want to abuse JSON to express logic, please keep it as your
| dirty little secret.
| Lapsa wrote:
| eval("temp < 110 && pie.filling == 'apple'")
| code-is-code wrote:
| I also did this some year ago. A big learning was that you should
| define the allowed input types in the logic object.
|
| https://github.com/pubkey/secure-json-logic#readme
| sebmellen wrote:
| Thanks for the input. I submitted this because I'm looking
| around for ways to define a matrix for accepting a given
| "credential" within the schema of the credential itself -- a
| bit hard to explain without getting into it. This is the best
| model I've found so far to do what I'm trying to do, but it's
| still very imperfect.
| ctoth wrote:
| This project reminds me quite a bit of [0] which I'm currently
| using to write rules to parse tags from Openstreetmap. Having a
| standard way to share expressions does seem quite useful,
| especially when it's multilingual.
|
| [0]: https://github.com/google/cel-spec
| sebmellen wrote:
| Very nice, had not heard of this before. I will take a close
| and careful look.
| remram wrote:
| What is the advantage of this being JSON? Couldn't the language
| be _more_ "terse, consistent, secure, and flexible" if it wasn't
| JSON, with the possible advantage of parsing faster and being
| friendlier to write?
|
| The website lists the ability to easily send it "between front-
| end and back-end code, and even store it in a database", is there
| an advantage to it being JSON for any of these goals?
| pjerem wrote:
| We blindly use JSON for everything because one day, someone
| discovered that JavaScript embedded a JSON parser called
| eval(). Yup, that's where our civilization is.
| skybrian wrote:
| Programmers are already familiar with the surface syntax,
| including gotchas like only having doubles.
|
| Also, the logic can be embedded in an already-existing JSON
| file.
|
| This is useful if you occasionally need to look at the file,
| but usually you don't, so it's not worth putting any more
| effort into nice tooling.
| IshKebab wrote:
| Ha they heard of "truthy" and "false" but apparently stopped
| reading before "... are a really really terrible idea!".
| mcphage wrote:
| What's terrible about truthy and falsy? How do you even have a
| language without a definition of what is truthy and what is
| falsy?
| coldtea wrote:
| There are several languages that only allow booleans in such
| comparisons.
|
| There you can't do e.g. a bare: if (a)
|
| for things that e.g. in C/Java etc would be "truphy" (like 0,
| null, etc). Instead you need to do: if (a !=
| null)
|
| (that is, check with an expression that returns an actual
| boolean true or false, not anything truthy/falsy that
| "coerces" to true/false).
|
| In the same way, where in Python you'd do: a
| = "" if not a: print "this will be printed"
|
| there you'd do it like: if not (a == "") --
| or if not a.isEmpty(): ...
|
| or some such.
| mcphage wrote:
| Sure, but then "truthy" for that language is just true, and
| "falsy" is just false. It's still relevant to understand
| the concept of "what is considered true, and what is
| considered false", even if the answer is simple for certain
| langauges.
| nsonha wrote:
| it's only a matter of time before you are called gatekeeper
| because "json is a programming language"
|
| I remember when I was an university student thinking writing java
| in XML (Spring) was cool. Man I was dumb.
| telekid wrote:
| That's a strange lisp...
|
| A few other strategies for solving this problem include something
| along the lines of the Small Clojure Interpreter (1) and
| Defunctionalization (2, 3)
|
| [1] https://github.com/borkdude/sci
|
| [2] https://blog.sigplan.org/2019/12/30/defunctionalization-
| ever...
|
| [3]
| https://www.cis.upenn.edu/~plclub/blog/2020-05-15-Defunction...
| joshlemer wrote:
| The difference between this and a full lisp like Clojure is
| that this must be turing-incomplete. From the description:
|
| >JsonLogic has no setters, no loops, no functions or gotos. One
| rule leads to one decision, with no side effects and
| deterministic computation time.
|
| Also it appears that sci is still experimental: "Experimental.
| Breaking changes are expected to happen at this phase. "
| lootsauce wrote:
| There are legitimate uses for such things. We are currently
| implementing a processing rules configurator UI and backend that
| must ultimately be executed in sql. It must support arbitrary
| nested boolean logic and comparison expressions. Last time we did
| this we ended up developing a custom data structure for the
| front-end and a custom printer for the sql output. This is a
| standardized version of solving just that problem.
|
| My question is if not a solution like this how then SHOULD I be
| implementing communication of such rules from the frontend to the
| backend?
| dec0dedab0de wrote:
| I can see using this for writing validators that can be written
| once, then ran on the api and frontend. I'm struggling to think
| of another use.
| ekimekim wrote:
| The niche that immediately came to mind when I saw this was
| allowing a user to specify a filter expression for some query,
| either as a simple text-based language or using some sort of UI
| (with drop-downs and such). Having a well-established spec with
| existing libraries for turning these kinds of expressions into
| an AST for transfer, storage, execution later, etc is valuable.
| I've definitely implemented a simplified, domain-specific
| version of this kind of thing in various projects over the
| years.
| rendall wrote:
| sebmellen, I looked at its repo and it's just the license? Am I
| missing something?
| sebmellen wrote:
| Just to be clear -- not my project, but I'm trying to use this
| or something like it. I found it pretty compelling though also
| somewhat lacking, and HN is a great place to get more
| discussion and maybe read about some alternatives :)
| diegoholiveira wrote:
| I did a rules engine to the company that I work based in this
| specification, but using go language. It is a very successful
| project because our clients can create rules without tech people
| around in our frontend, it's very easy to translate our rules
| into json and store it.
|
| I even did a library to implement it in go language:
| https://github.com/diegoholiveira/jsonlogic
| bww wrote:
| The idea of representing an expression as an abstract syntax tree
| for interchange is not an inherently bad idea. Trying to shoehorn
| a general purpose data interchange format into a highly
| specialized application like that is a common anti-pattern,
| however.
|
| When I see this sort of thing (which I assume was inspired by
| MongoDB's own atrocious "query language") I'm always surprised by
| the fact that many engineers don't seem to be aware of how easy
| it is to write a parser that is actually designed for the data
| you're trying to represent. At least "easy" in the context of
| undertaking a project that is attempting to generalize this exact
| problem.
|
| JSON is a fine interchange format until you need a specialized
| runtime to evaluate the data, which is what is happening here. At
| that point there's zero benefit to using a general purpose
| interchange format just because it already exists: just write a
| DSL.
|
| A good place to start: https://www.antlr.org/
| kemitchell wrote:
| This has been independently reinvented countless times, in
| countless languages. Would be nice to get a somewhat generalized
| standard in place.
| bob1029 wrote:
| We do something almost like this, but we didn't try to invent
| any of the hard bits. We serialize our domain instances into
| JSON documents which also happen to contain the business rules
| as in-line SQL properties, and then project this JSON document
| into SQL databases as required for evaluating business logic.
|
| Ephemeral, in-memory instances of SQLite can be incredibly
| powerful tools for building an extensible business logic
| engine.
| idolaspecus wrote:
| Could you expand on this idea a bit more? My curiosity has
| been piqued, but I'm not sure I really understand the system
| you've described.
| bob1029 wrote:
| The combining of JSON & SQL is mostly inconsequential here.
| It is just a convenience for sending things in 1 file vs
| multiple.
|
| The big takeaway is that SQL is a really great tool for
| exposing any sort of customizable logic over arbitrary
| datsets.
|
| The only major caveat with this - You will typically have
| to perform some degree of transformation over source data
| in order to achieve a form of normalization well-suited to
| the writing of business logic (SQL). Assumptions (i.e.
| denormalizations beyond 3NF [0]) made in your schema here
| will inevitably hamper or kill the ability of the business
| to write flexible queries which can satisfy real-world
| needs. Today, a customer may have multiple accounts. In a
| few years, maybe we decide it goes the other way too. If
| you made an assumption, such as nesting these complex types
| in any way whatsoever, you are probably stuck with a
| steaming bag of shit that you now have to refactor and
| retest top-to-bottom. Using relation types to decouple
| nested complex types is the core tenant in my mind.
| Identity is foundation, but you can fudge your way around
| that a little bit.
|
| This one caveat is why a lot of developers look at this
| idea as a bad one at face-value. It takes a lot of work &
| iterations with the business stakeholders to get this
| correct. You can't sit in a silo and expect to completely
| figure out the abstract nature of business types or learn
| how they might be related and in what ways. There really is
| a "correct" and "incorrect" way to go about it if you are
| being properly academic. Worry about webscale and
| performance later. Get it correct first. Nothing is too
| complex for a SQL schema.
|
| If you can satisfy the academic gods of normalization and
| achieve a stable schema, then you are in for a wonderful
| ride. Between using views to compose higher-order
| functions, and UDFs [1] to wire into customized SQL
| functions, you can satisfy literally any degree of
| complexity required by the business. The only limit is your
| ability and discipline around modeling the domain types &
| relations, and willingness to get your hands dirty with
| some views and functions. You will find your business
| experts loving the power they gain by being able to write
| queries in a domain specific language they inherently
| understand. Giving them higher-order functions (views) and
| iterating on that side of the fence is yet another gigantic
| value play that is invisible if you are looking anywhere
| other than SQL. [0]:
| https://en.wikipedia.org/wiki/Third_normal_form [1]:
| https://www.sqlite.org/appfunc.html
| idolaspecus wrote:
| Thanks for the detailed response!
| TeMPOraL wrote:
| It's called, "use a Lisp, dammit!".
|
| Seriously. There are Lisp languages that could replace whatever
| language you're using, and, there are also Lisp
| languages/runtimes that you could _embed_ in whatever language
| you 're using, to avoid rewriting it from scratch like this.
| skybrian wrote:
| Which lisp though? There are still too many choices.
|
| The fact that people say "use a lisp" instead of "use Lisp X
| like everyone else" should tell you something.
|
| It's like the difference between "use SQL" and "use SQLite"
| or "use Postgres."
| TeMPOraL wrote:
| > _Which lisp though?_
|
| Whichever works best for your particular constraints.
|
| > _It 's like the difference between "use SQL" and "use
| SQLite" or "use Postgres."_
|
| Precisely! "Use Postgres" is a valid answer to the
| question, "which database should I use?", or "which
| relational database should I use?". And "use SQL" is a
| valid recommendation when you see someone reinventing
| relational data model and reimplementing a relational
| database without realizing it.
|
| Similarly, "use a Lisp" is a valid recommendation when you
| see someone reinventing programming using trees from first
| principles - of which a telltale sign is reinventing
| s-expressions.
| joshlemer wrote:
| A lot of shallow, smug snark coming into the comments section
| from people who know what s-expressions are and I guess want to
| brag about that for some reason. S expressions are cool but
| that's just _a syntax_, there are other possible syntaxes for
| expressions, and it's perfectly fine that somebody chooses to
| embed a language in JSON rather than s-expressions. Everyone
| suggesting to use Scheme or Clojure or Common Lisp and dropping
| the meme-quote that everyone eventually reimplements Lisp are
| missing the fact that this language is designed to be evaluated
| deterministically, so it does not support looping or functions
| and is Turing-Incomplete, unlike Clojure/Scheme/CommonLisp.
| tgbugs wrote:
| They may be shallow comments, but they have a point. JSON is
| fundamentally unsuitable for anything numerical for a variety
| of reasons [0]. Thus, it actually can't ever even get to the
| point of being a suitable replacement for expressions in the
| languages you listed. Most web tech has insidious anti-
| intellectual designed baked in, and the end result is that
| people end up rolling their own mutually incompatible bespoke
| solutions to problems that were solved before the web was even
| a glimmer in the eyes of the advertising industry.
|
| 0. https://stackoverflow.com/questions/1423081/json-left-out-
| in...
| ironmagma wrote:
| > Most web tech has insidious anti-intellectual designed
| baked in
|
| Citation? I don't know many people who would call Brendan
| Eich anti-intellectual for instance.
| shawnz wrote:
| With s-expressions where that functionality is simply not
| provided as part of the underlying syntax at all, then every
| solution is a mutually incompatible bespoke solution. You
| could just use all string values in JSON and get the same
| effect.
| whalesalad wrote:
| Ultimately it's all data. The difference between this and lisp
| is just a bunch of extra characters and noise in the stream.
|
| What is really the meaningful difference between this and an
| s-expression language? "" and {}, really. It's a different way
| to serialize the same thing.
|
| So I'd argue a lot of the criticism is valid.
|
| We do, as an industry, tend to run in circles.
| forgotmypw17 wrote:
| I think it's just a natural law that information tends to
| "crystallize" into certain patterns, and we're just the
| implementors of those repeating patterns. :)
| joshuamorton wrote:
| https://github.com/joshuamorton/tidbits/blob/master/lispy.py.
| ..
| sebmellen wrote:
| The most important difference to me is that this is usable
| within already extant JSON Schemas that can be patched up or
| added to.
| athrowaway3z wrote:
| I remember years ago when i first came to hackernews there
| was a project very similar to this. An engineer blog proud of
| the AST they encoded as JSON.
|
| I had only a vague idea of what an AST was, but the highest
| upvoted comment was clearly saying: This is dumb, we have
| dedicated formats for turning text into ASTs. ( i.e. a
| programming language ).
|
| In the past decade+? i have learned what an AST is and have
| now twice, in a professional setting, prevented an engineer
| from re-inventing this very concept.
|
| If i had to choose if hackernews is a place where smug snark
| comments crack down on re-inventing known concepts or a happy
| place where every idea is a good one i will choose the
| former.
|
| And once every blue moon we get to laugh and look back at
| snarky comments such as this:
| https://news.ycombinator.com/item?id=9224
| samatman wrote:
| I don't understand this at all.
|
| JSON is a serialization format. So say you have an in-
| memory AST, and you want to serialize it: why not use JSON?
|
| If you don't want or need to serialize it, then of course
| don't use JSON. I can make up plenty of other reasons not
| to, but they're variations on some other format being
| better for the application, not JSON being inadequate in
| any way. I'd probably use JSON myself, and I don't care for
| it much.
|
| Or are we talking about building up an AST in JSON
| _directly_ rather than taking some parser output and
| serializing it? Ok that 's... not an AST then, it's a
| programming language with JSON compatible syntax, and yes I
| would try and prevent that from getting implemented as
| well.
| incrudible wrote:
| Yes, we have programming languages. Lots of them. Most are
| distinguished by what you can do with them. Few are
| distinguished by what you can _not_ do with them.
|
| This is one of the few projects addressing the latter
| problem space.
| brundolf wrote:
| The difference is the collection of extremely powerful
| parsers, tooling, language support, etc that already exist
| for this syntax. There's a proper Content-Type header,
| blazing-fast native parsing in web apps, you could store it
| directly in MongoDB or the like without an extra
| serialization/parse step, you could query it with jq. Heck,
| you could statically-check these expressions using
| TypeScript.
|
| Lispers are always pointing out how the parenthesis-and-
| whitespace notation is just incidental; how s-expressions are
| really something deeper that isn't bound to a specific
| syntax, and how this is a strength. The OP is a
| _demonstration_ of that strength.
| pydry wrote:
| >What is really the meaningful difference between this and an
| s-expression language?
|
| Turing completeness.
|
| >So I'd argue a lot of the criticism is valid.
|
| I'd argue they should have paid more attention in college.
| This is far from a superficial difference.
|
| You might as well call HTML a programming language.
| Seriously.
| rvense wrote:
| >>What is really the meaningful difference between this and
| an s-expression language?
|
| >Turing completeness.
|
| S-expressions in and of themselves are obviously not Turing
| complete. This language could easily have been encoded in
| S-expressions, just like Lisp can be encoded as JSON.
| (Like, trivially, as lists with quoted strings instead of
| atoms, or using whatever object-based syntax.)
| pydry wrote:
| Well, the most famous example most definitely is.
|
| There's thousands of ways this could have been encoded.
| Why that one specifically?
| remram wrote:
| Correct me if I'm wrong, but not every s-expression
| language is Turing-complete, you need the ability to define
| functions which is not a given. This project doesn't have
| functions (or loops) seemingly on purpose (and their
| addition would make this weird language just as Turing-
| complete).
| [deleted]
| [deleted]
| yongjik wrote:
| I think comparison to s-expressions are a red herring. In Lisp,
| I guess, s-expressions are an integral part of how you code. As
| a piece of general code, it can be great or terrible. This
| "JsonLogic" thing is explicitly intended to be "logic-inside-
| configuration" because (I hope) nobody's writing program with
| JsonLogic. Unfortunately, logic inside configuration is almost
| always a bad idea. (It doesn't matter whether you're using json
| or xml or s-expressions.)
| brundolf wrote:
| Don't most of the problems with "logic-inside-configuration"
| come from turing-completeness? This spec has neither control-
| flow nor reusable functions (recursion); it's nothing but
| simple expressions. That seems safe to me.
| eevilspock wrote:
| Here's the thing: I implemented exactly this for a side project
| where I needed users to be able to express simple logic for
| custom data handling rules. Here are some examples:
| level = new Expression(['map', ['char', ['tail', 2], 0], {'=':
| 1, '-': 2}]) body = new Expression(['parse', ['trim',
| ['body']]]) name = new Expression(['replace', ['trim',
| ['body', 1]], /[ \t\r\n]+/, ' ']) target = new
| Expression(['first', ['body', 2], ['body', 3], ''])
|
| The arg to `new Expression` is a Javascript object (i.e. can be
| sourced from JSON). The first element in each nested array is a
| function name/operator. It was absolutely trivial to implement.
| All the functions are implemented in a few lines of code within
| cases of a switch statement, and nested expressions are handled
| recursively.
|
| For me this is just a temporary throwaway solution while I work
| on other more critical stuff first. I will replace it with an
| s-expression based DSL later. Like JSONLogic, it won't be
| Turing complete.
|
| It just seems to me that JSONLogic is making a huge deal for
| what's really just a small reusable library.
| brundolf wrote:
| Mapbox's API has something similar, except they use the first
| element in an array for the operator instead of an object key:
| https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions/
|
| Some will recognize that these are basically just Lisp
| s-expressions (as JsonLogic also seems to pretty much be)
|
| "Code as data" indeed
| lloydatkinson wrote:
| Is this a recent project? Anything using that ancient theme
| looks... ancient.
| codeulike wrote:
| https://en.wikipedia.org/wiki/Inner-platform_effect
|
| That said, I think everything has uses in some circumstances;
| there are no rules in software that are beyond debate
| imoverclocked wrote:
| I get it. I do ... it still rubs me the wrong way because:
|
| 1) You are leveraging a JSON parser to get strings 2) The strings
| contain tokens that need to be "parsed" 3) You turn this double-
| parse into an AST
|
| I see this pattern all too often. If you create (or re-use an
| existing) grammar that is specific to the problem domain then you
| get a much faster parse, smaller data transfer/storage, and a
| more human-readable format.
| dan-robertson wrote:
| This sort of rule language you can put in configs is often
| useful. They tend to eventually cause problems as logic that
| should have been implemented properly gets embedded in the mini
| language and the little rules get more and more complicated (or
| even auto-generated from a simpler specification), but they are
| invaluable while they do work.
|
| One thing that surprised me was the inclusion of map/reduce/cat.
| Allowing these operators can make runtime exponential in the size
| of the program. I feel like that is against the spirit of the
| language.
| mcphage wrote:
| I don't understand why they represent it as a object with a
| single key, whose value is an array:
|
| - If it's an object, then nothing is going to enforce there only
| being one key.
|
| - If it's a unary operator, then the value doesn't need to be
| wrapped in an array, but then how does it distinguish between an
| unary operator, whose operand is an array, vs. an n-ary operator?
|
| Both of these problems would be solved by having each clause be
| an array, with the first value being the operator, and the rest
| of the operands being the parameters. That way having multiple
| operators isn't even syntactically possible, and having multiple
| operands is just as simple as the unary operand case.
| flying_sheep wrote:
| IMHO coding logic in JSON is similar to puzzle game. I would
| recommend to use jq instead.
| daenz wrote:
| Like wasm, the idea of portable logic is interesting.
|
| Unlike wasm, this is the wrong vehicle for it. And this
| implementation's very-limited nature means that anyone who buys
| into it will need to rip it out when the limited logic inevitably
| doesn't scale with the rest of their applications.
| forgetfulness wrote:
| Since you can't expand rules into any other rules, yes, it's
| pretty restricted. Kind of a feature though.
| gloryless wrote:
| There are a ton of scenarios where this would be useful. Not
| everything has to be the new paradigm shift. It's just a tool
| erulabs wrote:
| Probably not appropriate for a large poly-glot organization, but
| I really like creating shared JS libraries that can be used in
| the browser and also in Node.js apps. For game development,
| having the game logic in a shared library makes server-side
| validation and client-side prediction really easy and prevents
| code duplication.
|
| I'm sure there is some reason it's all a horrible idea but almost
| all my projects these days use React front-ends and Node.js back-
| ends and a shared library used by both, ideally containing most
| of the complex logic. This seems like a neat version of that that
| might be useful in an organization which uses many different
| languages.
| closeparen wrote:
| We are quite successfully using Starlark for an embeddable,
| executable config language. For example, I can take a Starlark
| expression at the command line and use it to filter elements of a
| collection.
|
| https://github.com/bazelbuild/starlark
| orasis wrote:
| This is almost always a bad idea. It's best to find a way to use
| a full blown programming language for these types of
| customization.
| geuis wrote:
| Could someone explain why this or similar projects are useful?
| fomojola wrote:
| It is a DSL for additional logic that can be: - Stored in your
| existing data store (assuming your data store can store a
| string) - Executed without eval() or any other potentially
| dangerous method - Executed in bounded time
|
| You think of things like Lua in Redis: this is one take on a
| not-quite-as-capable alternative for logic that can be safely
| executed in restricted environments (barring errors in the
| implementation of the parser).
|
| There will be editing/verification requirements: writing any
| moderately complex logic structure without a designer/test
| evaluator would be a nightmare, but as a generic way to
| specify/embed custom logic in a system that is language
| independent, has effectively no additional parser requirements
| (given that just about every single language has a JSON parser
| that is probably already in use in your project) it isn't a
| completely bad look. S-expression parsers do exist, but I'd
| wager many more people are familiar with the JSON parser in
| their language than the S-expression parser available in their
| language.
|
| I will say: it isn't complete. It lacks clarity about the
| behavior in the face of missing/invalid operation arguments.
| Something like {"<" : ["ham", 42]}
|
| I'd assume would throw an evaluation exception of some kind,
| but that should be clear in the spec.
|
| The playground at https://jsonlogic.com/play.html is a start,
| but before you try handing this to a non-developer, you'd
| really want a visual editor with node folding of some kind (so
| you can hide deeply nested structures away while you work on
| other things), variable completion (so you specify a sample
| data object and if you're typing in a variable you get
| completion options) and operator parameter verification (to
| stop you from writing in incorrect/unsupported values based on
| the operator).
| coldtea wrote:
| For defining (and allowing users to touch) more powerful than
| static configuration and/or business logic, that you don't want
| to be turing complete.
| karambir wrote:
| We used this at an early version of ad-network where Advertisers
| would write JsonLogic against a set of user properties with all
| the operators. And this was checked at runtime when ad was to be
| shown. At the time, I thought this was a neat and quick way to
| give advertisers some form of targeting. We had ~500 active ad
| campaigns at any given time(not much growth beyond that) and this
| worked really great.
|
| But I always thought there should be better way for this kind of
| application. I see a lot of comments about Lisp. My question is:
| Is Lisp better for above scenario or there is even better way?
| spankalee wrote:
| I think avoiding a parser by using JSON is kind of neat, but it
| really isn't that difficult to write a parser for a small
| expression language and you get the benefit that you can expose a
| much nicer syntax to end users with the same parser - rather than
| having an standard AST and need a parser anyway to have decent
| UX.
|
| I work on and off on a very simple syntax language for things
| like templates, but would be well suited towards business rules
| and such too. It was the first parser I wrote outside of school
| and pretty easy to understand, small and fast too:
| https://www.npmjs.com/package/jexpr
| mmaug wrote:
| Congrats! You've invented a verbose version of LISP...
| garren wrote:
| It reminds me of this [0] post from a few months back which
| implements something more or less similar using js arrays as a
| kind of sexp.
|
| I'm working with a system that relies extensively on logic
| implemented as json structures. We're not using this lib, I found
| it to be difficult to follow and more difficult to debug. Ymmv,
| but I'd definitely think hard before leaning on something like
| this.
|
| [0] https://stopa.io/post/265
| shadeslayer_ wrote:
| Not to be _that_ guy but didn 't we agree about moving business
| all business logic into a single place, back in 2012?
| atatatat wrote:
| What if I use this as a read-only API of sorts for sending
| regular reports from a Blazor app db to legacy systems?
| mplanchard wrote:
| We built a rust version of this that provides a Python package
| via CFFI and a node package via WASM, because we found that the
| different implementations for different languages were pretty
| buggy and would sometimes resolve expressions differently. Also
| the original project in JS seems to be largely unmaintained. The
| rust version goes to great lengths to reimplement weird JS
| typecasting so as to be fully compatible with the original.
|
| https://github.com/Bestowinc/json-logic-rs
|
| I am currently working on an extension to add functions and more
| strongly typed operators to avoid the hassle of JS' type
| conversion. That extension will probably be released as a
| separate package, because I am no longer with Bestow.
| goodpoint wrote:
| > rust version of this that provides a Python package via CFFI
| and a node package via WASM
|
| I honestly thought it was parody around the unnecessary
| complexity of modern software.
| sebmellen wrote:
| Wow, awesome. Thank you! Just the kind of thing I'm looking for
| :)
| ar-nelson wrote:
| I've been trying to invent a JSON-Lisp language like this for a
| long time. My first attempt was Jaspr (https://github.com/ar-
| nelson/jaspr), which has its own syntax that compiles to JSON.
| But I'm working on a new, Turing-incomplete variant called
| MiniJaspr that fills a similar niche to config languages like
| Jsonnet or Dhall.
| beaconstudios wrote:
| if you're wanting to reuse the same logic on both backend and
| frontend, you can just use JS on the frontend and backend and
| pull your functions/utilities in from a shared library - either a
| git submodule, private NPM package or (my preference) have all
| three running inside a yarn workspaces monorepo.
| weatherlight wrote:
| man, I implemented a rules engine library where i expressed, the
| rules as S-Expressions (basically a lisp) that mapped to ruby
| lambdas. that way when finance would come back and be like, "what
| was the logic and the rules at a given point of time, I could
| point to what the rule was, what was it configuration, and who
| changed the configuration or the rule." and the rule execution
| strategy. It works, I'm proud of it, the lisp layer is completely
| abstracted away from the developers and the users who configur ed
| the rule.
|
| I thought I was so clever :) Apparently, engineers have a habit
| of doing this.
| natn wrote:
| I built something like this once for defining form validation
| rules. It was fun. I was very proud of it. I'd probably just use
| JSONSchema now though.
| asah wrote:
| please no. just no.
| devit wrote:
| That seems worse than using the common C/Java/JavaScript syntax
| for operators and function calls, that can be easily parsed with
| any JavaScript parser.
| ardit33 wrote:
| And the circle of life continues! I have seen exactly this method
| in 2004-2006 but with XML.
|
| If you are reading this, and you think it is a good idea, please
| don't follow it as it is not.
|
| Back in 2006-2009 I worked at MobiTV, which we had the same exact
| way/method of programing our mobile apps, on J2ME/feature phones.
| The made up language was called CEF which was based on XML. While
| the idea is sound in paper, This turns really fast into an ugly,
| debug everywhere type of scenario, where it is hard to both
| develop and debug properly.
|
| The only way this is ok, is when you have some fully automated UI
| tool, that stores some kind of state, and retrieves it back, but
| with no human intervention and some very very limited logic.
| Otherwise you are in a world of pain. If you try to include real
| application logic into something like this it is going to hurt
| your business long term.
|
| It will turn your business logic like some Maven configuration,
| full of gotchas and more.
| sebmellen wrote:
| Maybe you can tell me if there's a better solution. I'm open to
| hearing any options because I'm at a loss of how to do this
| otherwise:
|
| Say we have a schema which defines certain data. Let's say it's
| a "credential" which is a "COVID-19 Back to Work Credential."
| The credential is valid in the case that someone either 1) has
| a COVID vaccination _or_ 2) has a negative COVID test in the
| past 72 hours. That data might look like this:
| { "credentialName": "COVID-19 Back to Work Credential",
| "credentialIssuer": "Acme Labs Inc.", "credentialData":
| { "rapidSarsCov2PCRTest": {
| "hasTestResult": true, "testResult": "negative",
| "testTime": 1622145851 },
| "covid19Vaccination": { "hasVaccination": false
| } } }
|
| Now, say I want to define the conditions under which this
| "credential" is valid or invalid, but I want to include this
| "matrix" within the schema (not any business logic, just matrix
| logic that pertains to the data _within the schema itself_ ).
|
| Optimally, I'd be able to do this within the same schema or
| file.
|
| With JsonLogic, that might look like this (probably flawed
| logic, just a demo, not using this in production, may cause
| your computer to go up in flames, etc.): {
| ... "parsingMatrix": { "if": [
| { "or": [ {
| "===": [ { "var":
| "credentialData.rapidSarsCov2PCRTest.testResult" },
| "negative" ] },
| { "===": [ { "var":
| "credentialData.covid19Vaccination.hasVaccination" },
| true ] } ]
| }, "valid", "invalid" ]
| } }
|
| Can you think of another way to do this that doesn't rely on
| using JsonLogic or something like it (or a cleaner method for
| doing it in JSON)?
| goto11 wrote:
| How about representing the logic as a JavaScript expression:
| (credentialData.rapidSarsCov2PCRTest.testResult==='negative')
| || credentialData.covid19Vaccination.hasVaccination)
| ? 'valid' : 'invalid'
|
| Seem easier to read and maintain to me.
| sebmellen wrote:
| I'd love to do this, the only problem there is we're
| sharing this data between systems which use different
| runtimes. A client who runs a Python environment might not
| easily be able to make use of that logic. With JsonLogic,
| that would theoretically be possible.
| goto11 wrote:
| You can easily write a parser for this in Python. As long
| as you only support expressions it should be pretty
| straightforward.
| sebmellen wrote:
| I see your angle. I'll consider this. Thanks for the
| ideas!
| adamkl wrote:
| I posted this in another thread, but it seems relevant to
| what you are looking for: https://stopa.io/post/265
|
| It walks through the process of building a Lisp in JSON
| and the associated parser in JavaScript. It could be a
| good starting point to build out a cross-platform
| approach to sending logic over the wire.
| sebmellen wrote:
| Nice, looks quite neat. I'll dive into it a bit deeper!
| chousuke wrote:
| I can't help but think that at the end of this road is
| yet another Lisp waiting to be discovered.
| contravariant wrote:
| What about: ["if", ["or", ["===", ["var",
| "credentialData.rapidSarsCov2PCRTest.testResult" ],
| "negative"], ["===", ["var",
| "credentialData.covid19Vaccination.hasVaccination"], true
| ] ], "valid", "invalid"]
| ?
| sebmellen wrote:
| That's nice, I like it! We don't really need anything more
| than this.
|
| It's hard to gauge whether or not it's better to go with an
| existing, possibly inferior standard, or to create a new
| one, like this...
|
| https://xkcd.com/927/
| contravariant wrote:
| I mean it is just lisp denoted in javascript lists, but
| sure we can call it a new standard if you like.
| sebmellen wrote:
| If this works out we'll either be adopting a previous
| standard or defining a new one for these evaluation
| matrices!
|
| But yes, does look like other people have grazed this
| idea as well: https://www.i-programmer.info/programming/j
| avascript/2380-ja....
| mmcdermott wrote:
| Clojure Spec works really well for this sort of thing. It
| doesn't serialize to JSON, but it would be able to check for
| it.
|
| You could also think about Dhall as a front-end. You could
| represent the whole credential as a union type. This isn't
| deeply thought out, but this should give an idea as to how
| this would look: let TestResult = <
| Positive | Negative > let ScreeningTestDetails =
| { hasTestResult : Bool, testResult : TestResult, testTime :
| Natural } let CredentialData = <
| Vaccinated | RapidSarsCov2PCRTest : ScreeningTestDetails >
| let Credential = { credentialName : Text
| , credentialIssuer : Text , credentialData :
| CredentialData } let result
| : Credential = { credentialName = "COVID-19 Back
| to Work Credential" , credentialIssuer = "Acme
| Labs Inc." , credentialData =
| CredentialData.Vaccinated } let
| result2 : Credential = {
| credentialName = "COVID-19 Back to Work Credential"
| , credentialIssuer = "Acme Labs Inc." ,
| credentialData =
| CredentialData.RapidSarsCov2PCRTest {
| hasTestResult = True , testResult =
| TestResult.Negative , testTime =
| 1622145851 } }
| let prop0 = l(x : ScreeningTestDetails) -
| assert : greaterThan x.testTime 1522145851 [?] True
| in result2
|
| Notice here that the type for credential data can only be
| vaccinated or a test result. It can't even represent
| unvaccinated. You could probably take it farther with
| dependent types and assertions.
|
| Edit: added an assertion to model the 72 hour requirement.
| 0xFACEFEED wrote:
| Straw man.
|
| With all due respect, you're making a classic mistake:
| presenting the solution to a problem without tracing the
| problem back to the use case.
|
| Why do you need to include the logic matrix in the schema? I
| can promise you that the real world use cases where you'd
| need to this are virtually non-existent. You wouldn't even do
| this for some extreme case like Mars rover software.
|
| Your business logic should have a single source of truth. The
| vast majority of the time you can just write an API for other
| software to synchronize with.
|
| Otherwise just ship new builds of your software package to
| the client instead of a new schema. If you need to be modular
| then use modular primitives such as shared libraries.
|
| Again, there's virtually no real world scenario where you
| need to ship a _logic schema_ (in any format) to a client.
| You might as well ship a shared library, importable module, a
| completely new binary, etc, etc.
| sebmellen wrote:
| Interoperability is the main reason. We need this data and
| the evaluation matrix to be portable across different
| "credential wallets" as part of a standard model for matrix
| evaluation of Verifiable Credentials (as an extension that
| we're working on to the existing data model
| https://www.w3.org/TR/vc-data-model/).
| 0xFACEFEED wrote:
| You didn't state the use case initially. The context of
| the discussion is evaluating the value of the approach.
| What I'm saying is that you can't make that evaluation
| without stating the use case. Obviously one can think up
| a scenario where JsonLogic can be useful - that doesn't
| mean anything.
|
| > Interoperability is the main reason. We need this data
| and the evaluation matrix to be portable across different
| "credential wallets" as part of a standard model for
| matrix evaluation of Verifiable Credentials (see also
| https://www.w3.org/TR/vc-data-model/).
|
| Representing verification logic in the schema flawed.
| Just because the W3C publishes a spec doesn't make it
| good.
|
| So I guess one of the few valid use cases for JsonLogic
| (or similar) is if your company makes a bad technical
| decision and you're forced to implement _something_?
| asah wrote:
| I'm not sure how to express how much I loathe everything
| about this "solution."
|
| To answer your question, what you have is (effectively) code,
| and just use a programming language for this, call it a
| function, give it a name, arguments, test suite and register
| it as a plugin to your platform. Oh, and documentation,
| change history, etc.
|
| Seriously - the "overhead" more than pays for itself when 100
| other yahoos do this nonsense and you end up with data files
| containing untestable code that breaks when combined with
| other code, breaks when the platform is changed, etc etc
| sebmellen wrote:
| Ok, I take your point, but let's say we need to share these
| credential objects between different systems that do not
| have prior knowledge of how to evaluate the credential
| data. Also, let's say we constrain the logic to only allow
| for evaluation of any given part of the credential data
| against a binary "pass | fail" matrix.
|
| What is a better way to share this important part of the
| schema (the matrix) without resorting to letting the
| "business logic" perform the evaluation? Optimally, any
| matrix should be able to run against the same business
| logic for evaluation.
|
| Also, though I understand why you say that, we won't have
| "100 other yahoos doing this nonsense," and each schema
| would go through a pretty thorough review process.
| omegaworks wrote:
| If your business logic doesn't meet the needs of your
| business without the schema, the schema is a part of your
| business logic, that should be subjected to a suite of
| automated tests.
|
| If your concern is the sharability, consider making a
| library or service that provides the business logic.
| sebmellen wrote:
| We'd like to be able to include evaluation matrices
| within credentials as an extension to the _Verifiable
| Credentials_ standard (see https://www.w3.org/TR/vc-data-
| model/). Optimally, different libraries and different
| services will be able to evaluate a credential using the
| credential's included matrix (i.e. the evaluation matrix
| should not be reliant on any business logic from any
| particular party). I can't get too deep into the use-case
| but having these parts bundled together is important for
| what we're working on.
| [deleted]
| mvaliente2001 wrote:
| Sometimes you need to embed an expression interpreter in
| your application, for example to allow users to define them
| at runtime. In cases like that one, having a library with a
| well defined specification could save a lot of time.
| 0xFACEFEED wrote:
| It's much more likely that the library would do more harm
| than good.
|
| Libraries tend to cover broader spectrum of use cases
| than you'd need. Usually that's okay (eg: URL parsing,
| string manipulation, HTTP client, etc) but in cases like
| this the logic schema should be as absolutely minimal as
| possible.
|
| If you're building an interpreter and need an
| interchangeable format then you can always generate that
| out of your own bespoke and very constrained format.
| shaunxcode wrote:
| I cant help but imagine what it would like like in EDN:
| {... parsingMatrix (if (or (=== (var
| "credentialData.rapidSarsCov2PCRTest.testresult")
| "negative") (=== (var
| "credentialData.covid19Vaccination.hasVaccination")
| true)) "valid" "invalid")}
| sebmellen wrote:
| I presume jsedn is your library [0]? I was heretofore
| unaware of EDN, but it looks like a very clean fit for our
| needs. I will examine this more in depth, thank you.
|
| [0]: https://github.com/shaunxcode/jsedn
| enriquto wrote:
| > exactly this method in 2004-2006 but with XML.
|
| Of course! JSON is the modern equivalent of XML. In 10 years
| everybody will mock JSON just like today we mock XML.
| juped wrote:
| JSON mania has given me an appreciation for XML not having
| been so bad after all.
| jchw wrote:
| I like JSON a lot more than XML for what JSON is used for.
| XML did have some advantages, like more standards for
| schemas and templating, but the JSON ecosystem has at least
| decent facsimiles for these facilities. But the real star
| of the show is the data model: XML is a _markup language_.
| Jamming data structures into it is awkward. Not so for
| JSON, which has two aggregate types, a list type and a map
| type, followed by the usual suspects of primitive types:
| string, number, boolean, null.
|
| I can implement a full, strict, compliant JSON parser in an
| afternoon, maybe even less time. It is simple enough to
| parse that you can even do it in pure C with relative ease.
| XML is a lot more complex and a lot of implementations
| skimped pretty hard on the details. I mean I have fond
| memories of tinyxml2, and if you take apart any app made in
| the 2000s you have a good chance of finding reference to it
| (or on Windows-only apps, MSXML3, or on Linux, libxml...)
| but it certainly let you do a lot of surprising things. I
| saw a lot of apps doing XML documents with multiple root
| nodes. And Apple's plist format is a nightmare. It's so
| easy to fuck up interpreting XML plist, that Apple did, and
| it lead to one of the more entertaining privilege
| escalation bugs in iOS history.
|
| I have some fond memories, but I just don't miss XML. :)
| dnautics wrote:
| I dunno, to me it's pretty clear that JSON has improvements
| over XML; XML:
|
| - does not entirely make it clear what should go into a tag
| attribute versus a nested tag
|
| - conversion of those two features into a unified internal
| datatype can be tricky (for example, this property led to
| choices that for erlang's xmerl causes a security
| regression if you are handling user-submitted xml).
|
| - first class support for text inside of a tag is not what
| you want in 90% of data interchange events, and support for
| it creates a burden when deserializing.
|
| - it's confusing what should be a text inside a tag versus
| a tag attribute. Or should that text be parsed into a
| number? At least JSON is strongly typed, you know what
| datatype is what just by looking at it.
|
| - because there aren't good "best practices" around it,
| everyone rolls their XML schemas with their own ideas about
| what sort of thing should go where.
|
| The major benefit of XML is its obession with
| schematization means that at least in many case you can
| grab a schema and figure out an appropriate declarative
| command to obtain what you want (if you have the right
| library), but this has basically been conquered in JSONland
| using JsonSchema/OpenAPI, and stuff like JsonLogic.
| nly wrote:
| JSON can't express ordering or duplicate fields in a
| consistent way.
|
| Consider how you'd write these 2 bits of XML in JSON:
|
| <A><B>foo</B><C>bar</C></A>
|
| vs.
|
| <A><B>too</B><C>bar</C><B>uh oh</B></A>
|
| Without a schema, in the first case, how do you determine
| whether B should be "foo" or ["foo"]? In the second how
| do you preserve the relative ordering of B #1, C and B
| #2?
|
| I worked on a project where we had a parse tree that we
| wanted to serialize out, and for this reason XML was the
| natural choice.
| dnautics wrote:
| So this is exactly a symptom of unclarity of the roles
| that xml causes in the first place. It seems like You're
| tying using the tags as keys instead of as information
| _categories_. In json you would make this something like
| (pardon my lack of quotes, I 'm on mobile):
| {type: a, of:[{text: too, type: b}, {text: bar, type:
| c}]}}
| picometer wrote:
| { "a": [ { "b": "foo" }, { "c": "bar" } ] }
|
| vs.
|
| { "a": [ { "b": "too" }, { "c": "bar" }, { "b": "uh oh" }
| ] }
| nly wrote:
| Yes, so in essence:
|
| - Only ever have a single key in each JSON object
| (treating them as tuples)
|
| - Make all object values arrays.
|
| It makes for some very unnatural looking JSON.
| bokchoi wrote:
| > - it's confusing what should be a text inside a tag
| versus a tag attribute. Or should that text be parsed
| into a number? At least JSON is strongly typed, you know
| what datatype is what just by looking at it.
|
| JSON's types are pretty anemic compared to the
| XMLSchema's datatypes[0]. Even it you don't use all of
| XSD's complex type system, having these basic datatypes
| is extremely useful and I wish JSON had similar.
|
| [0] https://www.w3.org/TR/xmlschema11-2/
| legulere wrote:
| - JSON just has UTF-8. XML has encoding madness.
|
| - JSON has just one escape format and all unicode
| codepoints can be used. XML generally allows only certain
| unicode codepoints, at some places like element names its
| further restricted (Quick: Which characters are not
| allowed? What's the difference between XML 1.0 and 1.1
| here?). XML escapes at every place differently. In
| comments you need to escape less than elsewhere. In
| attributes you can use newlines but they will get
| normalized to spaces, you have to hex-encode newlines.
| There's Cdata.
|
| - JSON doesn't have the entity madness with potential
| security issues.
|
| - JSON doesn't have namespaces that add a lot of
| complexity with little benefit
| fastball wrote:
| I dunno, for me JSON will always be better than XML due to it
| just being nicer to read / work with.
| willseth wrote:
| You have clearly only ever had to deal with very simple
| JSON
| goodpoint wrote:
| This. Once a document is big or complex enough, the
| benefit of human readability fades away and you are left
| with a brittle and very slow serialization format.
| fastball wrote:
| How much slower is JSON serialization than XML
| serialization?
| goodpoint wrote:
| Roughly in the same order of magnitude, depending on the
| implementation.
|
| Light-years away from zero-copy serialization formats.
|
| See https://en.wikipedia.org/wiki/Comparison_of_data-
| serializati...
|
| Random example:
| https://google.github.io/flatbuffers/md__benchmarks.html
|
| Speed is not everything: being able to self-describe data
| structures (without the data) enables generation of
| parsers, documentation and tests.
|
| Streaming support also matters.
| fastball wrote:
| Haha nope, I've dealt with JSON files that were deeply
| nested and in the 100s of MBs.
|
| When you're dealing with complex data, JSON isn't very
| fun, but XML is still worse.
| gameswithgo wrote:
| I've worked with Will on a large XML based system. I'll
| try to briefly describe our workflow. Our company created
| reference books. Those books ended up both as printed
| books and as HTML in a web application service people
| could subscribe too. Various people would create the
| content, some in WYSIWIG editors, others editing raw html
| to tag content to give it structure, and tools that fall
| somewhat in between. XML tags and annotations can do
| things like indicate where the title is, sub headings,
| links to other books or content. etc etc.
|
| This annotation structure not only lets us transform the
| xml into HTML that resembles the physical book via CSS,
| but also lets us search the content with awareness of
| what the content is. Simple example, if a search term
| appears in a title give it more weight.
|
| When a book is done the XML goes off to a printer to
| become a book, AND into our XML database. A nice feature
| of which is a lot of our content is in the DB as XML, you
| ask for a book page and the DB returns the HTML for the
| page, backend just forwards that HTML to the browser
| which displays it. ZERO parsing/transformation anywhere
| once the DB sends it! Just fling the payload at the
| browser. Super cool at times.
|
| Anyway we all work with these formats differently, some
| of us never touch the json and xml, some of us only tweak
| values in config files. Those of us who work with it like
| that, the only differences between XML and JSON are "how
| nice are the serialization apis and how fast are they?
| how big is the payload?"
|
| But when working WITH the format directly there can be
| more meaningful differences. And the tools that actually
| exist for the things you are doing may push you towards
| one format or the other, even if in principle it wouldn't
| have really mattered.
|
| note: I keep mixing tenses here but this was all in the
| past, we got bought, don't do any of this anymore!
| willseth wrote:
| Cool then maybe share your experience wrangling giant
| complex JSON and why that was the better technical
| solution over XML.
| linkdd wrote:
| Please keep your patronizing comment to yourself, or add
| some arguments to it.
|
| JSON's spec is simpler, and the data are more compact.
| There are a ton of extremely fast parsers, as well as
| stream parsers. Many languages support JSON natively
| making it extra easy for interoperability.
| willseth wrote:
| Really? Try querying JSON, or transforming it, or
| validating it. There are fast JSON parsers? Cool, there
| are fast XML parsers too (that stream). JSON's spec is
| simpler, it's also more limited. I don't know what your
| point is. OP claimed XML was "worse" than JSON for large,
| deeply nested data, and his most compelling argument was
| "Haha nope." But sure, I'm patronizing. Go police someone
| else's comments.
| kbenson wrote:
| > his most compelling argument was "Haha nope."
|
| Pretty sure that was in response to you making
| assumptions about their experience, not as an answer to
| the question about what specifically makes them think
| that, which you only asked afterwards.
|
| This whole chain of comments is a good example of why
| responding with a dismissive short comment isn't a good
| idea, even if it feels good to send in the moment.
| willseth wrote:
| > This whole chain of comments is a good example of why
| responding with a dismissive short comment isn't a good
| idea
|
| This is simply inevitable as long as commenters are
| willing to make broad generalizations about complex
| topics. And it's hardly unfair to make assumptions about
| someone's experience when they _do not include it_ along
| with their highly reductive comment supposedly based on
| such experience!
| mypalmike wrote:
| It's just arrays and maps. Regardless of how large or
| deeply nested json gets, it's always very simple.
| marktolson wrote:
| I have successfully implemented this exact project in the past.
| The project allowed for runtime logic modification however
| tracking states was built into the platform to make debugging
| simple. As with every other library or framework, JsonLogic is
| a great tool if you implement it responsibly.
| solidsnack9000 wrote:
| Maybe it's a kind of having your cake and eating it too:
| enjoying the flexibility of passing code around and running it
| with eval, while not having the security, stability and runtime
| problems implied by eval.
|
| There are limited scopes in which this can work but it seems to
| be more about the environment or code loader than about the
| programming language, _per se_ : for example, plugin systems
| for build tools and servers. The plugin might be isolated by
| runtime features (like in the JVM) or by processes (as some web
| servers do, or as Postgres does) but it's not _language
| features_ that tend to be useful.
|
| Tensorflow models and CSS selectors are both examples of fairly
| useful plugins that still have limited enough semantics to be
| sandboxed effectively.
| pydry wrote:
| It sounds like your language didn't steer clear of Turing
| completeness.
|
| That's usually how this type of thing goes wrong. I've seen
| similar things both work and fail for that reason.
|
| This language made it an explicit goal, though.
| jchw wrote:
| I am not saying that you are wrong. Not at all.
|
| However, something I've come to learn is that some ideas I
| thought were bad were actually not bad. They were poorly
| executed and the exact reasoning why they did not work well in
| a given application was not well-understood.
|
| So I can see an argument for "this was horrible back when it
| was done in the early 2000s" simultaneously with "this could
| actually still be a good idea for some use cases."
| janderland wrote:
| Currently reading about agriculture throughout human history.
| It made me wonder how many people failed to domesticate a
| single kind of crop and assumed crop domestication as a whole
| isn't a good idea.
|
| I realize that people need to make decisions based on their
| personal experience, and I don't have a good rule-of-thumb
| for when to try a variation of a "bad" idea.
| marksbrown wrote:
| 'Many of life's failures are people who did not realise how
| close they were to success when they gave up' -- Thomas
| Edison.
| burnished wrote:
| said the man who tested something like 6000 different
| kinds of plant materials as filaments for a light bulb
| commandlinefan wrote:
| > If you are reading this, and you think it is a good idea
|
| I came to the comment section here hoping that the site was
| actually a joke...
| asah wrote:
| please no. just no.
|
| "Logic" is lazy word for "code" and we saw what happened when
| Excel "macros" grew up into major applications.
|
| To be safe under maintenance, safe vs security, etc code needs at
| least these things: - source control - docs (and ideally,
| examples) - tests (and ideally, CI)
| alex7o wrote:
| Can I ask why do we need to embed lisp in JSON, can't we just
| serialise our lisp to JSON?
| rubyist5eva wrote:
| I worked at a marketing company and we had a targeting engine
| that was basically this, but not as elegant. Will give this a try
| this weekend and see how it compares in practice, cool project.
| arthurcolle wrote:
| Not sure why this is getting so much hate, I think it's pretty
| cute. Can't really imagine when I'd use it, but i like it.
| papito wrote:
| Imagine trying to _configure_ rules in a CMS without touching
| code. I work at a place that does it. They may... be using
| this.
| laurent123456 wrote:
| Hmm... unversioned, untestable code saved in a database. What
| could go wrong.
| papito wrote:
| No this is not code - this is _configuration_. Many places
| actually save CODE into the DB and then load it at runtime
| for, say, ETL jobs. It 's not an easy problem.
___________________________________________________________________
(page generated 2021-05-27 23:01 UTC)