package jscheme;

/** A closure is a user-defined procedure.  It is "closed" over the
 * environment in which it was created.  To apply the procedure, bind
 * the parameters to the passed in variables, and evaluate the body.
 * @author Peter Norvig, peter@norvig.com http://www.norvig.com 
 * Copyright 1998 Peter Norvig, see http://www.norvig.com/license.html **/

public class Closure extends Procedure {

    Object parms;
    Object body;
    Environment env;
    
    /** Make a closure from a parameter list, body, and environment. **/
    public Closure (Object parms, Object body, Environment env) {
        this.parms = parms;
	this.env = env;
	this.body = (body instanceof Pair && rest(body) == null)
	    ? first(body)
	    : cons("begin", body);
    }

    /** Apply a closure to a list of arguments.  **/
    public Object apply(Scheme interpreter, Object args) {
	return interpreter.eval(body, new Environment(parms, args, env));
    }
}
