         //Assign a name for this temporary closure
         let fname = "TMP$"+String(arc4random_uniform(UInt32.max))
         
-        let f: (SExpr)->SExpr = { params in
+        let f: (SExpr, [SExpr]?, [SExpr]?)->SExpr = { params,locals,values in
             guard case var .List(p) = params else {return .List([])}
             p = Array(p.dropFirst(1))
             //Remove temporary closure
             localContext[fname] = nil
             
             // Replace parameters in the lambda with values
-            if let result = lambda.replace(this:vars, with:p).eval(){
+            if let result = lambda.eval(with:vars, for:p){
                 return result
             }else{
                 return .List([])



/// Local environment for locally defined functions
public var localContext = [String: (SExpr)->SExpr]()

/// Global default builtin functions environment
///
/// Contains definitions for: quote,car,cdr,cons,equal,atom,cond,lambda,label,defun.
private var defaultEnvironment: [String: (SExpr)->SExpr] = {
    
    var env = [String: (SExpr)->SExpr]()
    env[Builtins.quote.rawValue] = { params in
        guard case let .List(parameters) = params, parameters.count == 2 else {return .List([])}
        return parameters[1]
    }
    env[Builtins.car.rawValue] = { params in
        guard case let .List(parameters) = params, parameters.count == 2 else {return .List([])}
        guard case let .List(elements) = parameters[1], elements.count > 0 else {return .List([])}
        
        return elements.first!
    }
    env[Builtins.cdr.rawValue] = { params in
        guard case let .List(parameters) = params, parameters.count == 2 else {return .List([])}
        
        guard case let .List(elements) = parameters[1], elements.count > 1 else {return .List([])}
        
        return .List(Array(elements.dropFirst(1)))
    }
    env[Builtins.cons.rawValue] = { params in
        guard case let .List(parameters) = params, parameters.count == 3 else {return .List([])}
        
        guard case .List(let elRight) = parameters[2] else {return .List([])}
        
        switch parameters[1]{
        case .Atom:
            return .List([parameters[1]]+elRight)
        default:
            return .List([])
        }
    }
    env[Builtins.equal.rawValue] = {params in
        guard case let .List(elements) = params, elements.count == 3 else {return .List([])}
        
        var me = env[Builtins.equal.rawValue]!
        
        switch (elements[1],elements[2]) {
        case (.Atom(let elLeft),.Atom(let elRight)):
            return elLeft == elRight ? .Atom("true") : .List([])
        case (.List(let elLeft),.List(let elRight)):
            guard elLeft.count == elRight.count else {return .List([])}
            for (idx,el) in elLeft.enumerated() {
                let testeq:[SExpr] = [.Atom("Equal"),el,elRight[idx]]
                if me(.List(testeq)) != SExpr.Atom("true") {
                    return .List([])
                }
            }

     - Parameter environment: A set of named functions or the default environment
     - Returns: the resulting SExpression after evaluation
     */
    public func eval(with locals: [SExpr]? = nil, for values: [SExpr]? = nil) -> SExpr?{
        var node = self
        
        switch node {
        case .Atom:
            return evaluateVariable(node, with:locals, for:values)
        case var .List(elements):
            var skip = false
            
