bubble-operator-upwards demultiplexes all alternative branches in a form by way of cartesian product. This operation is notably useful for easy implementation of certain kinds of shorthand notations in macros. A cartesian-product function is also exported, as it's needed to implement the main function.

Some examples:

(bubble-operator-upwards 'and '(plate (and ham eggs) beans)) => (AND (PLATE HAM BEANS) (PLATE EGGS BEANS)) (bubble-operator-upwards 'alt '(section (alt 1 2 3) - (alt "a" "b")) :result-kind :branches) => ((SECTION 1 - "a") (SECTION 1 - "b") (SECTION 2 - "a") (SECTION 2 - "b") (SECTION 3 - "a") (SECTION 3 - "b")) (bubble-operator-upwards 'or '(>> (or ul ol) (or (:class (or "important" "urgent")) (id "first-priority")))) => (OR (>> UL (:CLASS "important")) (>> UL (:CLASS "urgent")) (>> UL (ID "first-priority")) (>> OL (:CLASS "important")) (>> OL (:CLASS "urgent")) (>> OL (ID "first-priority")))

bubble-operator-upwards is in Quicklisp:

(ql:quickload "bubble-operator-upwards")

See the project's home for further information. Actual documentation is in the README.
This library is in the Public Domain. See the UNLICENSE file for details.