probmods / webchurch

A Church to Javascript compiler (DEPRECATED)
Other
140 stars 15 forks source link

can't redefine church built-ins and if you try to, errors are very opaque. #55

Open feste opened 10 years ago

feste commented 10 years ago

CODE EXAMPLE:

(define (plus a b) (+ a b))
(plus 1 1)

ERROR:

Cannot call method 'split' of undefined

/home/feste/webchurch/church:58
    throw e
          ^
TypeError: Cannot call method 'split' of undefined
    at evaluate (/home/feste/webchurch/evaluate.js:211:25)
    at Object.<anonymous> (/home/feste/webchurch/church:54:25)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:901:3
longouyang commented 10 years ago

For reference, the generated javascript looks like this:

(function () {
        var formatResult = require('./util.js').format_result;
    var churchToBareJs = require('./evaluate').churchToBareJs;
    var __pr = require('./probabilistic-js');
    __pr.openModule(__pr);
    var __ch = require('./church_builtins');
    openModule(__ch);
    var plus = function (x, y) {
        enterfn(0);
        var call0 = plus(x, y);
        leavefn();
        return call0;
    };
    enterfn(1);
    var call1 = plus(1, 2);
    leavefn();
    return call1;
}());

There is an obvious problem of recursive function definition here. Ideally, we might do something like:

var old_plus = plus;
var plus = function(x, y) {
enterfn(0);
var call0 = old_plus(x,y);

i.e., detect whenever user code will overshadow old builtins (but in a way that still uses the old builtins) and change generated js accordingly. I could see this being hard, though.

Also, while in looking into this, I've found some other strange edge cases, which I'll post soon.

longouyang commented 10 years ago

Some other strange edge cases:

;; works
(define f +)
(eval '(f 1 2))

;; fails
(define plus +)
(eval '(plus 1 2))

;; fails (weird)
(define plus +)
(eval '(+ 1 2))

;; fails (recursive define)
(define (plus x y) (+ x y))
(plus 1 2)