语内语义差异

时间:2010-08-27 22:55:38

标签: language-agnostic language-design language-features

我一直在考虑做自己的语言(实用性:这是一个思想实验)。我提出的一个想法是语内语义变异。你基本上编写了语义正则表达式,用等效代码替换。您可以在D-中稍微不那么直接地看到它 - 它们具有转换为D代码的字符串混合。除了我打算隐瞒它们,并以更循环的方式。

现在,我来自C ++。所以,如果你考虑:

string a, b, c, d;
// do stuff
a = b + c + d;

此代码会产生各种临时性。即使你有右值参考,你也会创建临时值,它们只会被更有效地重复使用。但它们仍然存在并仍然浪费性能。在最简单的情况下,我在考虑如何消除这些问题。您可以编写一个语义正则表达式,将其转换为最优化的形式。

string a, b, c, d;
// do stuff
a.resize(b.size() + c.size() + d.size());
a = b; a += c; a += d;

如果我实现了std :: string,我可能会写得更快一些。关键是它们是隐式的 - 当你使用std :: string类时,std :: string实现者编写的公理会影响任何std :: string代码。您可以将其放入现有的C ++代码库中,重新编译,并获得std :: string实现者可以免费设想的最快的字符串连接。

目前,您可以进行的优化是有限的,因为您只有语言允许的上下文,在这种情况下,C ++中的运算符重载只接受两个参数,this和arg。但语义注册表几乎可以占用您可能需要的所有上下文 - 因为您可以指定匹配的内容 - 甚至可以匹配宿主语言中不存在的语言功能。例如,交换

是微不足道的
string a;
a.size;

string a;
a.size();

如果你想窃取C#属性。您可以匹配类定义并实现编译或运行时反射等。

但是,我的意思是,它可能会让人感到困惑。如果有一个错误,或者幕后真的没有反映出编写的代码,那么追踪它可能是一个完全的婊子,我没有考虑如何深入实现它。你们怎么看待我提出的语言功能?

哦,伙计,选择正确的标签。嗯...

编辑:关于我的一个答案,我也想违反限制范围。简单的事实是语义正则表达式没有限制(减去可能必须添加的实现细节)。例如,您可以转换表达式

int i;
cin >> i;
int lols[i];

int i;
cin >> i;
std::variable_array<int>(alloca(sizeof(int) * i), i);

alloca的语义使得模板操作变得不可能 - 如果你想要上述内容,你必须编写一个宏。在C ++ 03或C ++ 0x中,您无法封装自己的VLA。

此外,语义正则表达式可以匹配实际上不会调用任何编译时工作的代码。例如,您可以匹配类定义的每个成员,并使用它来创建反射系统。到目前为止,这在C ++中也是不可能的。

2 个答案:

答案 0 :(得分:1)

如果谷歌有类似“C ++表达模板”的东西,你会发现实际上C ++已经具有非常相似的功能。根据你提出的语法,你的想法可能会使这些代码更容易理解(表达模板当然并非微不足道)但至少对我而言,你并没有完全清楚(如果有的话)以真正新的能力的方式。

答案 1 :(得分:1)

(警告:猛犸提前回答!)

我认为它被称为宏;)好吧,至少在C / C ++世界之外(“宏”指的是预处理器提供的这种严重限制的替换)。而且它不是很新颖。虽然我认为一个适当的,强大的宏系统可以为语言添加比任何其他功能更多的功能(假设我们保留了足够的原语,它不仅仅是turing-completene,而且对真正的编程很有用),因为一个足够聪明的程序员可以添加几乎所有可能在将来或特定域中有用的功能,而无需为该语言添加(进一步)规则。

基本思想是将程序解析为包含源代码的字符串上方的表示,例如ASTparse tree。这些树提供了有关程序的更多信息,另一个程序可以遍历此树并对其进行修改。例如,可以查找VariableDeclaration节点,检查它是否声明了T的普通旧数组,并将其替换为新的VariableDeclaration节点,而该节点改为声明{ {1}}的{​​1}}。例如,这可以通过为树提供模式匹配来改进,使元编程更容易。一个强大的过程,当且仅当程序员能够处理这种抽象级别并知道如何充分利用它时。

请注意,当我谈到“模式匹配”时,我会谈到函数式编程中的模式匹配,而不是正则表达式。正则表达式不足以理解不规则语言,这包括关于每一种有用的语言 - 仅仅允许包含平衡括号的粗略大小的表达式,规则正则表达式。有关模式匹配的精彩介绍,请参阅 What is 'Pattern Matching' in functional languages? 上的接受答案,如果只是学习如何使用它以及如何处理树,可能会学习像Haskell oder O'Caml这样的函数式语言(还有很多其他很酷的功能!)。

现在你提出的语言:老实说,我怀疑它会有用。 C ++本身就是如何不设计语言的完美示例(除非你想成功):采用现有语言,保持向后兼容=保留所有这些(包括坏东西),并添加一堆新功能它们本身就足够复杂,然后将它们调整一千次并添加一百个特殊情况,以便与现有语言的语法和语义或多或少地一起工作。它使得成功的可能性更大(如果你开始使用的语言已经很受欢迎),但你最终会得到一个神秘且不优雅的野兽。话虽这么说,我真的很想看到一种非lisp语言,允许这种能力的宏。

正确(或至少是更好)的方式是重新思考每一位,从最基本的语义到精确的语法,将其与您想要添加的内容集成,并调整新形成的语言的所有部分,直到整个画面看起来正确。在您的情况下,这会产生非常方便的副作用:易于解析。当然,必须在应用宏之前解析源代码,因为它们与树有关系,而不是字符串片段。但是C ++很难解析。就像字面上常用的难以解析的语言一样。

哦,虽然我们正在努力:Macros本身可以让我们心爱的工具(具有自动完成和调用技巧的IDE,静态代码分析等等)的生活变得悲惨。理解一段代码是很困难的,但是如果这个代码在到达执行的表单之前会被非常严重地转换,并且可能非常严重,那么它会变得更糟。通常,代码分析工具无法处理宏。整个区域非常难以clever people make up new languages for research on it and write papers on it neither of us can comprehend.所以要注意宏确实有缺点。