什么时候定义新的宏(或更通用/抽象:资源),我们必须考虑宏已经定义的情况。xparse
通过使用四个前缀,可以很好地处理这个问题(恕我直言)
\New...
,如果控制序列已经存在,则会引发错误\Renew...
,如果控制序列不是已经存在\Provide...
,如果宏不存在则定义宏,如果宏存在则不执行任何操作(并保留先前的定义)\Declare...
,它定义宏,无论其是否存在,因此可能会覆盖现有的宏。
对于这个问题的范围,我们将其称为new
、、renew
和provide
机制declare
。
现在可以注意到
- 以上所有都可以考虑定义所以这可能是正确的概念
- 据我所知,决定不使用
def
或define
类似的东西是故意的,为了摆脱Texs内部\def
原语(通常应该避免)。 - 许多其他软件包也依赖于其中的一些约定,特别是
new
,renew
并且provide
似乎总是表现得如上所述,至少从我迄今为止偶然发现的宏来看是这样。
但是,此规范也有许多例外情况:
- 尽管 LaTeX 提供了
\newtheorem
,其行为类似于new
上述意义,但包thmtools
选择了\declaretheorem
,其行为实际上类似于一种new
机制。 - 该
acro
包使用缩写\DeclareAcronym
来表示new
。 \DeclareMathOperator
包中有mathtools
,它的作用也类似new
- 包选项以 引入
\DeclareOption
,但其行为也类似new
。
因此对我来说,这似乎是经常使用declare
而意味着declaring some resource
,因为没有新的控制序列供用户立即使用。
所以我的问题是,在编写自己的包时我通常应该遵循什么惯例,尤其是当涉及到resources
我的包可能提供的内容(最广泛的意义)时。
- 所描述的
declare
宏是否只是旧代码的残余并且在今天可能被认为是不好的风格? - 您是否应该坚持
\Define...
执行xparse
所调用的操作\Declare
?这可能也会明确说明宏的作用。 - 或者是否存在一些很好的论据来解释为什么
define
在不同情况下会有两种不同的行为,如果是这样,我们如何判断上下文/正确的用法? - 或者您应该
\Declare...
在定义宏时不提供功能(从而保留 Declare 用于声明包资源等),因为它很少需要和其他三种变体new
,renew
并provide
提供更好的接口? - 还有 的概念
setting
,LaTeX3 内核包似乎大量使用了 。我认为这是设置控制序列的好名字,因为你实际上“设置”了一些标记以便扩展此控制序列,但这似乎不是声明首字母缩略词等时的合适名称。
在我看来,最后三点可能是最相关的。例如,l3kernel
束中只有两个控制序列declare
(\text_declare_purify_equivalent:Nn
和\text_declare_expand_equivalent:Nn
),因此该术语似乎很少使用。
如果有人拥有更多经验或更广阔的视野,也能证实我的上述考虑,我会很高兴,但我想摆脱这种挣扎,因为我经常不确定该选哪个名字。
答案1
您触及了一个热门话题,它不仅与 LaTeX 有关,还与许多其他计算机语言有关。团体和公司编写了自己的样式书,试图消除这些惯例。在我看来,一个极端但很好的例子是 Go,它在语言本身中强制执行了许多惯例(例如,以大写字母开头的名称是全局的,其余的是本地的)。另一个例子是 Lua,各个团体使用不同的惯例,但至少有一件事他们都同意:那就是类应该大写,但它实际上没有类,只有原型。
首先,关于命名约定的最佳建议是遵循原始语言开发人员的风格。
- 蛇形字母、帕斯卡字母、驼峰式字母、小写字母、大写字母等等。
变量和函数可以用多种方式编写,snake_like、、、 和pascalLike
David Carlisle -like ,对于后者或前者无意批评。CamelCase
lowercase
CAPITALS
~@#asd:\x/!
在背景中,对“正确”和“错误”的感知取决于用户而不是你。LaTeX3Team 建议将代码分为三个大级别 a)作者级别 b)模板设计器水平和 c)程序员级别,这很有意义。这与许多其他计算机语言不同,后者几乎总是针对程序员。
1.1作者级别
这是最重要的层级。它可以由一个用户组成:即您、一个小团队或大量用户。
用户讨厌陌生的领域/舒适区。
自 80 年代初以来,发生了很多事情。计算机语言来了又去。霍尔在撰写有关计算机语言的文章时写道:
实现上述任何一个目标的必要条件是语言设计极其简单。如果简单,甚至语言设计者本人也无法评估其设计决策的后果。如果简单,编译器编写者甚至无法实现可靠性,当然也无法构建紧凑、快速和高效的编译器。但简单性的主要受益者是语言的使用者。在人类智力和实践活动的所有领域,从木工到高尔夫,从雕塑到太空旅行,真正的工匠是彻底了解其工具的人。这也适用于程序员。完全了解其语言的程序员可以处理更复杂的任务,并且比不了解时更快、更令人满意地完成它们。事实上,程序员对了解其语言的需求如此之大,以至于几乎不可能说服他换一种新语言。不管他现在使用的语言有哪些缺陷,他都已经学会了与之共存;他学会了如何通过纪律和文献来减轻它们的影响,甚至以一种在新的、更干净的、可以避免这种缺陷的语言中不可能实现的方式利用它们。
因此,在设计一种新的编程语言时,尤其有必要将简单性作为吸引程序员离开他们当前的高级语言的目标,以便程序员可以轻松地学习和记住它的所有特性,可以为他的每个目的选择最好的工具,可以充分理解每个决策的影响和后果,然后可以集中他的大部分智力去理解他的问题和他的程序,而不是他的工具。
这和你的包/类命令有什么关系?在某种程度上,你给你的用户群提供了一种新的语言(你的键和宏的语言),至少让他们有点熟悉。
1.1.1 如果我们遵循 Hoare 的观察,那么所有用户命令都应该是
CamelCase
,不是因为它是最好的,而是因为大多数用户都会熟悉它,而且你遵循的是当前趋势。全小写的方法也是可以接受的,但我不喜欢混合使用。
1.1.2 键:我喜欢它们全部使用小写字母并且没有空格。这是个人偏好。这似乎也是大多数软件包的当前趋势。我不喜欢 TikZ/pgf 在键中使用空格的方式。但是,在我使用 PGF 键开发的任何相关代码中,我都使用空格来遵循惯例。更好的非常规方法是使用点,而不是空格。诸如 这样的键arrow latex
读起来会更好arrow.latex
,顺便说一下,这是一个完全可以接受的键名称,比arrow@key
或箭头更好。在布局键中的空格以获得合乎逻辑的名称间距时,请考虑使用点。 用于 PGF 键的目录式结构latex
也是如此。/
1.1.3 具体内容
新的 - 构造全局函数,创建命令
提供 - 如果未定义则构造
宣布 - 与 New 相同,但可以是本地的。您可以多次声明它。
放 - 我使用小写的 \pkgsetkeys{} 设置密钥。最好只使用一个命令。
如果使用不同的设置命令,请考虑将它们合并为一个。
PkgSet{font}{...}
PkgSet{color}{...}
如果你经常这样做,也许你就不会DeclareEnoughKeys
。
人类喜欢把事物分类。如果你曾经看过罗伯特·萨波斯基,他有一些非常有说服力的论据来解释我们为什么这样做。你可以在 Youtube 上找到它们,它们值得一看。由于大多数用户已经内化了,
New
等等Declare
。尽可能坚持这些惯例。
1.2模板设计者级别
如上所述,但此外您还可以使用小写命令。
1.3程序员级别
您应该开放 API,以便程序员了解代码的哪些部分可以使用。如果您使用 LaTeX3 约定进行编码,我的建议是遵循这些约定。约定是使用l_snake_like_variables_tl:N
前置和后置附件来使它们独一无二。这与匈牙利命名约定非常相似,老实说,这种风格并没有多少朋友。但是,需要认识到,考虑到 TeX 语法的局限性,这是一个很好的解决方案,并且 |expl3| 消除了 TeX 编程的大量繁琐工作。
总之,您预期的用户群应该决定风格。