var sgFun = {
    map: function(fun, list) {
	var res = new Array();
	for (var i = 0; i < list.length; i++) {
            res[i] = fun(list[i]);
	}
	return res;
    },

    reduce: function(fun, list, init) {
	var result = init;
	for (i = 0; i < list.length; i++) {
            result = fun(result, list[i]);
	}
	return result;
    },

    filter: function(fun, list) {
	var result = [];
	for (i = 0; i < list.length; i++) {
            if (fun(list[i]))
		result[result.length] = list[i];
	}
	return result;
    },


    partial: function(fun) {
	var fixed=arguments;
	var res = function() {
	    var newargs = Array();
	    for (var arg in fixed) {
		newargs[newargs.length] = arg;
	    }
	    for (var arg in arguments) {
		newargs[newargs.length] = arg;
	    }
	    return apply(fun, newargs);
	}
	return res;
    },

    any: function(fun, list) {
	for (var i = 0; i < list.length; i++) {
            if (fun(list[i]))
		return true;
	}
	return false;
    },

    all: function(fun, list) {
	for (var i = 0; i < list.length; i++) {
            if (!fun(list[i]))
		return false;
	}
	return true;
    },

    or: function(list) {
	return this.any(function(el) {return el;}, list);
    },
    
    and: function(list) {
	return this.all(function(el) {return el;}, list);
    },

    // Y Combinator
    Y: function(le) {
	return function (f) {
            return f(f);
	}(function (f) {
            return le(function (x) {
		return f(f)(x);
            });
	});
    }
};
/* a try at list comprehension */
// lc(f(x, y, z), x, in_(list), when)
/*var lc = function(expr, toBind, inList) {
    var args = inList();
    return map(expr, args);
}*/