[RFC] JSObjectLiteral.jl

Hello,

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.
-3312329fe9891403

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))...)
            end
       :[$(elts...)] => Expr(:vect, map(json, elts)...)
       a :: Symbol || a :: T where T <: Number || a :: T where T <: AbstractString => a
end

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

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.

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