Re: ParsedBoxWrapper's in packages
- To: mathgroup at smc.vnet.net
- Subject: [mg115429] Re: ParsedBoxWrapper's in packages
- From: Yaroslav Bulatov <yaroslavvb at gmail.com>
- Date: Tue, 11 Jan 2011 00:32:36 -0500 (EST)
Wow, that looks complicated....is it likely to work in future versions? At the core, I basically want 1. Have \[Element] work like MemberQ for lists. 2. Define functions that use f[a_\[Element] b_] syntax 3. Be able to import this functionality without breaking behavior or functions like Reduce that use "Element" built-in Is there perhaps a way to do this without Notation package? On Mon, Jan 10, 2011 at 8:54 AM, Leonid Shifrin <lshifr at gmail.com> wrote: > 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? >> > >