HOPL4 笔记 6

HOPL 是 History of Programming Languages(编程语言历史)的缩写,是 ACM 旗下的一个会议,约每十五年举办一次。
这是我父的第三篇 HOPL 论文,发表于 2021 年。中文译本 出自 Boolan 之手,不胜感激。

Concepts—我父最大的执念,也算是我父的滑铁卢了吧……大约是十年前吧,就看过我父亲自上阵“路演” Concepts 主题的 PPT。念念不忘,必有回响。终于还是标准化了。
这是一篇夹在 C++14 和 C++17 时间线中间的大幅文章,远不到 C++20 内容出场的时候,可见我父的急不可耐……

我的看法?我是一个反模版者(注意不是反泛化),语法笨重,强制的实现可见,乱七八糟的错误信息。一群四六不懂的 TMP 至高无上鼓吹者直接让我把这种理性的反对变成了冲动的反感。所以这么些年我都没怎么系统地学习过模版。

Concepts 当然是出于善意,能解决“乱七八糟的错误信息”问题,在正向使用模版的时候也能对编译器做出正确的指示。但是!不管是优柔寡断或是市场的原因,引入新特性的同时依然保留了旧的、坏的实现路径,恰恰是我父前文提到的 N+1 问题:为了解决前边 N 种方案存在的问题引入了第 N+1 种方案。隔代的 C++ 程序员们该怎么沟通、共事?(此刻,我突然理解了那些依然坚持使用 C++98 的程序员们。)而且 Concepts 引入的长长的前缀语法抵消了 auto 所做的简化努力,语法笨重的问题反弹了。

为时晚矣……模版依然是特定人群(专家?)、特定领域(开源?)的小众选择。

6. 概念

精确指定并检查一个模板对于参数的要求曾经是 C++0x 的最出彩之处,会对泛型编程提供关键支持。可是,它最终甚至没能进入 C++17。

概念是简化泛型编程的宏伟计划的一部分。

因为这一点经常被忽视,我必须强调,概念是谓词,它们不是类或类层次结构。

6.3.6 改进

在 Concepts TS 工作的初期,一个 concept 是一个返回 bool 值的 constexpr 函数。

1
2
3
// 函数风格:
template<typename T>
concept bool Sequence() { return Has_begin<T>() && Has_end<T>(); }

然后 Gabriel Dos Reis 将变量模板引入到 C++14(§5.2)中。

1
2
3
// 表达式风格:
template<typename T>
concept bool Sequence = Has_begin<T> && Has_end<T>;

删除 bool 是 Richard Smith 提出的一系列改进建议的一部分

1
2
3
// 表达式风格:
template<typename T>
concept Sequence = Has_begin<T> && Has_end<T>;

6.3.7 等效语法

Concepts TS 支持在函数声明中使用概念的三种表示法:

为通用起见,显式使用 requires 语句

1
template<typename S> requires Sortable<S> void sort(S&);

简写表示法,用于表示类型的类型

1
template<Sortable S> void sort(S&); // 简写表示法

自然表示法(也称为简短表示法、常规表示法等)

1
void sort(Sortable &); // 自然表示法

自然表示法成为强烈反对概念的焦点。我——还有其他人——坚持这种优雅的表达…………我们看到(过去和现在)这是有用而优雅的一步,可以使泛型编程逐渐变成一种普通的编程方式,而不是一种具有不同语法、不同源代码组织偏好(“仅头文件”)和不同编码风格(例如模板元编程)的暗黑艺术

精准的命中 C++ 模版范式的死穴啊!

我也很确定,我的目标是使泛型编程尽可能地像“普通”编程,但这不是普遍共识。仍然有人认为,泛型编程超出了绝大部分程序员的能力。但我没有看到任何证据。

是现状无端形成了一道非必要的技术壁垒,导致绝大部分程序员远离了模版;而非泛型本身。“有人”在故意将因果倒置。

投票结果依然对我们不利:25 票赞成,31 票反对,8 票弃权。我的解释是,用户投了赞成票,语言技术人员投了反对票,但这可能会被认为是酸葡萄吧。

Concepts 被投票踢出了 C++17,我父急了……

6.4 C++20 概念

自然表示法(例如 void sort(Sortable&);)因有争议而被排除在外。

我父怂了,折中出了一个“丑八怪”方案:

使用 auto 来识别使用自然表达式的模板参数,例如 void f(Concept auto&);

1
2
3
4
// 几乎自然的表达式:
void sort(Sortable auto& x); // x 必须 Sortable
Integral auto ch = f(val); // f(val) 的结果必须为 Integral
Integral auto add(Integral auto x, Integral auto x); // 能用一个宽类型来防止溢出

为了能让用户感知到 Concepts 和 Template,在概念名称和变量中间插入了一个 auto,以区别于非模版代码……

“自然表达式”已重命名为“缩写语法”,虽然它不仅仅是一个缩写。

延迟很多年才引入概念造成了长期的伤害。
基于特征(traits)和 enable_if 的临时设计数量激增。一代程序员在低级的、无类型的元编程中成长起来

泪目,我父深知我心……我对模版所有的思考都化作了文章开头的引言,居然如此契合我父的心意,不枉我学之、用之、思之、信之。

评论