我被搞糊涂了所有内置在声称为防止评价在某种程度上数学函数:Unevaluated,Defer,Hold,以及超过一半的形式的打Hold*.Mathematica文档只是单独解释了每个函数,但没有解释为什么要选择其中一个函数.任何人都可以对所有这些功能提供一致的解释吗?整件事对我来说似乎是一个令人费解的混乱.将它全部与Lisp宏相关可能是一个很好的起点.
大多数Mathematica语言都设计得非常好,但看起来Wolfram真的把自己描绘成了这方面的一个角落.或者我可能会遗漏一些东西.
我想描述我一直有一个问题与Plot使用With,以保持定义的参数"本地".我不一定要求解决问题:我遇到的问题是理解问题.
有时候我使用如下的结构来获得一个Plot:
方法1
plot1 = With[{vmax = 10, km = 10},
Plot[Evaluate@((vmax x)/(km + x)), {x, 0, 100},
AxesOrigin -> {0, 0}]]
Run Code Online (Sandbox Code Playgroud)
我喜欢这种方法,即使对于非Mathematica用户来说,它也是相当清楚的.
当要绘制的方程式变得更加复杂时,我喜欢在绘图外部定义它们(使用SetDelayed).例如:
f[x_] := (vmax x)/(km + x)
Run Code Online (Sandbox Code Playgroud)
但是,以下不起作用
方法2
plot2 = With[{vmax = 10, km = 10},
Plot[Evaluate@f[x], {x, 0, 100}, AxesOrigin -> {0, 0}]]
Run Code Online (Sandbox Code Playgroud)
我一直天真地认为它应该.但是,基于Help语句
Plot将变量x视为本地,有效地使用Block
我使用过各种解决方法,大多数情况如下
方法3
plot3 = Plot[With[{vmax = 10, km = 10}, Evaluate@f[x]], {x, 0, 100},
AxesOrigin -> {0, 0}]
Run Code Online (Sandbox Code Playgroud)
这个看起来很尴尬,甚至通常需要对Mathematica用户进一步解释.
绘图输出

但是,最近我发现偶然的机会,取代 …
SaveDefinitions是一个不错的选择Manipulate.它导致Manipulate在Manipulate面板中存储用于创建的任何定义.以这种方式制作的Manipulate可以复制到空白笔记本中,并且仍然可以单独使用.此外,包含许多此类操作的工作笔记本也不会变成粉红色的盒子,打开时会在其下方打印错误消息.大!
然而,所有这些善良都有它的黑暗面,如果你不知道它,它会让你真的很难受.我已经在我已经工作了几天的笔记本中使用了这个,但是我向您展示了一个重新创建问题的分步玩具示例场景.
在这种情况下,你想创建一个Manipulate漂亮的波浪函数的图,所以你定义这个(请创建一个像这样的窗口大小,这很重要):

定义很好,所以我们下次保留它并使其成为初始化单元.接下来我们添加Manipulate,并执行它.
f[x_] := x^2
Manipulate[
Plot[n f[x], {x, -3, 3}],
{n, 1, 4},
SaveDefinitions -> True
]
Run Code Online (Sandbox Code Playgroud)
一切都很棒,Manipulate真的很闪耀,这是美好的一天.

只是做你的偏执自我,检查定义是否正常:

是的,一切仍然检查出来.精细.但现在你想到一个更好的波浪函数是正弦,所以你改变定义,执行和偏执,检查:

一切都还好.你已经准备好从一天的努力中挽救你的工作并退出.[退出内核]
明天.你重新开始工作了.您评估笔记本中的初始化单元格.定义还好吗?校验.

现在,您向下滚动到Manipulate框(不需要重新执行SaveDefinitions),使用滑块稍微玩一下.并向上滚动.

作为你的偏执狂,你再次检查f的定义:

瞧,有人改变了你背后的定义!Information根据In []数字(In[1]:def为f,In[2]第一个?,In[3]第二个?),在第一个和第二个(?)检查之间没有执行任何操作.
发生了什么?嗯,这Manipulate当然是.A FullForm揭示其内部结构:
Manipulate[Plot[n*f[x],{x, -3, 3}],{{n, 2.44}, 1, 4},Initialization:>{f[x_] := x^2}]
Run Code Online (Sandbox Code Playgroud)
你有罪魁祸首.框的初始化部分再次定义f,但它是旧版本,因为我们Manipulate在修改其定义后没有重新评估.一旦操纵盒出现在屏幕上,它就会被评估,并且您已经恢复了原来的定义.在全球范围内!
当然,在这个玩具示例中,很明显发生了一些奇怪的事情.在我的情况下,我在一个更大的笔记本中有一个更大的模块,在经过一些调试后,我改变了一小部分.它似乎工作,但第二天,同样的错误,在再次击中之前曾经惹过我.我花了几个小时才意识到我用来研究各方面问题的几个操作中的一个是这样做的.
显然,我很想说,这是不受欢迎的行为.现在,对于强制性问题:除了在每次更改可能由他们使用的定义时重新执行笔记本中的每个操作之外,我们还能做些什么来防止这种背后行为Manipulate发生Manipulate?
在最近的SO问题中,提供了三个不同的答案,每个答案使用不同的方法来防止Equal[]表达的评估.他们是
Defer[]Unevaluated[]HoldForm[]有时我仍然无法在这些选项之间进行选择(并且根据前面提到的问题的答案判断,对于其他人来说,选择并不总是清楚的).有人能否就这三种方法的使用写清楚的说明?
还有其他三个包装
Hold[],
HoldPattern[],
HoldComplete[],和各种Attributes的功能
HoldAll,HoldFirst,HoldRest和数字版本,NHold*即也可以讨论,如果你想!
我只是注意到这基本上是旧问题的重复(我已经投了很多,只是忘了...).在1999年Mathematica开发者大会上,这个讲话被接受的答案Defer与之相关,因为它是"6中的新人".Defer与其他评估控制机制相比,它与前端的联系更紧密.它用于创建未评估的输出,如果提供和Input表达式,将对其进行评估.引用文档中心:
Defer [expr]返回一个保持不变的对象,直到它作为Mathematica输入显式提供,并使用Shift + Enter,就地评估等进行评估.
这与这个问题有点关系
但是上面的问题没有回答我的问题,因为它讨论了完整的控制定义.(我也尝试过那里展示的一些技巧,但它们对我的问题不起作用).
我现在只询问部分控件的定义.(使用这种论坛格式也很难跟进一个老问题.因为使用微小的评论区域,很难提出更多的问题,并且更像是在询问空间较大的新问题时,可以粘贴代码和图片).
我所做的所有尝试都不起作用.我将从简单的例子开始解释这个问题.
假设有人想写
Clear["Global`*"];
Manipulate[Plot[f*g, {x, -1, 1}],
Grid[{
{Style["f(x)="],
PopupMenu[Dynamic[f], {x, x^2, x^3}, ImageSize -> Tiny]},{Style["g(x)="],
PopupMenu[Dynamic[g], {x, x^2, x^3}, ImageSize -> Tiny]}
}]
]
Run Code Online (Sandbox Code Playgroud)
您可以看到每个控件定义中都存在重复的代码重复.(像ImageSize,Spacings->和许多其他装饰设置之类的东西会反复重复每个控件.

如果我能写出类似的东西,那会是多么美好的事情
Manipulate[Plot[f*g, {x, -1, 1}],
Grid[{
{Style["f(x)="], PopupMenu[Dynamic[f], Evaluate@Sequence@v]},
{Style["g(x)="], PopupMenu[Dynamic[g], Evaluate@Sequence@v]}
}],
Initialization :>
(
v = {{x, x^2, x^3}, ImageSize -> Tiny}
)
]
Run Code Online (Sandbox Code Playgroud)
但这不起作用.我在上面的那一行尝试了许多其他的东西,没有任何作用.喜欢
{Style["f(x)="], PopupMenu[Dynamic[f], v]},
Run Code Online (Sandbox Code Playgroud)
和
{Style["f(x)="], PopupMenu[Dynamic[f], Evaluate@v]}
Run Code Online (Sandbox Code Playgroud)
和
Manipulate[Plot[f*g, {x, -1, 1}],
{{v, {{x, x^2, x^3}, ImageSize -> Tiny}}, None},
Grid[{
{Style["f(x)="], PopupMenu[Dynamic[f], …Run Code Online (Sandbox Code Playgroud) 我正在运行一个Table函数,这将耗费太多时间来完成.
我想知道是否有办法检索到目前为止计算的结果.
如何将从单元格表达式中提取的任意框规范转换为输入表达式?
这是我在FullForm语法中对Save Mathematica代码的回答.在该上下文中,模式匹配被用于从使用读取的笔记本表达式中提取框规范Import.
我认为ToExpression或者MakeExpression会做盒子解释的工作,但在某些情况下他们没有.
考虑一个包含表达式的输入单元格:
StringForm["a = ``", 1]
Run Code Online (Sandbox Code Playgroud)
这种细胞的细胞表达如下:
Cell[BoxData[
RowBox[{"StringForm", "[",
RowBox[{"\"\<a = ``\>\"", ",", " ", "1"}], "]"}]], "Input"]
Run Code Online (Sandbox Code Playgroud)
我可以BoxData从这个单元格ToExpression中获取子表达式并使用获取相同的输出,就像我评估原始单元格一样:
ToExpression @
BoxData[
RowBox[{"StringForm", "[",
RowBox[{"\"\<a = ``\>\"", ",", " ", "1"}], "]"}]]
Run Code Online (Sandbox Code Playgroud)
但现在考虑以下输入表达式:
StringForm["a = ``", 1]
你必须仔细观察才能发现差异:a用斜体字表示.这是相应的单元格表达式:
Cell[BoxData[
RowBox[{"StringForm", "[",
RowBox[{"\"\<\!\(\*
StyleBox[\"a\",
FontSlant->\"Italic\"]\) = ``\>\"", ",", " ", "1"}], "]"}]], "Input"]
Run Code Online (Sandbox Code Playgroud)
如果我正常评估这个单元格,我会得到预期的结果.但是,如果我尝试应用ToExpression到BoxData像以前一样的子表达式: …
该功能MapAll被看作是重要的,足以保证短表//@,但我很少使用它,尤其是相对于其他人一样/@,/.和@@@我用几乎无处不在.
什么样的应用最好地利用MapAll?
它主要用于某些领域或编程风格吗?
与其他运营商相比,它可以多久使用一次?
我想在mma中制作一个迷你编程语言.从文本文件到包中的模块.理想情况下,我应该能够通过另一个包中的函数从Mathematica中生成包和模块.
问题:这可能吗?我正在寻找一个参考或一个例子来启动它.
编辑:例如:
想象一下具有n个整数类型寄存器的存储体.
说明是:
1 Z(n)
2 C(m,n)
3 J(m,n,q)
4 S(n)
每行都有一个地址.第一行1,第二行2等.Z(n)在寄存器n中存储0.寄存器n中的寄存器m的C(m,n)存储值.J(m,n,q)如果值寄存器m等于寄存器n的值则跳转到地址q的行.S(n)将n加1到寄存器n中的值.
然后给出两个工作程序P和QI想要生成连接程序P + Q.
然后给出两个工作程序P和QI想要在P之后生成替换Q.
最后,我想开始尝试递归...这个'迷你项目'的目的.