https://sep.yimg.com/ty/cdn/paulgraham/onlisp.pdf On page 36 Paul writes the following:

The conditions above do not guarantee the perfect locality you get with purely functional code, though they do improve things somewhat. For example, suppose that f calls g as below:

(defun f (x)
  (let ((val (g x)))
    ; safe to modify val here?

Is it safe for f to nconc something onto val? Not if g is identity: then we would be modifying something originally passed as an argument to f itself. So even in programs which do follow the convention, we may have to look beyond f if we want to modify something there. However, we don’t have to look as far: instead of worrying about the whole program, we now only have to consider the subtree beginning with f.

I don't understand what he means by saying that it is not safe for f to nonc if g is identity. Or I suppose I don't understand the idea that he's trying to convey in this paragraph in general.


He's talking about side-effects of calling a function (and whether they can be avoided).

A purely functional language would not allow a call to f(x) to modify the value of the argument being passed to that function; but because nconc is destructive, that's exactly what would happen here if g was the identity function (as then val would refer to the same cons cell as the argument to f).

I.e. val would not be a value which was local to the function.

Not the answer you're looking for? Browse other questions tagged or ask your own question.