From 65485af4c2fa9b8f7606bdf9dc23a0d0d93cc908 Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 19 Jan 2026 20:10:04 -0500 Subject: [PATCH 1/3] Go over Optional doc --- mathics/builtin/patterns/defaults.py | 74 ++++++++++++++++------------ 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/mathics/builtin/patterns/defaults.py b/mathics/builtin/patterns/defaults.py index f908473e4..d647dbd51 100644 --- a/mathics/builtin/patterns/defaults.py +++ b/mathics/builtin/patterns/defaults.py @@ -19,48 +19,58 @@ class Optional(InfixOperator, PatternObject): - """ - - :WMA link:https://reference.wolfram.com/language/ref/Optional.html + """:WMA link:https://reference.wolfram.com/language/ref/Optional.html
'Optional'[$pattern$, $default$]
'$pattern$ : $default$' -
is a pattern which matches $pattern$, which if omitted - should be replaced by $default$. +
is a pattern matching $pattern$; when $pattern$ is omitted, \ + $default$ is substituted for $pattern$.
+ Optional is used to specify optional arguments in function signatures. + + Set up a default value of 1 for the pattern 'y_' in function 'f': + >> f[x_, y_:1] := {x, y} - >> f[1, 2] - = {1, 2} + + When we specify a value for the 'y' parameter, it has the value provided: + >> f[a, 2] + = {a, 2} + + But if the 'y' parameter is missing, we replace the parameter \ + using the default given in the delayed assignment above: + >> f[a] = {a, 1} - Note that '$symb$ : $pattern$' represents a 'Pattern' object. However, there is no \ - disambiguity, since $symb$ has to be a symbol in this case. - - >> x:_ // FullForm - = Pattern[x, Blank[]] - >> _:d // FullForm - = Optional[Blank[], d] - >> x:_+y_:d // FullForm - = Pattern[x, Plus[Blank[], Optional[Pattern[y, Blank[]], d]]] - - 's_.' is equivalent to 'Optional[s_]' and represents an optional parameter which, if omitted, \ - gets its value from 'Default'. - >> FullForm[s_.] - = Optional[Pattern[s, Blank[]]] - - 'InputForm' shows it in its 'Infix' or 'Postfix' form depending on the \ - number of parameters: - >> InputForm[s_:a+b^2] - = s_ : a + b^2 - Following WMA conventions, - >> InputForm[Optional[s__]] - = (s__.) - >> Default[h, k_] := k - >> h[a] /. h[x_, y_.] -> {x, y} - = {a, 2} + Do not confuse with '$symbol$ : $pattern$', which is also a 'Pattern'. \ + The distinction is to left of the colon. When a $symbol$ is given, we get: + + >> y:1 // FullForm + = Pattern[y, 1] + + Whereas, in an 'Optional' expression, on the left of the colon we have a pattern like 'y_': + + >> y_:1 // FullForm + = Optional[Pattern[y, Blank[]], 1] + + The special form 'y_.' is equivalent to 'Optional[y_]': + + >> FullForm[y_.] + = Optional[Pattern[y, Blank[]]] + + In this situation, when the is 'y' parameter omitted, the value comes from \ + :Default:/doc/reference-of-built-in-symbols/options-management/default/: + + >> Default[g] = 4 + = 4 + + >> g[x_, y_.] := {x, y} + + >> g[a] + = {a, 4} + """ arg_counts = [1, 2] From 673ab860e3afbaf8b43d3abcc072ccf8ab907265 Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 19 Jan 2026 21:01:32 -0500 Subject: [PATCH 2/3] An example showing Optional binding before Pattern --- mathics/builtin/patterns/defaults.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mathics/builtin/patterns/defaults.py b/mathics/builtin/patterns/defaults.py index d647dbd51..1f1590336 100644 --- a/mathics/builtin/patterns/defaults.py +++ b/mathics/builtin/patterns/defaults.py @@ -71,6 +71,15 @@ class Optional(InfixOperator, PatternObject): >> g[a] = {a, 4} + When there are several unparenthesized colons, the colon for 'Optional' binds more tightly than the \ + colon for 'Pattern'. + + + Notice below that 'Optional', the second colon, is inclosed inside 'Pattern', \ + the first colon: + + >> x:_+y_:d // FullForm + = Pattern[x, Plus[Blank[], Optional[Pattern[y, Blank[]], d]]] """ arg_counts = [1, 2] From eb721167f9055a48dfc87fb72c6c879e1caf5446 Mon Sep 17 00:00:00 2001 From: rocky Date: Tue, 20 Jan 2026 06:51:23 -0500 Subject: [PATCH 3/3] Another pass over Optional... Make it more clear the operator nature of Optional and Pattern. Make more explicit the precedence between Optional and Pattern. --- mathics/builtin/patterns/defaults.py | 32 +++++++++++++++++----------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/mathics/builtin/patterns/defaults.py b/mathics/builtin/patterns/defaults.py index 1f1590336..33fec13a0 100644 --- a/mathics/builtin/patterns/defaults.py +++ b/mathics/builtin/patterns/defaults.py @@ -34,6 +34,12 @@ class Optional(InfixOperator, PatternObject): >> f[x_, y_:1] := {x, y} + Above, we put no spaces before or after ':', but they can be added. So: + + >> f[x_, y_: 1] := {x, y} + + is the same as the above. + When we specify a value for the 'y' parameter, it has the value provided: >> f[a, 2] = {a, 2} @@ -44,15 +50,19 @@ class Optional(InfixOperator, PatternObject): >> f[a] = {a, 1} - Do not confuse with '$symbol$ : $pattern$', which is also a 'Pattern'. \ - The distinction is to left of the colon. When a $symbol$ is given, we get: + Both 'Optional' and :Pattern: + /doc/reference-of-built-in-symbols/rules-and-patterns/composite-patterns/pattern/ \ + use ':' as their operator symbol. And both operators are used to represent a pattern. + + The way to disambiguate which of the two is used is by the first or left operand. When \ + this is a $symbol$, like 'y', the ':' operator indicates a 'Pattern': - >> y:1 // FullForm + >> y : 1 // FullForm = Pattern[y, 1] - Whereas, in an 'Optional' expression, on the left of the colon we have a pattern like 'y_': + In contrast, we have a pattern to the left of the colon, like 'y_' we have an 'Optional' expression: - >> y_:1 // FullForm + >> y_ : 1 // FullForm = Optional[Pattern[y, Blank[]], 1] The special form 'y_.' is equivalent to 'Optional[y_]': @@ -71,15 +81,13 @@ class Optional(InfixOperator, PatternObject): >> g[a] = {a, 4} - When there are several unparenthesized colons, the colon for 'Optional' binds more tightly than the \ - colon for 'Pattern'. + Note that the 'Optional' operator binds more tightly than the \ + 'Pattern'. Keep this in mind when there is more than one colon, \ + juxtaposed, each representing different operators: - - Notice below that 'Optional', the second colon, is inclosed inside 'Pattern', \ - the first colon: - - >> x:_+y_:d // FullForm + >> x : _+y_ : d // FullForm = Pattern[x, Plus[Blank[], Optional[Pattern[y, Blank[]], d]]] + """ arg_counts = [1, 2]