Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancing hooks #41

Open
Ambrevar opened this issue Oct 4, 2019 · 11 comments
Open

Enhancing hooks #41

Ambrevar opened this issue Oct 4, 2019 · 11 comments

Comments

@Ambrevar
Copy link

Ambrevar commented Oct 4, 2019

Serapeum has simple hooks, but while working with Next I figured they might not be enough.

In Next we use
https://github.com/scymtym/architecture.hooks mostly because I didn't know that Serapeum had hooks :p cl-hooks and Serepeum hooks seem to overlap a lot.

We've discussed some of the shortcomings of cl-hooks there:
https://github.com/scymtym/architecture.hooks/issues.
In short:

  • It'd be nice to have a hook type.
  • It'd be nice to have the ability to list all hooks, if possible without a global variable.
  • It'd be nice to be able to customize how hooks execution is composed. For instance, some hooks might return a list of values, others could be executed in reverse order, others could be reduced (the next hook takes as argument the return value of the previous one -- great for chaining filters!).

What's most problematic with hooks and as the Emacs experience has showed us is that they don't play well with lambda functions:

  • Lambdas are effectively blackboxes once added to the hook.
  • Lambdas don't compare, so adding the same lambda twice will stack it instead of being ignored.

We discussed this here: atlas-engineer/nyxt#419.

My solution to this was to implement a "handler" type which would allow the user to add anonymous functions to a hook but with extra data so that the handler can be compared and introspected to some extent.

Thoughts?
Let me know if this is a bit obscure, I can provide more examples.

@ruricolist
Copy link
Owner

You definitely have a point. The big advantage of hooks in Emacs is that they don't require coordination -- you can push to a hook even before the library that defines it is loaded. That doesn't work in CL, where you have to wait for the package. (I suppose you could use keywords as hooks, but that's disgusting.)

I'll read the discussions you linked. I do really like the idea of having something analogous to method combinations for hooks.

@ruricolist
Copy link
Owner

Note to self: cf. SRFI 173.

@ruricolist
Copy link
Owner

A thought: with indirection we gain the ability to check the arity of the supplied function by doing runtime compilation of a lambda: e.g. if the user provides function f we can compile (lambda (x) (funcall f x)) and the compiler might tell us if the arity is wrong.

@Ambrevar
Copy link
Author

Ambrevar commented Oct 5, 2019 via email

@Ambrevar
Copy link
Author

Ambrevar commented Oct 5, 2019 via email

@Ambrevar
Copy link
Author

Ambrevar commented Oct 5, 2019

I can work on a patch if you like.

By the way, moving to hook type will break the current implementation. What's the policy of Serapeum regarding backward compatibility?

ruricolist added a commit that referenced this issue Oct 7, 2019
@ruricolist
Copy link
Owner

I've converted the current implementation to use generic functions, so it should be possible to maintain backward compatibility with a dedicated hook class.

@Ambrevar
Copy link
Author

Ambrevar commented Oct 7, 2019

Great!

Discussing with @scymtym from cl-hooks (scymtym/architecture.hooks#5 (comment)) I figured the following regarding "global, ahead of definition hooks":

Have a notion of global hooks that can be optionally associated with a type or an instance.

For instance

  • (find-hook 'foo-hook)
  • (find-hook 'foo-hook 'bar-class)
  • (find-hook 'foo-hook (make-instance 'bar-class))

would return 3 different hooks (I came up with the helper functions here).

@Ambrevar
Copy link
Author

atlas-engineer/nyxt#483 is mostly ready. Would you consider merging them here?

@ruricolist
Copy link
Owner

I've added enhanced hooks to Serapeum. Since they involve a fair amount of new exports, however, I've taken a different approach: Serapeum now has a contrib/ directory, and the enhanced hooks are implemented in a new package, :serapeum/contrib/hooks.

@Ambrevar
Copy link
Author

Ambrevar commented Jul 4, 2020 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants