diff options
author | Vincent Ambo <tazjin@google.com> | 2020-01-17T18·04+0000 |
---|---|---|
committer | Vincent Ambo <tazjin@google.com> | 2020-01-17T18·04+0000 |
commit | 0a9a56953435382fa00357efb489860cee600a58 (patch) | |
tree | f7d6f418a93b5a8b1a94fe43742f48241c48daac /third_party/lisp/alexandria/definitions.lisp | |
parent | 30e4e5eefcd65c6fc1a3f37a90822ab1041576e0 (diff) | |
parent | 95aeb2ebae32a01ff79644daa523bda5d8552863 (diff) |
Merge commit '95aeb2ebae32a01ff79644daa523bda5d8552863' as 'third_party/lisp/alexandria' r/394
Diffstat (limited to 'third_party/lisp/alexandria/definitions.lisp')
-rw-r--r-- | third_party/lisp/alexandria/definitions.lisp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/third_party/lisp/alexandria/definitions.lisp b/third_party/lisp/alexandria/definitions.lisp new file mode 100644 index 000000000000..863e1f696286 --- /dev/null +++ b/third_party/lisp/alexandria/definitions.lisp @@ -0,0 +1,37 @@ +(in-package :alexandria) + +(defun %reevaluate-constant (name value test) + (if (not (boundp name)) + value + (let ((old (symbol-value name)) + (new value)) + (if (not (constantp name)) + (prog1 new + (cerror "Try to redefine the variable as a constant." + "~@<~S is an already bound non-constant variable ~ + whose value is ~S.~:@>" name old)) + (if (funcall test old new) + old + (restart-case + (error "~@<~S is an already defined constant whose value ~ + ~S is not equal to the provided initial value ~S ~ + under ~S.~:@>" name old new test) + (ignore () + :report "Retain the current value." + old) + (continue () + :report "Try to redefine the constant." + new))))))) + +(defmacro define-constant (name initial-value &key (test ''eql) documentation) + "Ensures that the global variable named by NAME is a constant with a value +that is equal under TEST to the result of evaluating INITIAL-VALUE. TEST is a +/function designator/ that defaults to EQL. If DOCUMENTATION is given, it +becomes the documentation string of the constant. + +Signals an error if NAME is already a bound non-constant variable. + +Signals an error if NAME is already a constant variable whose value is not +equal under TEST to result of evaluating INITIAL-VALUE." + `(defconstant ,name (%reevaluate-constant ',name ,initial-value ,test) + ,@(when documentation `(,documentation)))) |