define-type written in JavaScript

10 views
Skip to first unread message

Logan Kearsley

unread,
Dec 17, 2011, 2:43:25 PM12/17/11
to byu-cs-330-Fall-2011
It can't do type-enforcing, but otherwise works.

var defineType = function(name,subtypes){
var subtype,
_super = function(){};
Object.defineProperty(Object.prototype,name+"_q",{
get:function(){return this instanceof _super;}
});
for(subtype in subtypes){
(function(fields){
var len = fields.length,
construct = function(){
var that = (this instanceof construct)?this:
Object.create(construct.prototype);
for(var i = 0;i<len;i++){
that[fields[i]] = arguments[i];
}
return that;
};
construct.prototype = new _super();
construct.prototype.constructor = construct;
this[subtype] = construct;
Object.defineProperty(Object.prototype,subtype+"_q",{
get:function(){return this instanceof construct;}
});
}(subtypes[subtype]));
}
};

defineType('WAE',{
num:['n'],
binop:['op','lhs','rhs'],
def:['lob','body'],
id:['name']
});

This produces globally accessible constructors for num, binop, def,
and id, and boolean object properties .num_q, .binop_q, .def_q, .id_q,
and .WAE_q.

(5).num_q === false
id('x').num_q === false;
num(5).num_q === true
num(5).WAE_q === true

Jay McCarthy

unread,
Dec 17, 2011, 3:14:32 PM12/17/11
to byu-cs-330...@googlegroups.com
I love Javascript "abstractions".

var x = num(5);
x.num_q = false;
x.id_q = true;

interp(x);

<3

Jay
--
Jay McCarthy <j...@cs.byu.edu>
Assistant Professor / Brigham Young University
http://faculty.cs.byu.edu/~jay

"The glory of God is Intelligence" - D&C 93

Logan Kearsley

unread,
Dec 17, 2011, 4:08:41 PM12/17/11
to byu-cs-330-Fall-2011
On Dec 17, 1:14 pm, Jay McCarthy <jay.mccar...@gmail.com> wrote:
> I love Javascript "abstractions".
>
> var x = num(5);
> x.num_q = false;
> x.id_q = true;

Ah, I thought of that, and fixed it.
In a browser environment, the assignment fails silently, and the type-
querying properties maintain their true values.

In node, you get this:

var x = num(5);
try{ x.num_q = false;
x.id_q = true;
}catch(e){console.log(e.message);}

> Error: Cannot set property num_q of #<Object>

-logan.

Logan Kearsley

unread,
Dec 17, 2011, 7:37:22 PM12/17/11
to byu-cs-330-Fall-2011
Here's an updated version with type-case, too:

function defineType(name,subtypes){


var subtype,
_super = function(){};

this[name] = _super;


Object.defineProperty(Object.prototype,name+"_q",{
get:function(){return this instanceof _super;}
});
for(subtype in subtypes){

(function(fields,type){


var len = fields.length,
construct = function(){
var that = (this instanceof construct)?this:
Object.create(construct.prototype);
for(var i = 0;i<len;i++){
that[fields[i]] = arguments[i];
}

that._type = type;


return that;
};
construct.prototype = new _super();
construct.prototype.constructor = construct;

_super[type] = fields;
this[type] = construct;


Object.defineProperty(Object.prototype,subtype+"_q",{
get:function(){return this instanceof construct;}
});

}(subtypes[subtype],subtype));
}
}

function typeCase(type,arg,cases){
var subtype;
if(!(arg instanceof type)) throw "Type mismatch";
if(typeof cases._ === 'undefined'){
for(subtype in type) if(type.hasOwnProperty(subtype)){
if(typeof cases[subtype]==='undefined') throw "Missing "+subtype+"
case";
}
}
if(arg._type in cases){
return
cases[arg._type].apply(this,type[arg._type].map(function(fname){return
arg[fname];}));
}else{
return cases._();
}
}

defineType('CFWAE',{


num:['n'],
binop:['op','lhs','rhs'],
def:['lob','body'],

id:['name'],
if0:['c','then','else'],
fun:['args','body'],
app:['f','args']});

console.log(
typeCase(CFWAE,num(5),{
num:function(n){return "num "+n;},
binop:function(op,lhs,rhs){return "binop "+op+lhs+rhs;},
def:function(bindings,body){return "def "+bindings+body;},
_:function(){return "Else";}
})
);

typeCase is really inefficient, but it does work. You can get the same
functionality with better performance by just doing

switch(arg.constructor){
case num: ....
}

which is how I've implemented the translation of xinterp into
JavaScript.

-l.

Reply all
Reply to author
Forward
0 new messages