如何停止在 Format/Interpretation Mathematica 构造中发生递归?
这个问题源于 Michael Pilat 在防止“Plus”重新排列事物。在那里,他使用定义了自定义 +
表示法。
Format[myPlus[expr__]] := Row[Riffle[{expr}, "+"]]
问题是您无法复制和粘贴输出(尽管 % 或 Out[] 仍然有效)。为了解决这个问题,您应该使用 Interpretation
类型工具,它允许表达式显示为一件事,但在作为输入提供时解释为另一件事。我对迈克尔的答案的修改是
Format[myPlus[expr__]] := Interpretation[Row[{expr}, "+"], myPlus[expr]]
这可以成功复制和粘贴。问题在于修改复制的表达式。您可以使用 Ctrl-Shift-I
将复制的表达式转换回 InputForm
,然后更改您想要的任何内容并在任何表达式中使用 InputForm
。 但是如果您尝试使用Ctrl-Shift-N
将其更改回StandardForm
,那么您将输入一个递归,其中中的第二个参数>解释
反复被评估。尽管Interpretation
具有属性HoldAll
(在正常评估期间可以正常工作),但还是如此。
通常,在定义简单符号时,我使用低级 MakeBoxes
,例如
myPlus/:MakeBoxes[myPlus[expr__],fmt_]:=With[{r=Riffle[MakeBoxes/@{expr},"+"]},
InterpretationBox[RowBox[r],myPlus[expr]]]
,它工作得很好,所以我以前没有遇到过这个递归问题。
所以我的问题(最后)是: 我的 Format
类型命令出了什么问题,如何修复? 或者:如何制作与我的 MakeBoxes
类型命令等效的高级命令?
This question follows on from the answer given by Michael Pilat in Preventing “Plus” from rearranging things. There he defined a custom +
notation using
Format[myPlus[expr__]] := Row[Riffle[{expr}, "+"]]
The problem with this is you can't copy and paste the output (although % or Out[] still works). To get around this you should use the Interpretation
type facility which allows an expression to be displayed as one thing, but interpreted as another when supplied as input. My modification of Michael's answer is
Format[myPlus[expr__]] := Interpretation[Row[{expr}, "+"], myPlus[expr]]
This can be copied and pasted successfully. The problem lies in modifying copied expressions. You can convert a copied expression back to InputForm
using Ctrl-Shift-I
then change anything you want and use the InputForm
in any expression. But if you try to change it back to StandardForm
using Ctrl-Shift-N
then you enter an recursion where the second argument in the Interpretation
repeatedly gets evaluated. This is despite Interpretation
having the attribute HoldAll
(which works properly during normal evaluation).
Normally, when defining simple notations I use the low-level MakeBoxes
, eg
myPlus/:MakeBoxes[myPlus[expr__],fmt_]:=With[{r=Riffle[MakeBoxes/@{expr},"+"]},
InterpretationBox[RowBox[r],myPlus[expr]]]
which works perfectly, so I have not encountered this recursion problem before.
So my question (finally) is:
What went wrong with my Format
type command and how can it by fixed?
Or: How do you make a high-level equivalent of my MakeBoxes
type command?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我就此咨询了一位同事,他的建议本质上是,当您希望事情紧密时,在
MakeBoxes
上放置上值定义(如您所演示的)比使用Format
更好从输出到输入的集成。Format
实际上并不是为了生成可重复用作输入的输出,而只是为了格式化输出,因此在转换为时会出现
等。Interpretation
意外的递归StandardForm您可能会发现函数
ToBoxes
对 MakeBoxes 的有用补充。最后,这是一个关于盒子结构的教程。
哈!
I consulted with a colleague about this, and his recommendation was essentially that putting up-value definitions on
MakeBoxes
as you demonstrate is better than usingFormat
when you want things to be tightly integrated from output back to input.Format
isn't really intended to produce output that can be re-used as input, but just to format output, hence the unexpected recursion withInterpretation
when converting toStandardForm
, etc.You might find the function
ToBoxes
a useful complement toMakeBoxes
.Finally, here's a tutorial about box structures.
HTH!