让我们一步一步来评估flog[1, 2]...
鞭打[1, 2]
当计算此表达式时,Mathematica 将替换问题中给出的定义中的1forx和2for 。这产生了我们游览的下一步:yflog
flog[1, 2] = f[1, 2] /。v_ :> (PutAppend[未评估[flog[1, 2] = v;], $runningLogFile]; v)
请注意,这里的赋值flog[1, 2] = ..., 是其flog自身定义的一部分。
/.是一个中缀运算符,它是ReplaceAll函数的替代表示。 ReplaceAll将对第一个参数的值应用替换规则。保持这个想法 - 我们会回到它。第一个论点是flog[1, 2] = f[1, 2]。此表达式将评估f[1, 2]然后将结果分配给flog[1, 2]. 为了便于讨论,我们假设f[1, 2]返回345。因此,一个新的定义将被添加到flog,即flog[1, 2] = 345。赋值后,我们可以检查 的定义flog:

观察 whereflog最初只有一个定义,但现在它有两个 - 新添加flog[1, 2]的定义缓存了该调用的结果。这通常被称为“记忆”。
flog[1, 2] = 345可能会有为 建立新定义的副作用,flog但是,就像 Mathematica 中的每个表达式一样,它也产生一个值。经过一番折腾后,该值345将成为ReplaceAll.
to 的第二个参数ReplaceAll是运算符的调用,是RuleDelayed函数:>的中缀表达式。为了将这篇文章保持在可管理的大小,我们将简单地注意到规则在这种情况下对自身进行评估。
所以,现在我们有一个涉及/.评估的表达式......
345 /。v_ :> (PutAppend[未评估[flog[1, 2] = v;], $runningLogFile]; v
替换表达式将其第一个参数 ( 345) 与替换规则 ( v_) 的模式组件相匹配。 v_匹配345(或与此相关的任何其他内容)并给出345名称v以用于替换。 ReplaceAll然后替换规则右侧345的每个出现。v结果是要评估的下一个表达式...
(PutAppend[未评估[flog[1, 2] = 345;], $runningLogFile]; 345)
这里我们有两个用分号分隔的表达式。顺便说一下,;是一个扩展为CompoundExpression的中缀运算符。第一个表达式涉及PutAppend,它将其第一个参数的值写入名为第二个参数值的文件。但是请注意,第一个参数包含在Unevaluated中。这会抑制对第一个参数的评估,以便将其完全按原样写入文件:flog[1, 2] = 345;. 如果当前 Mathematica 会话结束,书面表达式可以读入未来的 Mathematica 会话,以重新建立记忆的结果flog[1, 2]。
CompoundExpression丢弃除最后一个以外的所有参数的值。在这里,最后一个参数是345。由于我们已经到了表达式的结尾,这将是原始调用的最终返回值。也就是说,flog[1, 2]返回345——尽管正如我们所见,有一些副作用将这个结果保存到内存和磁盘中以供将来参考。
未来的呼吁flog[1, 2]
现在如果flog[1, 2]再次调用,Mathematica 将找到新定义flog[1, 2] = 345。 345将直接退回,没有我们上面讨论的任何并发症。特别是,它甚至不会f[1, 2]再次调用。当然,这就是这个例子的全部动机。假设f计算起来非常昂贵,证明所有这些体操都是为了尽量减少计算发生的次数。