Is function application actually a memory manipulation algorithm? I thought about how in lambda calculus (and many implementations of functional programming languages) function (lambda) application and lambda itself, as a construct, are "primitive things", usually somehow implemented by an interpeter. Then I thought, can you "boil-down" these two things to more primitve stuff.
For instance, we have a following expression (apply is usually implicit by the syntax convetions, but whatever)

(apply (\x.\y.x) (a b))  

The interpreter:
1. Constructs a new environment, where arguments are bound to lambda's terms, i.e. new_env = this_env.append({"x":a, "y":b, "body":"x"})
2. Performs a rewrite of the whole application term with lambda's body, i.e.
  new_env["body"]   

Given only the environment manipualtion "primitives", like: "construct", "append", and "get", doesn't that make whole lambda calculus just a clever trick to hide memory ("tape") mutations? Now I know that turing machine and lambda calculus are equivalent, but is there something more to LC than just what I've described? What have I missed?
That seems reasonable to me, although I've never thought of other that way.  The critical point is that LC essentially involves variables and substitution.  So I wouldn't say it "hides" memory ops, exactly, that's just how LC substitution translates to Turing machinery.  On the other hand, substitution is not primitive - combinatory logic eliminates both variables and substitution.  So you might say LC introduces rather than hides something.