Hi Joseph, This looks really great! I'm especially fond of the 'opt-in' vs. 'opt-out' split. Thank you for putting in all the effort (and this has been very useful to me regardless of the final product - I always learn a lot reading your code). > I don't see a lot a real use cases for nesting, while I do see > quite a bit of complexity in allowing it! Agreed. > Worth bearing in mind that grouping is intended for the case > where you want to have a 'second axis' for keys. If you always > want to be able to set stuff in an order, then > \keys_set_known:nnN plus subtrees already works. Sure - that's what I've been doing, too, in the packages I'm working on. The filtering mechanism would still simplify this for cases where different subsets of keys need to be set in order in different places, but I'm not thinking of this as the primary function of storing the unused key. It was just the first example to pop to mind. Another use that I can think of off the top of my head is that it allows us to easily give detailed warnings to users when they're attempting to use keys in contexts where they shouldn't be. > The following implements that, but note that you will need the 'burning > edge' expl3 from GitHub/SVN as I've made some adjustments to the l3keys > code to allow for things we certainly will want whatever the final form > of groups/families. Saw that. :) I'm still not entirely sure about the handling of unknown keys. On the one hand, I think there is a substantial conceptual difference between keys that shouldn't be set because they're not in a group on the 'opt-in' list or they're in a group on the 'opt-out' list, and keys that cannot be set because they're undefined. For one, I expect users are likely to pass a disallowed key to a document command because they've not read the the documentation carefully enough (and then such a key can be filtered out), but when they pass an undefined key, they're likelier to have just made a typo. So they should get different notifications in the two cases. On the other hand, I agree that passing an undefined key to \keys_set_groups:nnn should normally be less bad than passing such a key to \keys_set_filtered:nnn. Maybe unknown key errors should be demoted to warnings in this case? Perhaps it would be altogether better to have both a \__keys_store_unused: and a \__keys_store_unknown: with two associated clists, and then distinguish between \keys_set_<groups/filter>:nnn and \keys_set_known_<groups/filter>:nnn (and possibly have a \keys_set_known_<groups/filter>:nnnNN in addition to \keys_set_<groups/filter>:nnnN). Finally, there's a small bug in the definition of \keys_set_filter:nnnN. Should be \cs_new_protected:Npn \keys_set_filter:nnnN #1#2#3#4 { \clist_clear:N \l__keys_unused_clist \keys_set_filter:nnn {#1} {#2} {#3} \tl_set:Nx #4 { \exp_not:o { \l__keys_unused_clist } } } And we're missing \cs_new_protected:Npn \keys_set_groups:nnnN #1#2#3#4 { \clist_clear:N \l__keys_unused_clist \keys_set_groups:nnn {#1} {#2} {#3} \tl_set:Nx #4 { \exp_not:o { \l__keys_unused_clist } } } I also expect you wrote this before including \__keys_store_unused: in the GitHub version, so it's not needed again here.