If you want to mirror how e.g. `Times` works, then what you want to do is exploit the `OneIdentity` attribute (which `NonCommutativeMultiply` already has), `Default` values and `Optional` patterns, and an identity value for `NonCommutativeMultiply`. If `f` has the attribute `OneIdentity`, that means that `f[x]`, `f[f[x]]`, etc. will match `x`. `Optional` patterns match a pattern to a provided default value if the expression does not appear. But there are two ways to provide a default value: either inline or via a value that's globally associated with the enclosing head. For example, if we have `f[a_:0, b_] := {a,b}`, then `f[2]` will be `{0,2}` thanks to the inline `Optional` pattern `a_:0`. But we could also use `f[a_., b_]` (`a_.` is `Optional[a]`) together with a separate evaluation of `Default[f] = 0` to get the same result. This works for pattern matching too: e.g. `Default[Times]` is `1`, and `f[Times[x_.,3]] := x` means that `f[3 y]` gives `y`, while `f[3]` gives `1`. The `OneIdentity` attribute means that `3` matches `Times[3]` which matches `Times[x_.,3]`. To be honest, I'm not 100% sure why `b+c` doesn't then match `NonCommutativeMultiply[a___,b_+c_,d___]`. It seems `OneIdentity` only meshes well with `Optional` patterns. However, it *does* match `NonCommutativeMultiply[a_., b + c, d_.]`. Here's a gotcha to watch out for: the `Default` value must be set *before* any definitions involving default patterns are evaluated. I suspect `Optional` is partially magical. ### Making `NonCommutativeMultiply` behave well We then also need to actually make our `Default` value actually behave like an identity for `NonCommutativeMultiply`. To do this, we add a definition using the intercept trick. We *also* need to make `NonCommutativeMultiply[a]` be `a` and `NonCommutativeMultiply[]` be the default value. Due to, I suspect (but possibly not), the magic of `Optional`, we need to temporarily clear `NonCommutativeMultiply`'s attributes while setting that definition. So, putting it all together: ``` Unprotect[NonCommutativeMultiply]; Default[NonCommutativeMultiply] = 1; (* or whatever value you'd like here *) Block[{a = Attributes[NonCommutativeMultiply]}, Attributes[NonCommutativeMultiply] = {}; NonCommutativeMultiply[a_.] := a; Attributes[NonCommutativeMultiply] = a; ]; NCMIntercept = True; NonCommutativeMultiply[a_, b__] := Block[{NCMIntercept = False}, NonCommutativeMultiply @@ DeleteCases[{a,b}, Default[NonCommutativeMultiply]] ] /; NCMIntercept Protect[NonCommutativeMultiply, NCMIntercept]; NCExpand[a_. ** (b_ + c_) ** d_.] := a ** b ** d + a ** c ** d ``` (Note that while `NCExpand[b + c]` works as expected, `NCExpand[b]` is still undefined! Another definition (`NCExpand[a_] := a`) is needed.) It is possible to do this a bit differently if you want `NonCommutativeMultiply[a]` to not evaluate further (the default behavior), perhaps by using `Default[NonCommutativeMultiply] := Sequence[]`. I haven't explored this though. Hope this helps! :)