I think one of Emacs' design decisions was deliberately not going fully functional, but having global state and different scoping (Was it "dynamically scoped"? I always forget, which one is which.), because threading everything through all the functions would be quite complicated.
However, it may be possible to interact with Emacs using Elisp in a quite functional way.
Many early lisps had dynamic scoping only. It meant that this code would return 5
(defvar x 1) ; new global var
(defun foo () x) ; function returns x
(+ (let ((x 4)) (foo)) (foo)) ; => 5
It also meant that anonymous functions weren’t closures. Later on, scheme used lexical scoping and Common Lisp used lexical scoping normally with dynamic scoping for special (typically global) variables like standard-input. At the time, implementers were worried that they wouldn’t be able to do lexical scoping efficiently.
Emacs lisp only had dynamic scoping for a long time. Furthermore it had buffer-local-variables where the editor has a notion of the current buffer, buffers can have definitions of variables, and the value you get for a variable depends on what it is bound to within that buffer as well as dynamically. Over time elisp got true closures/lexical scope, first via a library and later as a language feature (if a certain buffer-local variable is set when you compile/evaluate a file, you get lexical scoping; the easy way to set it is by writing a specially formatted line in the file which allows emacs to set ‘safe’ buffer local variables on opening the file.
I knew, that Elisp got lexical scoping at some point, but do you know, whether package authors now use it often or maybe even more than dynamic scoping?
Also thanks for the practical example of when it makes a difference!
However, it may be possible to interact with Emacs using Elisp in a quite functional way.