What is the main argument in favor of re-using short keywords (and adding context-dependent meanings) instead of just adding more keywords?
支持重用短关键字(并添加上下文相关的含义)而不是只添加更多关键字的主要论据是什么?
Is it just that you want to avoid breaking existing code that may already be using a proposed new keyword, or is there a deeper reason?
是否只是想避免破坏现有的代码,而这些代码可能已经在使用一个新的关键字,或者有更深层次的原因?
The new "enum class" in C++11 got me thinking about this, but this is a general language design question.
c++ 11中新的“enum类”让我想到了这个问题,但这是一个通用的语言设计问题。
68
Is it just that you want to avoid breaking existing code that may already be using a proposed new keyword, or is there a deeper reason?
是否只是想避免破坏现有的代码,而这些代码可能已经在使用一个新的关键字,或者有更深层次的原因?
No, that's the reason.
不,这是原因。
Keywords, by definition, are always considered keywords wherever they occur in the source, so they cannot be used for other purposes. Making something a keyword breaks any code that might be using that token as a variable, function, or type name.
根据定义,关键字在源文件中出现的任何地方都被认为是关键字,因此它们不能用于其他目的。将某项设置为关键字会破坏任何可能将该标记用作变量、函数或类型名称的代码。
The C committee take a different approach and add new keywords using _Reserved names, e.g. _Atomic
, _Bool
, and then they add a new header (
,
) with a nicer macro, so that you can choose whether to include the header to get the name atomic
or bool
, but it won't be declared automatically and won't break code that happens to be using those names already.
C委员会采用不同的方法,使用_reserve名称添加新的关键字,例如_Atomic, _Bool,然后添加一个新的头(
The C++ committee don't like macros and want them to be proper keywords, so either re-use existing ones (such as auto
) or add context-dependent "keywords" (which are not really keywords, but are "identifiers with special meaning" so they can be used for other things, such as override
) or use strange spellings that are unlikely to clash with user code (such as decltype
instead of the widely supported typeof
extension).
c++委员会不喜欢宏和希望他们适当的关键字,所以要么重用现有的(例如汽车)或添加上下文相关的“关键字”(这并不是真正的关键字,但“标识符与特殊意义”,这样他们就可以被用于其他事情,如覆盖)或使用奇怪的拼写,不太可能与用户代码(比如decltype而不是广泛支持typeof的扩展)。
17
Some old languages did not have keywords at all, in particular PL/1 where
一些旧语言根本没有关键字,尤其是PL/1
IF IF=THEN THEN BEGIN;
/* some more code */
END;
was a legal piece of code, but completely unreadable. (Look also into APL as an example of write-mostly programming language, which is completely cryptic to read a few months later, even by the code's original author).
是一段合法的代码,但完全不可读。(也可以将APL作为以写为主的编程语言的一个例子,即使是由代码的原始作者编写,在几个月后读它也是完全不清楚的)。
The C and C++ language family have a set of keywords defined by the language specification. But there are very widely used languages with billions of legacy source code lines. If you (or their standardization committee) add a new keyword, there is a chance of collisions with some existing program, and as you guessed and others answered this is bad. So if the standard added for instance enum_class
as a new keyword, chances are that someone would already have used it as an identifier, and that entity would be unhappy (to have to change their code when adopting a new C++ standard).
C和c++语言家族有一组由语言规范定义的关键字。但是有非常广泛使用的语言,有数十亿的遗留源代码行。如果您(或者他们的标准化委员会)添加了一个新的关键字,那么就有可能与一些现有的程序发生冲突,正如您所猜测的那样,其他人的回答是不好的。因此,如果为instance enum_class添加了一个新的关键字,那么很有可能有人已经将它用作标识符,而这个实体会不高兴(在采用新的c++标准时,不得不更改其代码)。
Also C++ is widely known to be slowly parsed (in particular, because standard headers like
are pulling dozen of thousand lines of source code, and because modules are not in C++ yet, and because the syntax is strongly ambiguous), so complexifying the parser to handle new syntax is not a big deal (parsing C++ has always been horrible anyway). For example the GCC community is working much harder on new optimizations than on new C++ features (apparently, recent features of the C++ standard library requires much work than parsing new syntax), even if the jump from C++03 to C++11 was a huge jump and required a lot of work in the C++ frontend. This is less true for the C++11 to C++14 jump.
c++也被广泛认为是慢慢解析(特别是,因为标准头喜欢 <向量> 拉打几千行源代码,因为模块还没有在c++中,因为语法是强烈模糊),因此复杂化的解析器来处理新语法不是一个大问题(解析c++一直是可怕的)。例如GCC社区是新优化工作更加困难比新的c++特性(显然,最近c++标准库的特点要求比解析新语法)工作,即使从c++ 03跳到c++ 11是一个巨大的跳跃,需要大量的在c++前台工作。对于c++ 11到c++ 14的跳转,情况就不太一样了。
Some other languages (e.g. some dialects of Lisp such as Common Lisp and some Scheme, where you could redefine a let
or if
macro, and macros in homoiconic languages like these are very different, since operating on ASTs, from the crude textual substitution mechanism in C or C++...) permit the redefinition of existing keywords; read also about hygienic macros. But this can make the source code difficult to understand a few months later.
一些其他语言(如Lisp的一些方言,如Common Lisp和一些计划,你可以重新定义一个让或者宏,在homoiconic和宏语言,像这些都是非常不同的,因为在ast操作,从原油文本替换机制在C或c++…)允许重新定义现有的关键词;还可以阅读有关健康宏的内容。但这可能会使源代码在几个月后难以理解。
10
I think it's mainly because adding keywords will break existing code that happens to use this keyword in other contexts, as you suggest.
我认为主要是因为添加关键字会破坏现有的代码,而这些代码恰好在其他上下文中使用了这个关键字,正如您所建议的那样。
10
Is it just that you want to avoid breaking existing code that may already be using a proposed new keyword, or is there a deeper reason?
是否只是想避免破坏现有的代码,而这些代码可能已经在使用一个新的关键字,或者有更深层次的原因?
By definition, a keyword is a special token which cannot be used anywhere else; as a result, introducing a keyword breaks any code that happened to use an identifier with the given spelling.
根据定义,关键字是一种特殊的令牌,在其他任何地方都不能使用;因此,引入关键字会破坏使用给定拼写的标识符的任何代码。
Some languages use the term contextual keyword to refer to spellings that are only interpreted as keyword in specific contexts. If no "wild" identifier could previously be used in this context, then it is guaranteed that the introduction of the contextual keyword will not break existing code. For example, since no identifier can appear immediately after the closing parenthese in a function signature, this is a place where one can introduce so-called contextual keywords (such as override
or final
).
有些语言使用“上下文关键字”一词来指代仅在特定上下文中被解释为关键字的拼写。如果之前不能在此上下文中使用“wild”标识符,则可以保证上下文关键字的引入不会破坏现有代码。例如,由于在函数签名的结束括号之后不能立即出现任何标识符,因此可以在这里引入所谓的上下文关键字(例如override或final)。
On the other hand, in places where any identifier was previously allowed, adding a keyword poses a risk. For example:
另一方面,在以前允许任何标识符的地方,添加关键字会带来风险。例如:
struct H { my_type f; enum { g }; };
: the use of enum class
rather than a new keyword is because any new word could be mistakenly taken as the start of a data member declaration in this context; only a keyword is unambiguous (in LL(1)), and introducing a new one could break code.void h() { my_type f; auto x = g(); }
: the use of auto
rather than a new keyword is because any new word could clash with an existing type. It's a surprising choice still, since it was already a keyword usable in this position in C (defaulting to int
type) but its meaning was altered (the justification was the low probability of its usage).As some have mentioned, languages can be designed without keywords entirely (Haskell comes pretty close), or made in a way than keywords can be introduced seamlessly (for example, if every declaration starts by a keyword already, then introducing a new keyword cannot clash). It just so happens than C and C++ where not made so, and indeed many C-like languages.
正如有些人所提到的,语言可以完全不使用关键字来设计(Haskell非常接近),或者以一种关键字可以无缝引入的方式进行设计(例如,如果每个声明都以一个关键字开头,那么引入一个新的关键字就不会产生冲突)。它只发生在C和c++中,而不是这样,而且确实有许多C语言。
-11
Mistaken enthusiasm of "less is more". It is thought (incorrectly) that by using fewer keywords, programmers would have to learn less and can be more productive sooner. But this only creates confusion about the syntax.
“少即是多”的错误热情。人们认为(错误地)使用更少的关键字,程序员必须学习更少,并且可以更快地提高效率。但这只会造成语法上的混乱。
"Real Perl programmers prefer things to be visually distinct." ---- Larry Wall
“真正的Perl程序员更喜欢在视觉上区分事物。”——拉里墙
In other words, use a keyword for one task only.
换句话说,只对一个任务使用关键字。