There is no real definition in Dave Thomas' video presentation.
Therefore I stick to the definition Don Stewart gives in his PhD cited in your question.
Dave Thomas mentiones in his video that a functional language "potentially allows runtime code swapping" because "it is pure".
The notion of a pure function means that the function does not have an internal state.
The arguments of the function completely determine its output. That would fit nicely to Don's definition.
It also gives a hint how your question must be answered: The answer is: "Yes and No depending on the code."
Yes
Function definitions
Nowadays one is encouraged to use lexical binding.
Let us define a function f
on lexical top-level.
In the following Elisp code fragments the evaluation results are given in the comments following the Elisp forms.
(defun f (x)
"Pure function"
(1+ x))
;; f
(symbol-function 'f)
;; (closure (t) (x) "Pure function" (1+ x))
The lexical environment does just hold a t
which is the symbol standing for "true" and evaluating to itself. The closure holds no state at all and we have a pure function which can be replaced by binding f
's function cell to another (pure) closure.
If we consider the contents of the value cells of all symbols as the current state of the Elisp runtime then swapping the pure function does not change the state of the Elisp runtime.
Note: Here we completely ignore that the function cells of the symbols actually also contribute to the state of the runtime. But that is also covered by Don's definition because the values of the function cells more or less represent the code fragments whose Don is speaking of.
Library reloading
Symbols for variables of a library should be declared as special by defvar
on top-level of the library. A default value can be passed as argument to defvar
. The value cell of the dynamic variable is is only bound to the given default value if it is not yet bound, i.e., it is not set yet.
If only devar
and defun
are used on top-level of the library and no setq
or function evaluation then the state of the library is even preserved when one reloads the library with (load-file "someLibName.el")
or (load-library "someLibName.el")
.
Thereby, the newly loaded library can also be a modified version of the first-loaded one. Naturally, it should use its dynamic variables in a compatible way.
No
Function definitions
Closures get a lexical environment with lexically bound symbols if they are defined in the context of a (nontrivial) let
-binding.
If one redefines the closure in a separate evaluation of the (same) let
form the newly defined closure has a fresh lexical environment.
It can no longer access the lexical bindings from the first evaluation of the let
binding.
That means that closures with nontrivial lexical environment have an internal state and that state is lost if one redefines the closure through reevaluation of the let
form.
The following code demonstrates the effect:
;; -*- lexical-binding: t -*-
(defun my-definitions ()
(let ((state 1))
(defun my-set-state (x)
(setq state x))
(defun my-get-state ()
state)))
;; my-definitions
(my-definitions)
;; my-get-state
(defalias 'my-save-fun (symbol-function 'my-set-state))
;; my-save-fun
(my-definitions)
;; my-get-state
(symbol-function 'my-save-fun)
;; (closure ((state . 1) t) (x) (setq state x))
(symbol-function 'my-set-state)
;; (closure ((state . 1) t) (x) (setq state x))
(symbol-function 'my-get-state)
;; (closure ((state . 1) t) nil state)
(eq (cadr (symbol-function 'my-set-state)) (cadr (symbol-function 'my-get-state)))
;; t ;; `my-set-state' and `my-get-state' have the same lexical environment
(eq (cadr (symbol-function 'my-set-state)) (cadr (symbol-function 'my-save-fun)))
;; nil ;; `my-save-fun' and `my-get-state' look very alike but they have differing lexical environments
(my-save-fun 2)
;; 2 ;; setting state of `my-save-fun' to 2
(my-get-state)
;; 1 ;; state of `my-get-state' remains 1
(my-set-state 3)
;; 3 ;; set state of `my-set-state' and `my-get-state' to 3
(my-get-state)
;; 3 ;; Voila...
Library reloading
If one sets the value of dynamically bound variables in a library with setq
its previously set value is lost.
Thus reloading such a library destroys the state of the runtime.
Needless to say that function evaluation on top-level of a library can also modify the values of the dynamic variables of the library.