Mathematica 9 is now available
Services & Resources / Wolfram Forums / MathGroup Archive
-----

MathGroup Archive 2011

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: ParsedBoxWrapper's in packages

  • To: mathgroup at smc.vnet.net
  • Subject: [mg115426] Re: ParsedBoxWrapper's in packages
  • From: Leonid Shifrin <lshifr at gmail.com>
  • Date: Tue, 11 Jan 2011 00:32:01 -0500 (EST)

Hi Yaroslav,

I could offer some chain of hacks, which, while not perfect, seem to do it.

First, an example package:

BeginPackage["NotationTest`"]

mySum;
myElement;
plus;

Begin["`Private`"];

BeginPackage["Global`",{"Notation`","NotationTest`"}]
InfixNotation[ParsedBoxWrapper["\[Element]"],myElement];
EndPackage[]

mySum[a_ \[Element] list_,expr_]:=plus[a,expr];

End[]
EndPackage[]

Note that we wrap the calls to InfixNotation into BeginPackage and
EndPackage in
some special way. The next ingredient is a pretty dirty hack, for which I
will probably be
flamed:

SetAttributes[loadWithNotations, HoldAll];
loadWithNotations[code_] :=
 Module[{oldSDdefs = DownValues[SetDelayed], temp, result},
  Needs["Notation`"];
  Unprotect[SetDelayed];
  def : _SetDelayed /; (temp; True) :=
   With[{dv = DownValues[SetDelayed]},
    Unprotect[SetDelayed];
    Clear[SetDelayed];
    ReleaseHold@MakeExpression[MakeBoxes[def], StandardForm];
    DownValues[SetDelayed] = dv;
    Protect[SetDelayed]];
  Protect[SetDelayed];
  AbortProtect[Catch[Catch[result = code, _]]];
  Unprotect[SetDelayed];
  DownValues[SetDelayed] = oldSDdefs;
  Protect[SetDelayed];
  result]

You must define this function in the Global` context before you load the
packages. Now, assuming
that you placed your package where Mathematica can find it (or appended its
directory tp $Path),
here is how you use it:

loadWithNotations[
 Needs["NotationTest`"];
]

Let us now check the resulting definition:

In[5]:= DownValues[mySum]//FullForm

Out[5]//FullForm=
List[RuleDelayed[HoldPattern[mySum[myElement[Pattern[NotationTest`Private`a,Blank[]],
Pattern[NotationTest`Private`list,Blank[]]],Pattern[NotationTest`Private`expr,Blank[]]]],
plus[NotationTest`Private`a,NotationTest`Private`expr]]]

You can load several packages inside loadWithNotations. In each of these
packages, you must isolate your
calls to InfixNotation, as I did it here. Note that this will only work for
definitions (with SetDelayed).

Now, how does this work. It took me some time to figure this out. The
problem is that Notation sticks to
MakeBoxes/MakeExpression, which it redefines. But normally, when we read in
packages (unlike when we enter expressions in interactive  FrontEnd
sessions), they are parsed by some different means, so MakeExpression is not
invoked. So, what I did here was to force the code to undergo
MakeBoxes->MakeExpression transition during the time SetDelayed executes,
thereby  forcing it to trigger the mechanisms of Notation. We need
ReleaseHold because Notation`'s version of MakeBoxes wraps the result in
HoldComplete, while we want it to execute. The reason why we need to wrap
things in BeginPackage / EndPackage with Global` is that Notation` checks
the $ContextPath for what is referred there as initializationContext
variable, which must be on the $ContextPath.

I can not say anything about the limitations of this approach, but it seems
to work in simple cases. I haven't used
Notation` package ever before, so it could be that I missed something
important.

Hope this helps.

Regards,
Leonid

On Mon, Jan 10, 2011 at 10:39 AM, Yaroslav Bulatov <yaroslavvb at gmail.com>wrote:

> I'm trying to turn my notebooks into stand-alone packages and I'm
> running into problems with Notation package. In particular, I'm using
> Notation package and InfixNotation, and when I save notebook as a
> package, I get "ParsedBoxWrapper"'s and definitions using infix
> notation fail to match, for example.
>
> InfixNotation[ParsedBoxWrapper["\[Element]"], MyElement]
> sum[a_ \[Element] list_, expr_] := ...
> sum[a_\[Element] {1,2,3},a]
>
> This fails to match when in .m file, but works fine in .nb file. My
> question is -- how should I package "sum" so that it matches correctly
> both in packages and in notebooks?
>
>



  • Prev by Date: Re: How to change the directory for the docs?
  • Next by Date: Re: I'm puzzled by drastic truncation of y-axis in DateListLogPlot
  • Previous by thread: ParsedBoxWrapper's in packages
  • Next by thread: Re: ParsedBoxWrapper's in packages