# A javascript stanc3

**URL:** <https://discourse.mc-stan.org/t/a-javascript-stanc3/11044>\
**Category:** Developers\
**Created:** [September 18, 2019, 11:15pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044 "2019-09-18T23:15:22Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![seantalts](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/seantalts/32/32_2.png) [@seantalts](https://discourse.mc-stan.org/u/seantalts)\
**Post date:** [September 18, 2019, 11:15pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/1 "2019-09-18T23:15:22Z")

</div>

I was playing around with stanc3 and js\_of\_ocaml (a compiler that compiles arbitrary ocaml code into javascript) and managed to make something that works with nodejs with basically the following commands, once I had nodejs installed and stanc3 was building locally:

```
opam install js_of_ocaml-compiler
dune build --profile=release src/stanc/stanc.bc.js

```

Amazingly well integrated with dune! To run it,

```
hal ~/scm/stanc3 (master) $ time node _build/default/src/stanc/stanc.bc.js test/integration/good/code-gen/mother.stan 

Warning: deprecated language construct used in 'test/integration/good/code-gen/mother.stan', line 60, column 21:
   -------------------------------------------------
    58:  
    59: void unit_normal_lp(real u) {
    60: increment_log_prob(normal_log(u,0,1));
                              ^
    61: u ~ uniform(-100,100);
    62: }
   -------------------------------------------------

increment_log_prob(...); is deprecated and will be removed in the future. Use target += ...; instead.

Warning: deprecated language construct used in 'test/integration/good/code-gen/mother.stan', line 184, column 20:
   -------------------------------------------------
   182:  
   183: real foo_lp(real x) {
   184: return x + get_lp();
                             ^
   185: }
   186:  
   -------------------------------------------------

get_lp() function is deprecated. It will be removed in a future release. Use target() instead.

real	0m1.817s
user	0m2.194s
sys	0m0.066s

```

Takes about 2s to transpile the (huge, intentionally egregious) mother model to C++ (compared with 0.081s for the native executable). Eight schools takes 0.871s with nodejs.

Given that there is a v8 port for R that runs Javascript, maybe this is a much quicker route to getting something up and running in RStan with stanc3? @bgoodri

Also this would make it easy to run the compiler and any future linters right in someone’s browser without having any server set up, which is kind of neat.

---

<div class="post-metadata">

**Author:** ![bgoodri](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/bgoodri/32/4451_2.png) [@bgoodri](https://discourse.mc-stan.org/u/bgoodri)\
**Post date:** [September 18, 2019, 11:48pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/2 "2019-09-18T23:48:26Z")

</div>

This seems promising. I had been aiming toward using

[http://caml.inria.fr/pub/docs/manual-ocaml/intfc.html#s%3Aembedded-code](http://caml.inria.fr/pub/docs/manual-ocaml/intfc.html#s%3Aembedded-code)

but Javascript would work as well as a C wrapper. My guess is @ariddell and @ahartikainen would agree?

---

<div class="post-metadata">

**Author:** ![seantalts](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/seantalts/32/32_2.png) [@seantalts](https://discourse.mc-stan.org/u/seantalts)\
**Post date:** [September 19, 2019, 12:00am UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/3 "2019-09-19T00:00:58Z")

</div>

I think Python is fine with standalone static binary executable, right?

---

<div class="post-metadata">

**Author:** ![seantalts](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/seantalts/32/32_2.png) [@seantalts](https://discourse.mc-stan.org/u/seantalts)\
**Post date:** [September 19, 2019, 3:50am UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/4 "2019-09-19T03:50:24Z")

</div>

Also worth noting the `js_of_ocaml` folks claim that the js version is often faster than the bytecode version :)

The V8 package seems good: [https://cran.r-project.org/web/packages/V8/vignettes/v8\_intro.html](https://cran.r-project.org/web/packages/V8/vignettes/v8_intro.html) but apparently it requires `libv8-dev` to be installed… Why can’t we do the same thing for OCaml or Stan on CRAN with a helper to install it locally?

---

<div class="post-metadata">

**Author:** ![bgoodri](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/bgoodri/32/4451_2.png) [@bgoodri](https://discourse.mc-stan.org/u/bgoodri)\
**Post date:** [September 19, 2019, 4:24am UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/5 "2019-09-19T04:24:16Z")

</div>

The guy who maintains the V8 R package is also the guy who maintains RTools, so he has already got Google’s v8 library onto CRAN for building binaries. Users only have to install Google’s v8 library on Linux, which is straightforward but differs slightly from one package manager to the next. So, we could bundle it or have a helper function to download it on Linux or just provide instructions, but it is not a big deal either way.

Getting the OCaml libraries built is probably possible too, but is more of a challenge on Windows than v8 was.

---

<div class="post-metadata">

**Author:** ![seantalts](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/seantalts/32/32_2.png) [@seantalts](https://discourse.mc-stan.org/u/seantalts)\
**Post date:** [September 19, 2019, 1:10pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/6 "2019-09-19T13:10:31Z")

</div>

> [@bgoodri](#):
>
> Getting the OCaml libraries built is probably possible too, but is more of a challenge on Windows than v8 was.

You mean getting them built and installed on CRAN Windows build machines?

Another consideration here - if we come out with a Stan REPL or interpreter-mode, that will link against C code and I doubt either of these methods will work for distribution. But at that point maybe we just release another package.

---

<div class="post-metadata">

**Author:** ![seantalts](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/seantalts/32/32_2.png) [@seantalts](https://discourse.mc-stan.org/u/seantalts)\
**Post date:** [September 19, 2019, 1:53pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/7 "2019-09-19T13:53:05Z")

</div>

Just in case, I added `stanc.js` builds to Jenkins: [https://github.com/stan-dev/stanc3/releases/tag/nightly](https://github.com/stan-dev/stanc3/releases/tag/nightly)

---

<div class="post-metadata">

**Author:** ![bgoodri](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/bgoodri/32/4451_2.png) [@bgoodri](https://discourse.mc-stan.org/u/bgoodri)\
**Post date:** [September 19, 2019, 3:31pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/8 "2019-09-19T15:31:54Z")

</div>

What I was saying in the meeting

```no-highlight
library(V8)
ctx <- v8()
ctx$source("https://github.com/stan-dev/stanc3/releases/download/nightly/stanc.js")

```

> Error in context\_eval(join(src), private$context) :  
> Please specify one model\_file.  
> Usage: stanc [option] … \<model\_file.stan\>  
> …

---

<div class="post-metadata">

**Author:** ![seantalts](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/seantalts/32/32_2.png) [@seantalts](https://discourse.mc-stan.org/u/seantalts)\
**Post date:** [September 19, 2019, 3:36pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/9 "2019-09-19T15:36:31Z")

</div>

Good point, I need to add a javascript-specific endpoint for this to be used not-from-nodejs if we’re serious about going this route. Should I go ahead and do that? Shouldn’t be more than a couple hours work at most.

---

<div class="post-metadata">

**Author:** ![bgoodri](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/bgoodri/32/4451_2.png) [@bgoodri](https://discourse.mc-stan.org/u/bgoodri)\
**Post date:** [September 19, 2019, 3:36pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/10 "2019-09-19T15:36:49Z")

</div>

Sounds good

---

<div class="post-metadata">

**Author:** ![seantalts](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/seantalts/32/32_2.png) [@seantalts](https://discourse.mc-stan.org/u/seantalts)\
**Post date:** [September 20, 2019, 7:13pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/11 "2019-09-20T19:13:31Z")

</div>

Okay, that took like twice as long as I thought it would - turns out you need to convert from and to JavaScript specific string representations at the API boundaries, but not for ints or numbers. Makes sense in retrospect; doc is totally absent on this use case.

Anyway, want to give this a try? [https://github.com/stan-dev/stanc3/releases/download/nightly/stanc.js](https://github.com/stan-dev/stanc3/releases/download/nightly/stanc.js)

---

<div class="post-metadata">

**Author:** ![bgoodri](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/bgoodri/32/4451_2.png) [@bgoodri](https://discourse.mc-stan.org/u/bgoodri)\
**Post date:** [September 20, 2019, 9:05pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/12 "2019-09-20T21:05:49Z")

</div>

I would if I knew how to call it.

```no-highlight
library(V8)
ctx <- v8()
ctx$source("https://github.com/stan-dev/stanc3/releases/download/nightly/stanc.js")

```

seems to work now, but I don’t know where to go from there. Something like

```no-highlight
> ctx$call("stanc", "foo.stan", "foo.cpp")

```

seems like it should work but says

> Error in context\_eval(join(src), private$context) : 0,248,Failure,-3,

---

<div class="post-metadata">

**Author:** ![seantalts](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/seantalts/32/32_2.png) [@seantalts](https://discourse.mc-stan.org/u/seantalts)\
**Post date:** [September 20, 2019, 9:06pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/13 "2019-09-20T21:06:57Z")

</div>

Woops. try `ctx$call("stanc", "model_name", "data {}")`

---

<div class="post-metadata">

**Author:** ![bgoodri](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/bgoodri/32/4451_2.png) [@bgoodri](https://discourse.mc-stan.org/u/bgoodri)\
**Post date:** [September 20, 2019, 9:07pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/14 "2019-09-20T21:07:51Z")

</div>

> [@seantalts](#):
>
> ctx$call(“stanc”, “model\_name”, “data {}”)

Same error

---

<div class="post-metadata">

**Author:** ![bgoodri](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/bgoodri/32/4451_2.png) [@bgoodri](https://discourse.mc-stan.org/u/bgoodri)\
**Post date:** [September 20, 2019, 9:12pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/15 "2019-09-20T21:12:02Z")

</div>

If I jump into the JavaScript interpreter with

```no-highlight
ctx$consolse()

```

then

```no-highlight
This is V8 version 3.14.5.9. Press ESC or CTRL+C to exit.
~ stanc "foo" "data {}"

```

yields

> SyntaxError: Unexpected string

---

<div class="post-metadata">

**Author:** ![seantalts](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/seantalts/32/32_2.png) [@seantalts](https://discourse.mc-stan.org/u/seantalts)\
**Post date:** [September 20, 2019, 9:13pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/16 "2019-09-20T21:13:12Z")

</div>

If I create a new ctx, source, and then use `ctx$eval("stanc('mn', 'data {}')")` it works for me… not sure why call doesn’t or what the best way of using this V8 package is :/

---

<div class="post-metadata">

**Author:** ![seantalts](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/seantalts/32/32_2.png) [@seantalts](https://discourse.mc-stan.org/u/seantalts)\
**Post date:** [September 20, 2019, 9:14pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/17 "2019-09-20T21:14:00Z")

</div>

> [@bgoodri](#):
>
> This is V8 version 3.14.5.9. Press ESC or CTRL+C to exit. ~ stanc “foo” “data {}”

You meant to type `stanc("foo", "data {}")`

---

<div class="post-metadata">

**Author:** ![bgoodri](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/bgoodri/32/4451_2.png) [@bgoodri](https://discourse.mc-stan.org/u/bgoodri)\
**Post date:** [September 20, 2019, 9:17pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/18 "2019-09-20T21:17:11Z")

</div>

> [@seantalts](#):
>
> `ctx$eval("stanc('mn', 'data {}')")`

OK. We can do `ctx$eval` rather than `ctx$call`. Can it read a file off the disk or do we need to read it from the disk in R and pass it to `stanc` as a string? Also, how do you specify additional arguments to the (old) `stanc` like `--allow-undefined`?

---

<div class="post-metadata">

**Author:** ![seantalts](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/seantalts/32/32_2.png) [@seantalts](https://discourse.mc-stan.org/u/seantalts)\
**Post date:** [September 20, 2019, 9:19pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/19 "2019-09-20T21:19:01Z")

</div>

The previous version that works with nodejs can read files but that’s because node presents additional APIs for OS stuff that vanilla JS doesn’t. So it looks like in this V8-in-R context we have to communicate back and forth via strings :/

---

<div class="post-metadata">

**Author:** ![seantalts](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/seantalts/32/32_2.png) [@seantalts](https://discourse.mc-stan.org/u/seantalts)\
**Post date:** [September 20, 2019, 9:20pm UTC](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044/20 "2019-09-20T21:20:55Z")

</div>

> [@bgoodri](#):
>
> Also, how do you specify additional arguments to the (old) `stanc` like `--allow-undefined` ?

Hm, I can build in whichever ones of those you need as an additional flags dict/obj thingy. Which ones do you use?

[Next page](https://discourse.mc-stan.org/t/a-javascript-stanc3/11044.md?page=2)
