Optional throws error when called from a package. Workaround?
String "x : Optional[_, default]"
in StandardForm
is interpreted as:
ToExpression["x : Optional[_,default]", StandardForm, HoldComplete] // FullForm
(* HoldComplete[Optional[Pattern[x, Blank[]], default]] *)
and in InputForm
as:
ToExpression["x : Optional[_,default]", InputForm, HoldComplete] // FullForm
(* HoldComplete[Pattern[x, Optional[Blank[], default]]] *)
The latter is done when reading a package file, and similar thing to the former is done in the front-end.
As per comment of Itai Seggev in the front-end x : Optional[_,default]
is represented by following boxes, which are interpreted as following expression:
RowBox[{"x", ":", RowBox[{"Optional", "[", RowBox[{"_", ",", "default"}], "]"}]}] // MakeExpression // FullForm
(* HoldComplete[Optional[Pattern[x, Blank[]], default]] *)
instead of HoldComplete[Pattern[x, Optional[Blank[], default]]]
, which is the surprising (possibly buggy) fact.
I think it should be reported to WRI.
As can be seen in Details section of Optional
documentation, what you called a workaround, in a comment, is actually the correct, documented way, which in full form is:
Optional[Pattern[name, something], defaultValue]
In a package you can use full form directly:
Optional[Pattern[x, Thing->{_}], Thing->{1}]
use infix form of Pattern
:
Optional[x : (Thing->{_}), Thing->{1}]
or infix form of both Pattern
and Optional
:
x : (Thing->{_}) : (Thing->{1})
I rewrote your package like this
BeginPackage["Dummy`"]
Clear[f,g,Thing]
Begin["`Private`"]
g[x_:default]:=x
f[x:(Thing->{_}):(Thing->{1})]:=x
End[]
EndPackage[]
and saved it to /Users/oldmg/Desktop/Dummy.m
and ran the following code
Quiet @ Remove["Dummy`*"]
<< "/Users/oldmg/Desktop/Dummy.m" (* *)
dummy = 42;
g[] && g[2]
Dummy`Private`default && 2
f[] && f[Thing -> {42}] && f[42]
(Thing -> {1}) && (Thing -> {42}) && f[42]
I believe this is the behavior you are looking for in Dummy.m
, so you might use this as a guide when you are writing your non-toy package code.