if (args.length!=arity) throwArity(args.length);
IPersistentMap bindings=PersistentHashMap.EMPTY;
for (int i=0; i<arity; i++) {
bindings=bindings.assoc(params[i], args[i]);
}
Environment e=body.compute(env, bindings);
while (true) {
Object ro=e.getResult();
if (ro instanceof ReturnResult) return ((ReturnResult) ro).value;
if (!(ro instanceof RecurResult)) break;
RecurResult re=(RecurResult) ro;
for (int i=0; i<arity; i++) {
bindings=bindings.assoc(params[i], re.values[i]);
}
e=body.compute(e,bindings);
}
return e.getResult();
}