An observation is that 'or-max' cannot currently be defined by the user, because there is no way to expand rx forms explicitly. One way to fill that hole is to add the function (rx-expand-definitions RX-FORM) which would expand RX-FORM until it no longer is a user-defined form. This would permit or-max to be defined as (rx-define or-max (&rest forms) (eval `(regexp ,(regexp-opt (or-max-strings (list forms)))))) (defun or-max-strings (args) (mapcan (lambda (item) (pcase item ((pred stringp) (list item)) (`(or-max . ,rest) (or-max-strings rest)) (_ (error "Illegal `or-max' argument: %S" item)))) (mapcar #'rx-expand-definitions args))) Of course, if the 'or-max' operator is generally useful, it would probably still make sense to define it as a primitive.