1 Introduction
2.1 Structures
2.2 Low-level API
Version: 5.1.2

browser-evaluate: evaluate JavaScript expressions in the browser through Racket

Danny Yoo <dyoo@hashcollision.org>

Source code can be found at: https://github.com/dyoo/browser-evaluate.

1 Introduction

This library allows you to send JavaScript expressions from Racket into a web browser. Furthermore, the library provides hooks to send string values from that evaluation back into Racket.

As a simple example, evaluating the following:
#lang racket/base
(require (planet dyoo/browser-evaluate))
(simple-js-evaluate "alert('hello world!');")
should bring up a browser window in which an alert dialog should display. The library depends on the browser to do the JavaScript evaluation, and sends values back and forth between the browser and Racket.

For more fine-grained control over evaluation, you can use js-evaluate, which allows string values to be returned back from JavaScript back to Racket. The JavaScript code should call the $SUCC success function to send the value back into Racket. For example:
#lang racket/base
(require (planet dyoo/browser-evaluate))
(define result (js-evaluate #<<EOF
var f = function(x) {
    if (x == 0) { return 1; }
    else { return x * f(x-1); }
When this program executes, result will be bound to an evaluated stucture whose evaluate-value will be 3628800.


 (require (planet dyoo/browser-evaluate:1:0))

(simple-js-evaluate str)  evaluated?
  str : string?
Evaluates a JavaScript string. Returns an evaluated structure that records how long the evaluation took, and on what browser the evaluation happened.

Each of the evaluation functions run in a isolated lexically scoped context. For example:
#lang racket/base
(require (planet dyoo/browser-evaluate))
(simple-js-evaluate "var x = 3;")
(simple-js-evaluate "var x = x + 1;")
(simple-js-evaluate "alert(x);")
should raise a error, since x will not be bound on the third use of simple-js-evaluate.

(js-evaluate str)  evaluated?
  str : string?
Evaluates a JavaScript string, where the user is responsible for calling $SUCC. The call to js-evaluate blocks until the JavaScript function calls $SUCC with a value.

For example:
#lang racket/base
(require (planet dyoo/browser-evaluate))
(js-evaluate "$SUCC(3 * 4);")
will return an evaluated structure whose evaluated-value will be the string "12".

In order to signal an exception back to Racket, use the implicit $FAIL function. For example.
#lang racket/base
(require (planet dyoo/browser-evaluate))
(js-evaluate "$FAIL('oh no!');")
will raise an error-happened whose exn-message field will be the string "oh no!".

2.1 Structures

The return value for the evaluation functions in this libarary are instances of the evaluated structure.
(struct evaluated (stdout value t browser)
  #:extra-constructor-name make-evaluated)
  stdout : string
  value : string?
  t : number
  browser : string?
value represents the value returned by a use of $SUCC. t represents the amount of time in milliseconds that evaluation took. browser represents the browser string.

The stdout field is currently underdocumented.

If the JavaScript code signals an error (with a use of $FAIL), then an error-happened structure will be raised to the Racket caller.
(struct error-happened exn:fail (message continuation-marks t)
  #:extra-constructor-name make-error-happened)
  message : string?
  continuation-marks : continuation-mark-set?
  t : number?

2.2 Low-level API

(make-evaluate program-transformer)
  (any/c -> (values string number))
  program-transformer : (any/c output-port . -> . void)
(Low-level function that’s used to implement simple-js-evaluate and js-evaluate.)

Produces a JavaScript evaluator that cooperates with a browser. The JavaScript-compiler is expected to write out a thunk. When invoked, the thunk should return a function that consumes three values, corresponding to success, failure, and other parameters to evaluation.

For example:
#lang racket/base
(require (planet dyoo/browser-evaluate))
(define my-eval
    (lambda (program op)
      (fprintf op #<<EOF
(function() {
   return function(success, fail, params) {
defines an evaluator my-eval that will always give back "ok" as the value of the evaluation.