Re: Format[ ] with \[OverBracket] in a package `Private` context
- To: mathgroup at smc.vnet.net
- Subject: [mg56508] Re: Format[ ] with \[OverBracket] in a package `Private` context
- From: Maxim <ab_def at prontomail.com>
- Date: Tue, 26 Apr 2005 21:54:05 -0400 (EDT)
- References: <d4hvn9$1io$1@smc.vnet.net> <d4klg4$ehr$1@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
On Tue, 26 Apr 2005 06:01:40 +0000 (UTC), Maxim <ab_def at prontomail.com>
wrote:
> On Mon, 25 Apr 2005 05:37:45 +0000 (UTC), Trevor Baca
> <trevorbaca at gmail.com> wrote:
>
>> hello mathgroup,
>>
>> my goal is to format foo[_List] objects with an overscripted
>> \[OverBracket], and then shove this bit of code into a package for
>> later access. this does the trick in a notebook session:
>>
>> Format[foo[l_List]] := Overscript[RowBox[l], \[OverBracket]] //
>> DisplayForm;
>>
>> the interpreter now outputs foo[{2,3,4,5}] as 1 2 3 4 with a lovely
>> overbracket stretching across the top. so far so good. now the hard
>> part: shoving this bit of code into a package without context issues
>> getting in the way.
>>
>> (three example packages follow; feel free to skip to the section marked
>> "CONCLUSION" at the bottom for the actual question.)
>>
>>
>> ==== PROBLEM PACKAGE =================
>>
>> BeginPackage["Foo`"]
>>
>> foo::usage="foo objects print with overbracket.";
>>
>> Begin["`Private`"]
>>
>> Format[foo[e_]]:=Overscript[RowBox[e],\[OverBracket]]//DisplayForm
>>
>> End[]
>>
>> EndPackage[]
>>
>> ==== end problem package ================
>>
>>
>> with the problem package, i interpret the following three commands:
>>
>> Quit[ ] (* to clear out any previous definitions in any contexts *)
>>
>> << Foo`
>>
>> foo[{2,3,4,5}]
>>
>> ... and, unfotunately, foo[{2,3,4,5}] prints as 2 3 4 5 with the ugly
>> label Foo`Private`\[OverBracket] running across the top. not at all
>> what i wanted. first solution:
>>
>>
>> ==== SOLUTION PACKAGE 1: use System` context ==========
>>
>> BeginPackage["Foo`"]
>>
>> foo::usage="foo objects print with overbracket.";
>>
>> Begin["`Private`"]
>>
>> Begin["System`"]
>>
>> \[OverBracket]
>>
>> End[]
>>
>> Format[foo[e_]]:=Overscript[RowBox[e],\[OverBracket]]//DisplayForm
>>
>> End[]
>>
>> EndPackage[]
>>
>> ==== end solution package 1 =======================
>>
>>
>>
>> with solution package 1, i again interpret the following three
>> commands:
>>
>> Quit[ ] (* to clear out any previous definitions in any contexts *)
>>
>> << Foo`
>>
>> foo[{2,3,4,5}]
>>
>> ... and this works: foo[{2,3,4,5}] now prints as 2 3 4 5 with the
>> overbracket running across the top, as desired. but i've introduced the
>> OverBracket symbol into the System` context directly; and is this a
>> generally bad practice? fearing that it might be, i build this second
>> solution:
>>
>>
>> ==== SOLUTION PACKAGE 2: use Foo` context ==========
>>
>> BeginPackage["Foo`"]
>>
>> foo::usage="foo objects print with overbracket.";
>>
>> \[OverBracket]
>>
>> Begin["`Private`"]
>>
>> Format[foo[e_]]:=Overscript[RowBox[e],\[OverBracket]]//DisplayForm
>>
>> End[]
>>
>> EndPackage[]
>>
>> ==== end solution package 2 =====================
>>
>>
>>
>> with solution package 2, i interpret the following three commands one
>> last time:
>>
>> Quit[ ] (* to clear out any previous definitions in any contexts *)
>>
>> << Foo`
>>
>> foo[{2,3,4,5}]
>>
>> ... and this, too, works fine: foo[{2,3,4,5}] prints as 2 3 4 5 with
>> the requested overbracket. unfortunately, the OverBracket symbol now
>> lives in Foo`\[OverBracket], which somehow seems wrong to me, and
>> further seems to violate the spirit of the purpose of the public
>> section of a package ... introduce symbols "for export".
>>
>>
>>
>> CONCLUSION: so is it better to stick the OverBracket symbol into the
>> System` context (as in solution package 1), or to stick the OverBracket
>> symbol into the Foo` context (as in solution package 2), or to do
>> something else entirely?
>>
>> (i strongly prefer solution 1 (using the System` context) because it
>> seems bizarre to me that the OverBracket symbol doesn't already exist
>> in the System` context, so why not remedy the situation? on the other
>> hand, i could be convinced that messing with the System` context is as
>> bad an idea as messing with most reserved namespaces, hence solution 2.
>> but what i don't like about solution 2 is that after loading the
>> package, Names["Foo`*"] will give you both "foo" (which is good) and
>> "\[OverBracket]" (which just seems wrong)).
>>
>> anything to help make the decision or clean this up?
>>
>>
>> trevor.
>>
>
> It seems that symbols such as \[OverBracket] are created when they're
> used
> for the first time, and they obey the usual rules: first search the
> current context and $ContextPath for that symbol, and if it is not found,
> create it in the current context. Therefore, they always have the full
> name such as Global`\[OverBracket], but if their context is in the
> $ContextPath or is the same as the current context, then the context
> prefix is not shown. That is what happens in your examples: if you put
> the
> symbol in System` or in Foo`, then the context name is omitted, but
> Foo`Private`\[OverBracket] can be accessed only by its full name.
>
> You are correct that the simplest way seems to be just to put
> \[OverBracket] in the System` context by evaluating
> (System`\[OverBracket];) once, after which you can reference
> \[OverBracket] by the short name -- it will automatically be found in the
> System` context, which is still in $ContextPath within
> BeginPackage/EndPackage. Alternatively, you could reference the symbol as
> Global`\[OverBracket] every time it is used inside the package.
>
> A subtle point is that if you enter f + Ctrl-^ + Escape + ' + Escape to
> enter f' (with the \[Prime] symbol as Superscript) and evaluate it, the
> expression will be interpreted as Derivative[1][f] and the symbol
> Global`\[Prime] won't be created, but if you just evaluate Escape + `
> + Escape, then the symbol will be created. I'm not sure how to state this
> rule in an exact way, but in any case it doesn't affect your case.
>
> Also I can't understand why with the definition
>
> Format[foo[l_List]] := Overscript[RowBox[l], \[OverBracket]] //
> DisplayForm
>
> foo[Table[i, {i, 3}]] and foo[Range[3]] are displayed differently -- in
> the second case the output will contain an explicit RowBox.
>
> Here's another way to define the same formatting rule:
>
> MakeBoxes[foo[L_List], form_] :=
> OverscriptBox[
> RowBox[
> Function[b, MakeBoxes[b, form], HoldFirst] /@
> Unevaluated@ L],
> \[OverBracket]]
>
> This will correctly display expressions such as
>
> foo[{EllipticE[0], EllipticE[1]}] // TraditionalForm // HoldForm.
>
> Maxim Rytin
> m.r at inbox.ru
>
Actually, there is a simpler way: use quotes. No need to introduce the
symbol \[OverBracket] at all, the argument of OverscriptBox should be
"\[OverBracket]". It occured to me when I was considering how to write a
reverse MakeExpression rule:
MakeBoxes[foo[L_List], form_] :=
OverscriptBox[
GridBox[
{Function[b, MakeBoxes[b, form], HoldFirst] /@
Unevaluated@ L}],
"\[OverBracket]"]
MakeExpression[OverscriptBox[b_GridBox /; Length@ b[[1]] == 1,
"\[OverBracket]"], form_] :=
MakeExpression[
RowBox[{"foo", "[",
RowBox[{"{",
RowBox[Drop[Flatten[#, 1], -1]&@ Transpose@
{b[[1, 1]],
Table[",", {Length@ b[[1, 1]]}]}
],
"}"}],
"]"}],
form]
Now if you enter several expressions separated by Ctrl-comma (matrix-like
notation) and put \[OverBracket] over them, the input will be interpreted
as foo[{...}], which can be seen by doing FullForm. GridBox is preferable
because this way we keep the ability to enter multiplication as space.
Maxim Rytin
m.r at inbox.ru