Skip to content

Commit

Permalink
Add JSON compat entry, update README.
Browse files Browse the repository at this point in the history
  • Loading branch information
twavv committed Dec 21, 2019
1 parent d4a8bca commit 805c177
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 12 deletions.
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ version = "1.0.0"
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"

[compat]
JSON = "0.18"
julia = "0.7, 1"

[extras]
Expand Down
36 changes: 24 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ JSString("initializeProgram({\"foo\":\"bar\"});")

## Interpolation

You can interpolate Julia objects or `JSString`'s (e.g. from other `@js` or
`js"..."` invocations) as well.
You can interpolate Julia objects or `JSString`s (e.g. from other `@js` or
`js"..."` invocations) as well as values from Julia (such as normal
strings, `Dict`s, etc.).

```julia
julia> foo = 42;
Expand Down Expand Up @@ -60,33 +61,38 @@ JSString("const link = <a href=\"https://julialang.org/\">\"Julia\"</a>")
Objects are ubiquitous in JavaScript.
To create objects using JSExpr, you can use a simple syntax using braces.
There are two variants of this syntax (_NamedTuple_ style and _Pair_ style).
You can also create objects use normal `NamedTuple` syntax.

```julia
# NamedTuple style
# NamedTuple braces style
julia> @js { foo="foo", bar="bar" }
JSString("{\"foo\": \"foo\", \"bar\": \"bar\"}")

# Pair style
# Pair braces style (similar to Dict constructor)
julia> @js { :foo => "foo", :bar => "bar" }
JSString("{\"foo\": \"foo\", \"bar\": \"bar\"}")

# NamedTuple syntax
julia> @js (foo="foo", bar="bar")
JSString("{\"foo\": \"foo\", \"bar\": \"bar\"}")
```

#### Why not `Dict`?
JSExpr does not attempt to translate _semantics_ between Julia and JavaScript
(with a few very minor exceptions covered in _Juliaisms_ below).
Since `Dict` can be a valid function name in JavaScript, we do not translate
the Julia `Dict` function to an object creation syntax.
the Julia `Dict` constructor to an object creation syntax.

## Juliaisms
JSExpr, for the most part, does not attempt to translate semantics between
Julia and the resulting JavaScript code.
The reason for the decision is due to the fact that Julia and JavaScript are
wildly different languages and we would invariably screw up some edge cases.
The reason for the decision is that Julia and JavaScript are
wildly different languages and we would invariably mess up some edge cases.
We do, however, translate a few Julian constructs to a _semantically_ equivalent
JavaScript.

#### Range Syntax (`...:...`)
JavaScript doesn't have a native `Range` object and the typical way of repeat a
JavaScript doesn't have a native `Range` object and the typical way to repeat a
loop body `n` times is to use a C-style `for` loop. There is no syntax for this
style of for loop in Julia, and `:` is not a valid JavaScript identifier, so the
colon function (`:`) is translated to JavaScript code that acts like a `Range`
Expand All @@ -99,7 +105,7 @@ julia> @js for i in 1:10
JSString("for (let i of (new Array(10).fill(undefined).map((_, i) => i + 1))) { console.log(i); }")
```

The resulting code is very ugly and will fully materialize the range and so
The resulting JS is very ugly and will fully materialize the range and so
should only be used for relatively small ranges.

## Serialization
Expand All @@ -123,19 +129,25 @@ julia> JSON.print(Dict("foo" => "bar", "bar"=>f))
- JavaScript keywords (`@new`, `@var`, `@let`, `@const`)

## Unsupported Expressions
### Not Yet Supported
* Ternary expressions (`... ? ... : ...`)
* `try` / `catch`

### Might Never Be Supported
* Object destructuring
* Argument splatting

If you notice anything else that's not supported or doesn't work as intended,
please [open an issue](https://github.com/JuliaGizmos/JSExpr.jl/issues).

#### Ternary Expressions
Julia lowers the `if` statements and ternary expressions (`... ? ... : ...`) to
the same `Expr` value, so JSExpr cannot distinguish between the two.
Julia lowers (during parse) `if` statements and ternary expressions (`... ? ... : ...`)
to the same `Expr`, so JSExpr cannot distinguish between the two.
This poses an issue because JavaScript does not allow non-expression statements
(e.g., loops and variable declarations) inside of a ternary expression.
(e.g., loops and variable declarations) inside of a ternary expression, but if
statements cannot be used in contexts which expect a value (but they _can_ be
used in such contexts in Julia).

There are plans to implement a heuristic to emit a ternary expression if
appropriate (e.g., if the bodies of the ternary expression contains only one
sub-expression) but this is not implemented yet.

2 comments on commit 805c177

@twavv
Copy link
Member Author

@twavv twavv commented on 805c177 Dec 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request updated: JuliaRegistries/General/7033

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if Julia TagBot is installed, or can be done manually through the github interface, or via:

git tag -a v1.0.0 -m "<description of version>" 805c1779c5eedd7ea62ae0ccce3d2c2e45dfc1f5
git push origin v1.0.0

Please sign in to comment.