[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!

3 Likes

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
2 Likes

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.

2 Likes

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
2 Likes