I am trying to define a replacement rule with optional argument color_RGBColor which should be replaced with Sequence[] when it is absent in the original expression:
style[line_Line, ___,
color_RGBColor: Unevaluated@Sequence[], ___] :> {color, line}
When RGBColor is present in the original expression, the rule works:
style[Line[], RGBColor[{}]] /.
style[line_Line, ___,
color_RGBColor: Unevaluated@Sequence[], ___] :> {color, line}
=> {RGBColor[{}], Line[]}
But when it is absent, it does not:
style[Line[], Thickness[0.01]] /.
Style[line_Line, ___,
color_RGBColor: Unevaluated@Sequence[], ___] :> {color, line}
=> style[Line[], Thickness[0.01]]
My questions are:
1) Why it does not work?
2) Is it possible to construct a single pattern which will work as desired?
Your pattern does not work because of the way the pattern-matching works for the default (optional) arguments, and also because you restricted the head to be
RGBColor. The problem is that the default argument value must match the pattern, whileUnevaluated[Sequence[]]certainly does not match_RGBColor.You have several ways out. A first attempt is to weaken your type-checking:
But this does not work since the matching is incorrect – the typing is indeed too weak. The hacky way to make it work is this:
The recommended way to do it is this:
This feature of the pattern-matcher is not very widely known, so I will stress it again: the default value for the (optional) pattern
x:ptrn:defaultmust matchptrn. For another example of such behavior, see this Mathgroup discussion.