Open stuhlmueller opened 8 years ago
Another possibility (which I'm sharing, but don't know is a good idea) would be to make this work by using something other than member expressions for our foreign function interface. This is probably a bigger change than the first 2 suggestions, but I think it has at least some merit.
Rethinking the FFI is a good idea and should be done before 1.0. I also agree that adding all webppl functions from packages to the top-level is not a long-term solution. (This would likely come up when we rethink require/import anyway.)
For now, a good next step would be to make a comprehensive list of all of the member expression calls that we have been using (in examples, dippl, forest, etc). Then we can think about what each instance would look like under different proposals.
A workaround that may improve code readability in some situations:
var call = function(method, arg1, arg2, arg3) {
return method(arg1, arg2, arg3);
}
var world = {
transition: function(x) {return x + 1;}
};
// This doesn't work:
// world.transition(1)
// This works:
call(world.transition, 1)
Ran into this here: https://gist.github.com/chrisranderson/ec5151619da3aaeab9e0f1327838ed8c#file-dp-js-L80. I wanted to make a more general function that took functions as part of a configuration. I guess you know, but the same thing happens when you have an array with a function in it.
Should your call
solution be put in the header and documented (btw thanks! worked great)?
Here's a thought, to keep the conversation going: wrap all deterministic JS functions in a webppl shim that handles continuations/stores/addresses.
It's easy to do this for all deterministic JS provided in webppl packages (we can apply the shim upon loading the package).
For builtins, it's not so clean. Ideally, we'd want to know what all the builtins are, and then mask those with shim-ed versions scoped to the current webppl env
. Off the top of my head, options for catching all the built-ins include:
Here's an idea for a new FFI syntax: we use {{{
and }}}
to delimit sections of code that will not receive the CPS transform.
e.g.,
{{{ _.groupBy(people, function(person) { return person.occupation }) }}}
This would address two issues with the current FFI:
agent.act(...)
) because the dot no longer means "we're calling a foreign function"This doesn't exactly solve the issue in #642 (summary: by default, parseFloat
is broken) but maybe we could address that applying the CPS transform to a list of JS builtins.
For complex programs, it is useful to bundle up functions into objects. For example, we might want to represent agents as follows:
Currently, we first have to reassign methods to use them (
var act = agent.act; act(...);
) so that they don't get interpreted as primitive function calls. This makes the resulting models less readable. There should be a way to directly call webppl functions as methods.Here are two possibilities that come to mind (I'm open to others):