A javascript stanc3

Also I got ctx$call("stanc", "mn", "data {}") working for me, though it did error the first 2 times I tried it. No idea what’s going on there.

OK. That is more or less what we do with the C++ stanc now.

Currently,

> args(rstan::stanc)
function (file, model_code = "", model_name = "anon_model", verbose = FALSE, 
    obfuscate_model_name = TRUE, allow_undefined = FALSE, isystem = c(if (!missing(file)) dirname(file), 
        getwd())) 

which are

  • file the name of the Stan program on disk, which if specified, I guess we need to read to a string from R
  • model_code Stan program as a R string
  • model_name which I guess I can just pass along as the first argument to stanc
  • obfuscate_model_name This made the class a long random string so that the user would not get clashes if they have different models called “my_model” or something generic. Maybe a better option would be for the class name to be the MD5sum of the Stan program?
  • allow_undefined tells stanc to not throw an error if you have a function that is declared but not defined, so that you can provide the definition in C++
  • isystem tells stanc what directories to look in for the C++ file that defines said functions

The last two are basically the same as in the existing stanc (e.g. in CmdStan)

stanc version 2.20.0

USAGE:  stanc [options] <model_file>

OPTIONS:

  --help              Display this information

  --version           Display stanc version number

  --name=<string>     Model name
                          (default = "$model_filename_model")

  --o=<file>          Output file for generated C++ code
                          (default = "$name.cpp")

  --allow_undefined   Do not fail if a function is declared but not defined

  --include_paths=<comma-separated list>
                      Comma-separated list of directories that may contain a file in an #include directive

A couple of other things. We need this merged PR


for stanc3 as well, so that packages with multiple Stan programs don’t get linker errors from having multiple definitions of new_model.

Also, can the resize_to_match functions go inside the namespace?

Finally, do we need a separate JavaScript file to call stanfuncs or can that be done with the existing one?

Also, how do you get the messages if there is a syntax error in the Stan program, as in

ctx$eval("stanc('mn', 'dat {}')")

?

+1 MD5 sum model name if obfuscated - better for caching with invalidation. The only thing stanc uses the model name for is printing error messages and the name of the C++ class, so if you are obfuscating it I’d send stanc the unobfuscated name still.

but wait, do you still need to obfuscate the name? You can just cache internally in rstan::stanc based on a MD5 sum of the model code, right? And you can call the resulting C++ file anything you want (you’ll have to write it out somewhere I suppose).

Gotcha, I’ll work on that.

Wait, is this for finding Stan includes? Or C++ includes? Does this flag get passed to clang or to stanc?

The includes thing is tricky. The V8 thing has no access to the file system. You might have to read them in as well and pass them in as some kind of dictionary from file path to model string… :/

Yep.

What is stanfuncs?

Hm, it doesn’t seem to be propagating the exception nicely. I can wrap the return value in an object like this:

{ cpp: "stan_model_cpp", warnings: ["warning1", "warning2"], errors: ["error1"] }

So if it succeeds, it will have a cpp key with a non-empty string. If it has warnings or errors they’ll be put in their lists. How’s that sound?

stanc for finding included Stan programs

Ah, I guess it is called compile_functions in the Stan library
https://github.com/stan-dev/stan/blob/master/src/stan/lang/compile_functions.hpp

Good

I am trying to put this check into rstan but the C++ code

ctx <- V8::v8()
ctx$source("https://github.com/stan-dev/stanc3/releases/download/nightly/stanc.js")
ctx$eval("stanc('test', 'data {}')")

is generating is actually not valid. It has this declaration

class  : public model_base_crtp<> {

which needs to be something like

class test
  : public stan::model::model_base_crtp<test> {
1 Like

Sounds like a bug. I’ll take a look - I think we need to unify our IO a little more and not assume we have a file to work with in some places still.

The latest nightly should have this bug fixed. Still working on trying to figure out how to output JS objects and convert a bunch of our pipeline for errors and warnings that assumes we can just print to returning something instead…

OK, that is ultimately necessary but not a huge priority for the next rstan release.

Woops, I thought I replied here already. The current nightly has the results wrapped in a js object now.

Thanks. I will check it out.

With the nightly, this

ctx <- V8::v8()
ctx$source("https://github.com/stan-dev/stanc3/releases/download/nightly/stanc.js")
ctx$eval("stanc('test', 'data {}')")

is just producing a string that says "[object Object]". Am I supposed to be calling it differently now?

😂 let me take another look. Sorry about that.

oh, try this instead:

> ctx$call("stanc", "test", "data {}")

OK. That works. Thanks.