[RFC] JSObjectLiteral.jl


For my own understanding of Julia macros and evaluation of expressions, I’ve made a tiny package that can parse “javascript-like” object literals in Julia, like {a: b, c: [d, { e, f, g: "gee!" } ], h: "ouch!" } by parsing and replacing the abstract syntax tree.

Any comments (like “why would you want to do this?” or “This is not what we usually call an object literal”) are welcome!


Cool job.
However, I’d say sorry for I cannot stop myself from selling my package.

using MLStyle
json(node) =
@match node begin
      :({ $(kvs...) }) => 
             let f = @λ :($k : $v) -> Expr(:call, =>, string(k), json(v))
                 Expr(:call, Dict, (f(kv) for kv in kvs if !(kv isa LineNumberNode))...)
       :[$(elts...)] => Expr(:vect, map(json, elts)...)
       a :: Symbol || a :: T where T <: Number || a :: T where T <: AbstractString => a

macro json(expr)
     json(expr) |> esc

Wow, that looks impressive. As far as I can tell you don’t have the shortcut { a } === { a: a } but I suppose that is just one more line in your code.

I couldn’t stop myself from developing somewhat further, and I can now also do things like evaluating a.b.c and a.b.c = 4 but this led quite a refactoring of everything.


Hey, your idea is cool. The reason why for my code is short is that I use better tools, but which is not the core of the making a package.
If you want to make JSObjectLiteral a solid solution for JSON operations, it’s still far to go, which is not MLStyle.jl could help with much, e.g., you can make following plans:

  • Chaining getter or setters, just as what you said, a.b.c, a.b.c = 4.
  • support (de)serialization for JSONs.
  • support queries/GraphQL on JSONs.

I sell my package, which is aimed at making developers or normal users able to focus on the core logics in their work instead of something boring and verbose.

1 Like

For the interested, with the help of @thautwarm, JSObjectLiteral.jl can now generate objects from more esoteric javascript expressions, such as

@js d = { e: exp(1) } ## Dict("e" => exp(1))
deep = @js { a.b.c: d.e, f: d } ## short for { a: { b: { c: d.e } }, f: d }
@js { a, f } = deep ## assignment-by-key-correspondence
@js a.b.c == exp(1) ## true
f == d ## true