3 ms·
Except that this is not a callback issue. It's an issue of circular dependencies - callbacks are merely the chosen dependency injection vehicle for this particu
by groby_b 12y ago
Except that this is not a callback issue. It's an issue of circular dependencies - callbacks are merely the chosen dependency injection vehicle for this particular item.
The message pumping example the author gives has the exact same issue. The core here is that two items (database & logger) are mutually dependant. That will always be an issue. It doesn't matter if your promises are circularly dependant, your context objects, your callbacks, or your globals.
Static analysis won't help - fully resolving circular dependencies is equivalent to solving the halting problem, IIRC.
And so the only way to prevent those dependencies is to constrain the design in a way that prevents circular dependencies. That's where the ad-hoc rules mentioned in the article stem from. They artificially restrain the problem space to prevent (classes of) circular dependencies.
- rian 12y agoYes, the core issue in the database logger example is that it's a circular dependency. The point of the article is that callback-based APIs like this obscure the actual problems (like circular dependencies). You're right that constrained designs prevents issues like these but callback-based APIs aren't inherently constrained. They allow anything to happen, which is why they conversely encourage errors like these (and are subject to pitfalls).
- groby_b 12y agoWhat would be an inherently constrained API, then? I've successfully managed to create circular dependencies in quite a few different styles, so I'd love to find one that saves me from myself ;)
- rian 12y agoMaybe inherently was the wrong word. Though you can imagine a logger API that was like this: typedef enum { CONSOLE_LOGGER, DATABASE_LOGGER, /* etc. */ } LoggerType; void add_logger(LoggerType); In this API you're constrained by what loggers you can add. It's not the totally unchecked free-for-all that a callback-based API provides. The user is strictly unable to shoot themselves in the foot. But this limits the expressive power that callbacks provide. Sorry I don't have any other API recommendations. The only way I can think of to stay expressive while safeguarding against unintended abuse is to include code analysis.
- markuz 12y agoI was thinking the same thing. It has nothing to do with callbacks. > fully resolving circular dependencies is equivalent to solving the halting problem, IIRC. I don't think so. Any good dependency injection framework would detect this kind of circular dependency.
- groby_b 12y agoOf logger and DB, certainly. The coupling introduced via locks is harder to detect. But most importantly, circular dependency between components might be OK in a path-dependent way - that's what I meant by fully resolving it. Just analyzing the dependency graph of injected components is indeed just a topological sort.