The major problem with function calls in most languages (ie. not Haskell) is the call-by-value evaluation order.
Another problem that keeps us from replacing macros with functions is that function arguments can't be the binding position that introduces a new variable. To use an old classic example,
(let ((x 3)
(y 4))
(+ x y))
could be translated to ((lambda (x y) (+ x y)) 3 4), but no function could introduce new names `x' and `y' into scope. Scope is a compile time notion, and a function happens at run time.
Another problem that keeps us from replacing macros with functions is that function arguments can't be the binding position that introduces a new variable. To use an old classic example,
could be translated to ((lambda (x y) (+ x y)) 3 4), but no function could introduce new names `x' and `y' into scope. Scope is a compile time notion, and a function happens at run time.