aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcolin <colin@cicadas.surf>2023-09-16 10:06:21 -0700
committercolin <colin@cicadas.surf>2023-09-16 10:06:21 -0700
commitffdcc3c6154aa5a77314e240621ff10a3e6c26e3 (patch)
tree41e85718cad4e939a9c953f33a5348c830fdf282
Initial commitmaster
-rw-r--r--README.org47
-rw-r--r--forget.asd10
-rw-r--r--forget.lisp39
-rw-r--r--package.lisp5
4 files changed, 101 insertions, 0 deletions
diff --git a/README.org b/README.org
new file mode 100644
index 0000000..3f845ac
--- /dev/null
+++ b/README.org
@@ -0,0 +1,47 @@
+* forget
+
+Forget things about symbols. Handy during interactive development.
+
+The `forget` function will forget function bindings, symbol bindings,
+and class bindings. It will also unintern a symbol from its home package.
+
+The `forget` function can forget packages too, but you must pass
+`:package? t` as an argument.
+
+Any of the default options can be turned off by passing `nil` to the
+appropriate option. E.g. if you wanted to forget everything but not
+unintern the symbol, you'd pass `:intern? nil`.
+
+Example:
+
+#+begin_src lisp
+CL-USER> (defvar unremarkable "hey")
+UNREMARKABLE
+
+CL-USER> (defun unremarkable () "hey")
+UNREMARKABLE
+
+CL-USER> (defclass unremarkable () ())
+#<STANDARD-CLASS COMMON-LISP-USER::UNREMARKABLE>
+
+CL-USER> (setf (get 'unremarkable :hey) "you")
+"you"
+
+CL-USER> (defpackage :unremarkable (:use #:cl))
+#<PACKAGE "UNREMARKABLE">
+
+CL-USER> (forget:forget 'unremarkable)
+WARNING: Unbinding function UNREMARKABLE
+WARNING: Unbinding value UNREMARKABLE
+WARNING: Unbinding class UNREMARKABLE
+WARNING: Dropping symbol-plist on UNREMARKABLE
+WARNING: Uninterning UNREMARKABLE from "COMMON-LISP-USER"
+NIL
+
+CL-USER> (forget:forget 'unremarkable :package? t)
+WARNING: Uninterning UNREMARKABLE from "COMMON-LISP-USER"
+WARNING: Deleting package "UNREMARKABLE"
+T
+CL-USER>
+
+#+end_src
diff --git a/forget.asd b/forget.asd
new file mode 100644
index 0000000..899dfa8
--- /dev/null
+++ b/forget.asd
@@ -0,0 +1,10 @@
+;;;; forget.asd
+
+(asdf:defsystem #:forget
+ :description "Development utility to forget everything about a symbol"
+ :author "Colin <colin@cicadas.surf>"
+ :license "Unlicense"
+ :version "0.0.1"
+ :serial t
+ :components ((:file "package")
+ (:file "forget")))
diff --git a/forget.lisp b/forget.lisp
new file mode 100644
index 0000000..cd2444e
--- /dev/null
+++ b/forget.lisp
@@ -0,0 +1,39 @@
+;;;; forget.lisp
+
+(in-package #:forget)
+
+(defun forget (symbol &key
+ (function? t)
+ (value? t)
+ (class? t)
+ (plist? t)
+ (interns? t)
+ (package? nil))
+ "Uninterns and forgets everything about a symbol"
+ (assert (symbolp symbol) (symbol) "~s is not a symbol." symbol)
+
+ (when (and function? (fboundp symbol))
+ (warn "Unbinding function ~s" symbol)
+ (fmakunbound symbol))
+
+ (when (and value? (boundp symbol))
+ (warn "Unbinding value ~s" symbol)
+ (makunbound symbol))
+
+ (when (and class? (find-class symbol nil))
+ (warn "Unbinding class ~s" symbol)
+ (setf (find-class symbol) nil))
+
+ (when (and plist? (symbol-plist symbol))
+ (warn "Dropping symbol-plist on ~s" symbol)
+ (setf (symbol-plist symbol) nil))
+
+ (when interns?
+ (warn "Uninterning ~s from ~s"
+ symbol
+ (package-name (symbol-package symbol)))
+ (unintern symbol (symbol-package symbol)))
+
+ (when (and package? (find-package symbol))
+ (warn "Deleting package ~s" (package-name (find-package symbol)))
+ (delete-package (find-package symbol))))
diff --git a/package.lisp b/package.lisp
new file mode 100644
index 0000000..5190795
--- /dev/null
+++ b/package.lisp
@@ -0,0 +1,5 @@
+;;;; package.lisp
+
+(defpackage #:forget
+ (:use #:cl)
+ (:export #:forget))