WebPPL packages are regular Node.js packages optionally extended to include WebPPL code and headers.
To make a package available in your program use the --require
argument:
webppl myFile.wppl --require myPackage
WebPPL will search the following locations for packages:
- The
node_modules
directory within the directory in which your program is stored. - The
.webppl/node_modules
directory within your home directory. Packages can be installed into this directory withnpm install --prefix ~/.webppl myPackage
.
Packages can be loaded from other locations by passing a path:
webppl myFile.wppl --require ../myPackage
Packages can extend WebPPL in several ways:
You can automatically prepend WebPPL files to your code by added a
wppl
entry to package.json
. For example:
{
"name": "my-package",
"webppl": {
"wppl": ["myLibrary.wppl"]
}
}
The use of some inference algorithms causes a caching transform to be
applied to each wppl
file. It is possible to skip the application
of this transform on a per-file basis by placing the no caching
directive at the beginning of the file. For example:
'no caching'; // Rest of WebPPL program
This is expected to be useful in only a limited number of cases and shouldn't be applied routinely.
Any regular JavaScript code within a package is made available in WebPPL
as a global variable. The global variable takes the same name as the
package except when the package name includes one or more -
characters. In such cases the name of the global variable is obtained by
converting the package name to camelCase.
For example, if the package my-package
contains this file:
// index.js module.exports = { myAdd: function(x, y) { return x + y; } };
Then the function myAdd
will be available in WebPPL as
myPackage.myAdd
.
If your JavaScript isn’t in an index.js
file in the root of the
package, you should indicate the entry point to your package by adding a
main
entry to package.json
. For example:
{
"name": "my-package",
"main": "src/main.js"
}
Note that packages must export functions as properties of an object. Exporting functions directly will not work as expected.
Sometimes, it is useful to define external functions that are able to access WebPPL internals. Header files have access to the following:
- The store, continuation, and address arguments that are present at any point in a WebPPL program.
- The
env
container which allows access toenv.coroutine
among other things.
Let’s use the example of a function that makes the current address available in WebPPL:
Write a JavaScript file that exports a function. The function will be called with the
env
container and should return an object containing the functions you want to use:// addressHeader.js module.exports = function(env) { function myGetAddress(store, k, address) { return k(store, address); }; return { myGetAddress: myGetAddress }; };
Add a
headers
entry topackage.json
:
{
"name": "my-package",
"webppl": {
"headers": ["addressHeader.js"]
}
}
Write a WebPPL file that uses your new functions (without module qualifier):
// addressTest.wppl var foo = function() { var bar = function() { console.log(myGetAddress()); } bar(); }; foo();
The WebPPL package template provides a scaffold that you can extend to create your own packages.
- json: read/write json files
- csv: read/write csv files
- fs: read/write files in general
- dp: dynamic programming (caching for mutually recursive functions)
- editor: browser based editor
- viz: visualization utilities
- bda: data analysis utilities
- agents: agent simulations
- timeit: timing utilities
- intercache: interpolating cache
- oed: optimal experimental design
These packages are no longer maintained, but may be worth a look: