Once a parameter X is bound to a value when a function F starts executing, X keeps that value. This is a lot like being a constant, but X can have different values each time F is executed. However, LISP didn't stay purely functional. Today, most LISP programmers seem to rely heavily on SETQ which is LISP's form of the assignment statement. LISP's mutation is not surprising.
Functional programming is anything but popular.
I won't advocate it here. Another approach is to permit assignments to X but only under controlled circumstances. The important thing is that X is fixed very, very early in a very, very simple way and then remains unchanged. Before one of these subprograms has executed, X is undefined. After any one of them has executed X is constrained to satisfy some condition.