Site icon R-bloggers

Introducing V8: An Embedded JavaScript Engine for R

[This article was first published on OpenCPU, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

JavaScript is an fantastic language for building applications. It runs on browsers, servers and databases, making it possible to design an entire web stack in a single language.

The OpenCPU JavaScript client already allows for calling R functions from JavaScript (see jsfiddles and apps). With the new V8 package we can now do the reverse as well: run JavaScript inside R!

The V8 Engine

V8 is Google’s open source, high performance JavaScript engine. It is written in C++ and implements ECMAScript as specified in ECMA-262, 5th edition. The V8 R package builds on C++ library to provide a completely standalone JavaScript engine within R:

library(V8)

# Create a new context
ct <- new_context();

# Evaluate some code
ct$eval("foo=123")
ct$eval("bar=456")
ct$eval("foo+bar")
# [1] "579"

However note that V8 by itself is just the naked JavaScript engine. Currently, there is no DOM, no network or disk IO, not even an event loop. Which is fine because we already have all of those in R. In this sense V8 resembles other foreign language interfaces such as Rcpp or rJava, but then for JavaScript.

A major advantage over the other foreign language interfaces is that V8 requires no compilers, external executables or other run-time dependencies to execute JavaScript. The entire engine is contained within a 6MB R package (2MB when zipped) and works on all major platforms.

ct$eval("JSON.stringify({x:Math.random()})")
# [1] "{"x":0.08649904327467084}"
ct$eval("(function(x){return x+1;})(123)")
# [1] "124"

Sounds promising? There is more!

V8 + jsonlite = awesome

The native data structure in JavaScript is basically JSON, hence we can use jsonlite for seamless data interchange between V8 and R:

ct$assign("mydata", mtcars)
out <- ct$get("mydata")
all.equal(out, mtcars)
# TRUE

Because jsonlite stores data in its natural structure, we can plug it staight into existing JavaScript libraries:

# Use a JavaScript library
ct$source("http://underscorejs.org/underscore-min.js")
ct$call("_.filter", mtcars, I("function(x){return x.mpg < 15}"))
#                      mpg cyl disp  hp drat    wt  qsec vs am gear carb
# Duster 360          14.3   8  360 245 3.21 3.570 15.84  0  0    3    4
# Cadillac Fleetwood  10.4   8  472 205 2.93 5.250 17.98  0  0    3    4
# Lincoln Continental 10.4   8  460 215 3.00 5.424 17.82  0  0    3    4
# Chrysler Imperial   14.7   8  440 230 3.23 5.345 17.42  0  0    3    4
# Camaro Z28          13.3   8  350 245 3.73 3.840 15.41  0  0    3    4

JavaScript Libraries

JavaScript libraries specifically written for the Browser (such as Jquery or D3) or libraries for Node that depend on disk/network functionality might not work in plain V8, but many of them actually do.

For example, crossfilter is a high performance data filtering library that I have used for creating D3 data dashboards in the browser, but crossfilter itself is just vanilla JavaScript:

ct$source("cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.11/crossfilter.min.js")

I’ll continue here in the next blog post later this week. Have a look at the (very short) package manual in the mean time.

To leave a comment for the author, please follow the link and comment on their blog: OpenCPU.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.