Wolfram mathematica 使用字符串而不是符号:善还是恶?

Wolfram mathematica 使用字符串而不是符号:善还是恶?,wolfram-mathematica,Wolfram Mathematica,我经常会处理{foo->value,…}形式的函数选项列表(或更通用的替换列表)。当foo在$Context中已经有值时,这会导致错误。防止这种情况的一个明显方法是使用字符串“foo”而不是符号:{“foo”->value,…}。这是可行的,但似乎激怒了我认识的一些老练的口齿不清的人,他们指责我把符号和字符串混为一谈,并告诉我使用内置的引用结构 虽然在不使用字符串的情况下编写避免冲突的代码当然是可能的,但这通常看起来麻烦多了。另一方面,我没有看到太多的{“string”->value}类型替换规

我经常会处理
{foo->value,…}
形式的函数选项列表(或更通用的替换列表)。当foo在$Context中已经有值时,这会导致错误。防止这种情况的一个明显方法是使用字符串“foo”而不是符号:
{“foo”->value,…}
。这是可行的,但似乎激怒了我认识的一些老练的口齿不清的人,他们指责我把符号和字符串混为一谈,并告诉我使用内置的引用结构

虽然在不使用字符串的情况下编写避免冲突的代码当然是可能的,但这通常看起来麻烦多了。另一方面,我没有看到太多的
{“string”->value}
类型替换规则的示例。所以问题是,这是一种可接受的使用模式吗?。。是否存在特别合适的情况?。。应该在哪里避免?。

在我看来(免责声明-这只是我的意见),最好避免使用字符串作为选项名称,至少对于函数中的“main”选项。字符串OTOH完全可以作为设置(选项的r.h.s.)。这并不是说您不能使用字符串,正如您所指出的。也许,它们更适合于子选项,许多系统功能(通常是“超级功能”,如
NDSolve
,在选项中可能有子选项)都以这种方式使用它们。我看到的使用字符串的主要问题是,它们减少了系统和用户的内省功能。换句话说,发现具有字符串名称的选项比发现具有符号名称的选项更难——对于符号名称,我可以只检查包中符号的名称,并且符号选项名称也有用法消息。您可能还希望自动化一些事情,例如编写一个实用程序来查找包中的所有选项名称等。当选项名称是符号时,这样做更容易,因为它们都属于相同的上下文。也很容易发现一些选项没有使用信息,可以通过编写实用函数自动完成

最后,您可以更好地防止类似选项名称的意外冲突。可能有许多选项序列被传递给函数,有时它们可能包含同名的选项。如果选项名称是符号,则完整的符号名称将不同。然后,您将得到一个阴影警告,同时一个保护-只有正确的选项(完整)名称将被使用。对于字符串,您不会得到任何警告,并且可能会使用错误的选项设置,如果具有错误设置的重复字符串选项名称(例如,用于其他函数)恰好位于列表的第一位。这种情况更可能发生在更大的项目中,但像这样的bug可能很难捕捉(这是一个猜测,我从未遇到过这种情况)


至于可能的冲突,如果您遵循一些命名约定,例如选项名称总是以大写字母开头,并且将大部分代码放在包中,并且不以大写字母开头变量或函数名称(对于交互式会话中的函数),那么您将大大降低此类冲突的可能性。此外,您应该在定义选项名称时或在包的末尾保护它们。然后,碰撞将被检测为阴影情况。避免阴影,OTOH,是一个普遍的必要条件,因此选项的情况在这方面并不比函数名等更特殊。

+1从技术上讲,大写符号保留给Mathematica内置,但这一惯例被广泛忽略。原因是,人们几乎可以确定大写的符号不会有向下的值。我试图尊重对函数名的保留,但在选项的情况下,我通常使用大写的名称定义自己的名称。@花环:大写的名称仅保留给
系统'
上下文中的符号。其他规则只是约定,而且,仅适用于在交互会话中创建的符号,而不是在包中创建的符号。在包中,约定是将导出的函数和选项名称大写。这可以在许多由WRI和第三方生产的附加包中看到。此外,这也是Roman Maeder在他的“Mathematica编程”中给出的建议,这是一个标准参考,特别是对于软件包编写。由于全名不同,冲突将导致阴影,因此会得到警告+1“我看到使用字符串的主要问题是它们会减少内省功能”+1而且,(v9)自动补全对字符串选项名不起作用。