关于“everything is an expression”……

看到了以前讨论 LISP 的帖子,里面也讨论了其他语言,有人提到了:

(1)为什么 C/C++ 也属于“everything is an expression”的范畴?

(2)这么做的危害是什么?为了避免这个危害是否足应该放弃上述语言?

(3)正确的设计应该是什么?

很简单,2018 年我理想编程语言的是 Ada,严格区分 statement 和 expression。

帯副作用表达式的求值順序的 undefined behavior,以及短路语义的不透明(不过 scala只有 if else 是短路的)。

这个问题,还请读者自行判断

1 个赞

上午写的东西太乱了,还是重新理一下吧:

之前我在思考回归C89标准,也就是放弃所有C的新特性编程,但发现还是缺了点什么。C89里面的statement有六种类型:

statement
	: labeled_statement
	| compound_statement
	| expression_statement
	| selection_statement
	| iteration_statement
	| jump_statement
	;

然后这里面只有两个分支能从不含statement的句子归约到statement,一个是expression_statement,另一个是compound_statement(又叫做block)。

expression_statement
	: ';'
	| expression ';'
	;

compound_statement
	: '{' '}'
	| '{' statement_list '}'
	| '{' declaration_list '}'
	| '{' declaration_list statement_list '}'
	;

也就是说,能归约到statement的不含statement的句子,要么是{ declaration_list },要么是expression;,没别的了。而declaration不产生副作用,在C89里面甚至不参与运行时。所以,所有的求值,最后都来自于expression。而C89里面的expression只有一种子类型,assignment_expression

LdBeth关注的应该是对编译优化的影响,从语义上说,statement顺序应当决定IO顺序,但是,因为statement推导,而一个statement中诸expression应该何时被求值,是不受statement约束,也不应该受statement约束的。理想的状态应该是:每个statement都遵循时序,statement里的每个expression都能在语义上遵循约定的求值顺序。

assignment_expression的设计固然有蠢的好处,早期的芯片上,所有涉及io的指令,基本都是单指令流单数据的mov指令。但是现在的芯片就不太一样了。C目前也做了多发射和向量化SIMD的优化,那是建立在打乱既定的expression求值顺序的前提下的。这种优化在语义上对用户不透明,只能借助额外的、非语义上的同步机制。

我当时比较关注的是block不能参与assignment_expression的右值,在C89里面作为右值的必须是引用或者常量,{ initializer_list }不是expression,而且只能参与declaration。在C20里面,它是可以做右值的,但依然不是完整的block。我当时考虑的是一种允许以block为右值的C,block作为值而不是statement处理。

至于正确的设计是什么,我真的也不知道。

1 个赞

GCC 有这个扩展

P.S. 所以现在是谁?

J

能具体说说你们喜欢这些语言的原因吗,感觉都好偏,第一次听说。

首先,为了装 B 学过比一般编程语言比格高的 Scheme,Haskell,再实际写点东西深刻体会下它们的痛点,再看这个项目下面的演讲,重点看 APL Patterns vs. Anti-Patterns 和 Does APL Need a Type System? 这两篇

In a summary:

FP: Types help you document code

APL: Just write clearer, shorter code

FP: Types help correctness

APL: Just rewrite clearer shorter code more often

FP: Types improve performance

APL: Just rewrite clearer shorter code more often with a mechanically sympathetic language

FP: Types help you write new code rigorously

APL: Just rewrite clearer shorter code more often with a mechanically sympathetic language that optimizes suggestivity to reuse proven, correct code in more places

A language that doesn’t affect the way you think about programming is not worth knowing.

1 个赞

感谢!哈哈,感觉有点难度。

所以 APL 和 J 是如何处理 statement/expression 问题的?

分开的,control flow 不能当 expression 用