Вот простая, очень схематичная версия:
Module[{tried},
Unprotect[SetDelayed];
SetDelayed[f_[args___, optpt : OptionsPattern[]], rhs_] /;
!FreeQ[Unevaluated[rhs], autoOptions[]] :=
Block[{tried = True},
f[args, optpt] :=
Block[{autoOptions}, autoOptions[] = Options[f]; rhs]] /; ! TrueQ[tried];
Protect[SetDelayed];]
Ваше использование:
In[8]:= Options[foo] = {bar -> 1};
foo[OptionsPattern[]] := autoOptions[]
foo[]
Out[10]= {bar -> 1}
Обратите внимание, что это не будет работать, когда также передаются явные опции - их учет - это еще немного работы, и это, как правило, не очень хорошая практика, так как я перегружал SetDelayed
- но вы просили об этом и получаете его.