Joseph Wright wrote:
> I've also started splitting \keys_manage:n into a \keys_define:n and a
> \keys_set:n function. For the moment, this is just cosmetic but I may do
> something more serious later. 

I've taken another look at things, and have completely re-modelled the
internals of key3.  Things now work as follows. For creating keys:

\keys_define:nn { module } {
  key-one   .code:n    = {Code, parameter #1, etc.},
  key-two   .set:N     = \l_module_var_tl,
  key-two   .value_required:,
  key-three .set:N     = \g_module_var_int,
  key-three .default:n = 0,
  key-four  .generate_choices:nn = {a,b,c,d} {
    Choice~`\l_keys_choice~tl'~is~number~\int_use:N \l_keys_choice~int
  }
}

Then to use them:

\keys_set:nn { module } {
  key-one   = value,
  key-two   = value,
  key-three = 3,
  key-four  = a
}

As you can see, I've attempted to simplify the structure, and creating
keys is now a bit more like the method used in template. On the other
hand, I've stuck with "properties" and not having them as single tokens.
I've also kept the multiple choices idea and value required/forbidden.

I've just uploaded the update to CTAN, so I imagine it will wend its way
around the world over the next 24 hours.
-- 
Joseph Wright