def let(args, env):
    var_list = args.car
    body = args.cdr
    argnames = cons_list(i.car for i in var_list)
    arg_values = cons_list(scheme_eval(i.cdr.car, env) for i in var_list)
    l = create_lambda(Cell(argnames, body), env)
    return l(arg_values)
def scheme_wrap(expr):
    if isinstance(expr, bool):
        return scheme_true if expr else scheme_false
    elif isinstance(expr, Real):
        return Number(expr)
    elif isinstance(expr, str):
        return String(expr)
    elif isinstance(expr, Iterable):
        return cons_list(map(scheme_wrap, expr))
    else:
        return expr
 def __call__(self, arguments):
     if type(self.argnames) is Symbol:
         name_bind = {self.argnames: arguments}
     elif Symbol('.') in self.argnames:
         names_l = list(self.argnames)
         args_l = list(arguments)
         positionals = names_l.index(Symbol('.'))
         name_bind = {s: v for s, v in zip(names_l[:positionals], args_l[:positionals])}
         name_bind[names_l[positionals + 1]] = cons_list(args_l[positionals:])
     else:
         name_bind = {s: v for s, v in zip(self.argnames, arguments)}
     call_env = Environment(self.parent_env, name_bind)
     return scheme_eval(self.code, call_env)
def scheme_eval_list(lst, env):
    return cons_list(map(lambda x: scheme_eval(x, env), iter(lst)))
def scheme_if(args, env):
    return cond(cons_list([cons_list([args.car, args.cdr.car]), 
                    cons_list([Symbol('else'), args.cdr.cdr.car])]), env)