@Override
	public Expr apply(Expr[] args, InterpContext ctx) throws RuntimeError {
		if (args.length != 2)
			throw new RuntimeError("macro-exp: bad syntax");
		if (args[0] == EMPTY_LIST)
			return new Macro(new Symbol[0], args[1], ctx.env);
		if (listq(args[0])) {
			Expr[] list = toExprArray(args[0]);
			Symbol[] ids = new Symbol[list.length];
			for (int i = 0; i < ids.length; i++) {
				if (!(list[i] instanceof Symbol))
					throw new RuntimeError("macro-exp: not an identifier");
				ids[i] = (Symbol)list[i];
			}
			int i = hasDuplicate(ids);
			if (i >= 0)
				throw new RuntimeError("macro-exp: duplicate argument name: " + ids[i]);
			return new Macro(ids, args[1], ctx.env);
		}
		throw new RuntimeError("macro-exp: bad argument");
	}