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.