bubble-operator-upwards is a function that "bubbles an operator upwards" in a form, demultiplexing all alternative branches 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.
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")))
First of all, in the way of packages there's the
bubble-operator-upwards package, which is also nicknamed
bubble-op-up. It exports the functions
(:import-from) only those you need or explicitly package-qualify the symbols. Don't
bubble-operator-upwardsoperator form &key (result-kind
nil) (collapsed-identity (ecase result-kind ((:full
:abridged) (list operator)) (:branches
nil))) => result
Bubbles operator upwards in form, demultiplexing all alternative branches by way of cartesian product. Hard to describe formally, but the examples above should give some inspiration for the basic effect, and some experimentation in the REPL is recommended.
result-kind is one of
:branchessimply returns the demultiplexed branches.
:fullreturns the same result as
:brancheswould, except wrapped in a cons whose CAR is operator.
:abridgedreturns the same result as
:fullwould, except if there's only one branch, only that branch is returned, without the wrapping.
if-collapsed and collapsed-identity determine what to do if the number of branches "collapses" to zero. if-collapsed is
nil. If it's
niland the result is indeed collapsed, then the value of collapsed-identity will be returned.
cartesian-product&rest possibility-groups => cartesian-product
Returns the cartesian-product of all possible combinations from possibility-groups, as a list. This function is inherently needed to implement
bubble-operator-upwards, so might as well export it...
cartesian-product'(1 2) '(a b c)) => ((1 A) (1 B) (1 C) (2 A) (2 B) (2 C))