以下精彩的回帖来自C++讨论组:
Why besides the type system?
I haven't read every part of the discussion, but let me try to highlight some points of semantics here.
我还没读完这次讨论中的所有部分,不过请让我突出强调一下这次讨论中的某些观点。
Let's assume we have a fully dynamic, strongly-typed language, i.e. there is no type checking at translation time, but still every value has a type that can be queried. Variables are not associated with fixed types, however, nor are functions. Functions themselves are first-class citizens, and can be passed around and combined. (Think Lisp, Javascript, or Haskell.)
假设我们有一种完全动态的强类型语言,也就是说语言中虽然没有编译期类型检查,但是所有的值都存在一个可供查询的类型。变量没有与固定类型相关联,函数也是如此。函数本身是一等公民,可以传来传去,也可以相互结合。(考虑一下Lisp,JavaScript,或Haskell语言)。
Now this language has a facility that allows dynamic type checking. I can write a type assertion, i.e. "expr : int". This will check, at runtime, that the value yielded by an expression is int. Furthermore, types are fully reified and first-class citizens too, so I can write "t = int" and then do "expr : t". (Think Ruby or Smalltalk, where classes are fully reified.) Because types are values, I can write functions that take and return types.
现在这种语言中有一种可供动态类型检查的设施。我可以写一个类型断言,如“expr : int”。在运行期这一断言会检查某个表达式所产生的值是否为int。另外,类型完全实体化并且是一等公民,所以我可以写“t = int”,然后做(类型断言)“expr : t”。(考虑一下Ruby或Smalltalk这一类“类”被完全实体化的语言。)由于类型也是值,所以我可以写一些能接收并返回类型的函数。
Let's look at C++.
让我们来看看C++。
In C++, we have various different kinds of things.
在C++中,我们有着各种不同种类的东西。
On the first level, we have values. Values have a type. (Let's leave value categories out of this.) This type is not itself a value, though; it is a different kind of thing. We cannot treat values as types or types as values. We also have functions, which are similar to values, but somewhat hobbled. We cannot pass functions around, only pointers to them. We can emulate everything you can do with functions with function objects (including lambdas) though. We define functions that take and return values.
在第一个层面上,我们有“值”,“值”有类型。(暂不考虑值的类别)类型本身不是值,类型和值不是一种东西。我们不能把值当作类型,也不能把类型当作值。我们还有函数,函数与值相类似,但使用上有些不自由。函数不能传来传去,函数指针可以。不过我们可以利用函数对象(包括lambda表达式)来模拟函数所拥有的一切功能。我们可以定义一些能接收并返回“值”的函数。
Values are runtime entities for the most part, but with non-type template arguments and constexpr, they have some role in compile time as well.
值在大多数情况下是运行期的实体,可是如果使用非类型模板参数和constexpr,值在编译期也能起到一定的作用。
On the second level, we have types. Types are almost purely compile time constructs, except for the extremely crippled type_info class, which is more of a type token than anything else. In C++, we write type assertions, which get checked at compile time, by associating functions and variables with types.
在第二个层面上,我们有类型。类型几乎纯粹是一种编译期的结构,除了极度残缺的type_info类。这个类更多的只是一种类型标识。在C++中,我们可以写类型断言。通过将函数、变量与类型相关联,类型断言在编译期会得到检查。
Then there's templates.
再有就是模板。
Templates are, mathematically speaking, functions that can only be called at compile time. A class template is a function that takes a bunch of parameters (types, values, and templates, i.e. other functions) and returns a type, which itself is composed of types (nested types), values (member constants and functions), and functions (nested templates). A function template is a function that takes parameters and returns a function. It is really just a limited form of a class template - aside from argument deduction, any function template can be emulated by a class template with a nested static function.
模板,从数学上说,就是一些只能在编译期被调用的函数。类模板就是一种接收一堆参数(包括类型,值和模板,模板即其他函数)并返回一个类型的函数。它所返回的类型本身也是由一些类型(嵌套类型),值(成员常量与成员函数),以及函数(嵌套模板)所构成的。函数模板就是一种接收一堆参数并返回一个函数的函数。不考虑参数推导功能的话,它实际上只是类模板的一种受限形式。任何函数模板都可以用带有内嵌静态函数的类模板来模拟。
The above is a bit of a mess. What I think FrankHB wants is a simplification of the above. We could relax the restrictions on compile time values to allow everything, and then reify types so that they are values. Then we can replace templates by constexpr functions that return types, and aside from the pesky issue of type equivalence (name-based equivalency does not play well with fully reified types) it would all be fine.
以上是有点乱。我认为FrankHB想要的是上述功能的简化。我们可以放松编译期对于值的限制从而允许一切都成为值,让类型实体化并成为值。然后我们就可以将模板替换为返回类型的constexpr函数。除了讨厌的类型等价问题以外(基于名字来判断是否等价与完全实体化的类型不大合拍),一切都会很完美。
Of course, the syntax of C++ quite disagrees. The problem is that the kind distinction is necessary to disambiguiate the syntax. Does "a b(c)" declare a function or a variable with an initializer? Is "a(c)" a comparison (a, b and c are values), a function call (a is a function template), a variable declaration (a is a class template), or a function-style cast (a is a class template and the code is part of a larger expression)? These are all very different things, and may influence how the compiler interprets the rest of the code.
当然,使用C++的语法难以实现上述简化。问题在于类型甄别对于消除语法上的歧义非常有必要。“a b(c)”所声明的是一个函数还是一个带有初始化器的变量?“a(c)”是一次比较操作(a,b和c都是值),一次函数调用(a是个函数模板),一个变量声明(a是个类模板),还是一次函数式的类型转换(a是个类模板并且这部分代码是一个更大的表达式的一部分)呢?这都是些非常不同的东西,(类型判断的结果)很可能会对编译器如何解释其余代码产生影响。
So while a language where types are first-class citizens that must be fully computable at compile time might be an interesting thing, C++ is not that language, and will not be. I simply can't see any viable transition path.
所以说,如果某种语言中类型是可以在编译期得以充分计算的一等公民,那么这种语言可能会很有趣。但C++不是这类语言,永远也不会。我根本看不到任何可行的转变途径。
Did that clear anything up, or did I just add further to the confusion?
我把观点说清楚了吗,还是仅仅让它更加含混不清?