gizmo385/discord.clj

Improve Storage/Management of Extensions/Extension Documentation

Opened this issue · 4 comments

Currently, when extensions are declared, information about those extensions, handlers, and their relevant documentation is maintained in a series of global atoms. This isn't ideal and can cause confusion (see #10) where extensions can be duplicated if files are reloaded without properly clearing out the global atoms.

Ideally, I think we should try and remove this from global state. At the moment, I don't have a great solution to this problem and would love input from others :)

Maybe it could work like add-watch? On atoms, refs, etc you associate a function with a particular reference. It's not super neat but it would allow multiple bot instances with potentially different extensions.

@JasonKDarby I looked at the add-watch documentation and I guess I'm not immediately seeing how add-watch would facilitate multiple bot instances. Can you explain a bit more about the idea? I'd never heard of add-watch and it looks pretty useful!

Maybe we should just store extension and command related information in the same namespace they're declared in, and have a facility that can associate between these bits of data and a specific reference to a bot.

This way, we could have defextension and defcommand describe what an individual bot should do when queried with a defined command, and we'd use @JasonKDarby's idea of an add-watch-like facility to associate between a specific bot and the generally-defined extension behavior: (add-extensions bot & extensions)

Below is an example of how I think the syntax of this might work out, used in a REPL-like setting.

(require '[discord.bot :as bot])
;; Bots are stored as refs using this create-bot facility
(def my-first-bot (bot/create-bot ...))
(def my-second-bot (bot/create-bot ...))
;; Command and Extension info is stored in place using these def-like facilities
(defcommand my-command ...)
(defextension my-extension ...)
;; Commands and Extensions are associated with their bots explicitly using this add-extensions facility
(bot/add-extensions my-first-bot my-command my-extension)
(bot/add-extensions my-second-bot my-extension)
;; Bots can be started independently from the extension adding and bot creation process.
(bot/start my-first-bot)
(bot/start my-second-bot)

defcommand and defextension would have to treat command and extension information like aggregate data though, because there isn't a super clean way to store the functions and docstrings all in one data structure, so given an extension name ext-name, we'd probably have to have a multimethod for calling the function, and a nested map structure for storing and navigating the docstrings, named ext-name-handler and ext-name-doc, respectively.