-
-
Notifications
You must be signed in to change notification settings - Fork 12
Description
I don't like the once-decorators and I think I should remove them. Decorators can already be added on top (via :@##) and execute again on each reload. But decorators can have arbitrary effects and aren't necessarily idempotent. If you're writing them yourself, write them so they're reloadable. But sometimes one has to use libraries.
There is an easy way to ensure they've only run once after the fact: use a zap@ expression in a defonce. You could have a series of them in a progn as well. It doesn't particularly matter what the resulting value is. A None or () is fine. The fact that the global exists will prevent it from running again on a reload.
Metaclasses may also be tricky. And some are even in the standard library.
One can always use defonce directly on a type() call to work around limitations (or write some modules in Python). Maybe doing tricky things should feel tricky. Make the right way obvious.
deftypeonce can't do __slots__. It has to be done at class creation time and can't be added later. (Or it can, but doesn't work.) This isn't very compatible with reloading anyway. Maybe the docs should recommend using type or types..new_class in certain cases. With a decorator, this almost looks like a class declaration:
:@##X#(types..new_class X.__name__ () None X)
(defun Spam (env)
(.update env : __slots__ '(x y)))
;;; or
(define Spam
(type 'Spam ()
(dict : __slots__ '(x y))))Of course, this is no more reloadable than a normal class statement.