19

我目前正在开发一种用于在连续环境中进行编程的新语言(将其与电气工程进行比较),并且我对某种语言构造有了一些想法。

让我通过解释然后通过定义来解释该功能:

x = a U b;

wherex是变量,aandb是其他变量(或静态值)。这就像 and 之间的联合a一样b;没有重复,也没有特定的顺序。

with(x) {
    // regular 'with' usage; using the global interpretation of "x"
    x = 5;
    // effectively will do:
    // x = a U b U 5;
    // a = 5;
    // b = 5;
    // Thus, when "a" or "b" changes, "x" is still equal to "5".
}
with(x = a) {
    // this code block is executed when the "x" variable
    // has the "a" variable assigned. All references in
    // this code-block to "x" are references to "a". So saying:
    x = 5;
    // would only change the variable "a". If the variable "a"
    // later on changes, x still equals to 5, in this fashion:
    // 'x = a U b U 5;'
    // '[currentscope] = 5;'
    // thus, 'a = 5;'
}
with(x = b) {
    // same but with "b"
}
with(x != a) {
    // here the "x" variable refers to any variable
    // but "a"; thus saying
    x = 5;
    // is equal to the rewriting of
    // 'x = a U b U 5;'
    // 'b = 5;' (since it was the scope of this block)
}
with(x = (a U b)) {
    // guaranteed that "x" is 'a U b'; interacting with "x"
    // will interact with both "a" and "b".
    x = 5;
    // makes both "a" and "b" equal to 5; also the "x" variable
    // is updated to contain:
    // 'x = a U b U 5;'
    // '[currentscope] = 5;'
    // 'a U b = 5;'
    // and thus: 'a = 5; b = 5;'.
}
// etc.

在上面,所有代码块都被执行,但是每个块中的“范围”会发生变化,如何x解释。在第一个块中,x保证为a: 因此与x该块内部的交互将在 上交互a。只有在这种情况下,第二个和第三个代码块才相等(因为not a: 那么只剩下b)。最后一个块保证x至少是aor b

此外; U不是“按位或运算符”,但我称它为“和/或”运算符。它的定义是:

"U" = "and" U "or"

(在我的博客http://cplang.wordpress.com/2009/12/19/binop-and-or/上,有更多关于此运算符的(数学)背景信息。它松散地基于集合。使用不同的语法,在这个问题中改变了它。)

更新:更多示例。

print = "Hello world!" U "How are you?"; // this will print
                                         // both values, but the
                                         // order doesn't matter.
// 'userkey' is a variable containing a key.
with(userkey = "a") {
    print = userkey; // will only print "a".
}
with(userkey = ("shift" U "a")) {
    // pressed both "shift" and the "a" key.
    print = userkey; // will "print" shift and "a", even
                     // if the user also pressed "ctrl":
                     // the interpretation of "userkey" is changed,
                     // such that it only contains the matched cases.
}
with((userkey = "shift") U (userkey = "a")) {
    // same as if-statement above this one, showing the distributivity.
}

x = 5 U 6 U 7;
y = x + x; // will be:
// y = (5 U 6 U 7) + (5 U 6 U 7)
//   = 10 U 11 U 12 U 13 U 14

somewantedkey = "ctrl" U "alt" U "space"
with(userkey = somewantedkey) {
    // must match all elements of "somewantedkey"
    // (distributed the Boolean equals operated)
    // thus only executed when all the defined keys are pressed
}
with(somewantedkey = userkey) {
    // matches only one of the provided "somewantedkey"
    // thus when only "space" is pressed, this block is executed.
}

Update2:更多示例和更多上下文。

with(x = (a U b)) {
    // this
}
// can be written as
with((x = a) U (x = b)) {
    // this: changing the variable like
    x = 5;
    // will be rewritten as:
    // a = 5 and b = 5
}

一些背景信息:我正在构建一种“与时间无关”的语言,例如 Java 是“与平台无关的”。语言中陈述的一切都是“原样”,并且不断地积极执行。这表示; 程序员不知道元素的顺序(除非使用构造明确说明),也不知道语句何时执行。该语言与“时间”概念完全分离,即它是连续执行的:

with(true) {
    a = 0; // only runs once (lazy execution)
}

with(a < 5) {
    a++;
} // this is a loop-structure;
  // how and when it's executed isn't known however.

with(a) {
    // everytime the "a" variable changes, this code-block is executed.
    with(true) {
        b = 3; // only 5 times (again lazy execution, but it's a sub-with)
    }
    with(b < 2) { // dependent on "b"
        // runs only 3 times * 5 times = 15 times.
    }
    with(b > 1) { // dependent on "b"
        b = b - 1; // runs 4 times * 5 times = 20 times.
    }
}

更新 3:

琢磨了一下这个语言特征的类型;它与 Netbeans Platform 的 Lookup 非常相似,其中每个“with”语句都是一个同步代理,处理它的特定对象“过滤器”。这不是基于类型,而是基于变量(基本上完全相同;只是识别对象的不同方式)。

我非常感谢你们为我提供了非常有见地的信息以及我可以研究的重要主题的链接/提示。谢谢。

我不知道这种结构是否已经存在,所以这是我的问题:这种语言特性是否已经存在?

4

10 回答 10

4

我发现这很难理解,但你的意思是:

x == a | b 

将是语法糖等价于:

(x == a) || (x == b)

在博客文章中,您给出了这个例子:

1 + (2|3)

因此,该表达式的类型是一对整数,其值为 3 和 4,每个整数代表一个可能的值。所以我们也可以说:

4 == (1 + (2|3)
3 == (1 + (2|3)

并且这两个都将评估为真。因此,运算符==可以将一个值与一种值向量进行比较,并且true如果向量中的任何值等于第一个值,则为。

这可以在几种语言中使用运算符重载来实现(尽管在对它们进行操作之前,您必须显式地将简单值“提升”到包装器类型中)。

它不是实际上与两个集合的并集相同,并且 == 被解释为“是其中的成员”吗?并且运算符喜欢 + 被提升,因此它们适用于集合的所有成员。

如果你做了 (1|2) + (4|8),你将得到 (5|9|6|10) 的等价物,因为这是四种可能的结果。

好的,从您添加的进一步示例中,我看到==实际上要求左右两侧是同一组,而不仅仅是重叠。但我仍然觉得你|只是两组的结合。这需要(或意味着)什么将取决于您对语言的所有其他功能所做的处理以处理集合。

关于你的说法:

语言完全脱离了“时间”的概念

你是否看过像 Haskell 这样的纯函数式语言?程序是一系列不知道执行顺序的定义,你只能编写没有副作用的纯函数,因此解释器可以随意排序执行,只要值在真正需要时可用。

更新:

您将此添加到您的问题中:

if(x == a | b) {
    // this 
}
// can be written as
if((x == a) | (x == b)) {
    // this
}
// which can be written as
if(x == a) {
    // this
}
if(x == b) {
    // with this
}

我想知道你认为这将如何具有启发性!

问题是,前两个版本在 if 下有一个代码块。所以如果第三个扩展版本有两个块,它们必须是同一个块。换句话说,这只是另一种写法:

if (x == a || x == b) {
    // this
}

在哪里 || 是传统的布尔 OR。这正是我第一次问的问题。

好的,再来一次……您现在更改了语法以表明您正在执行联合和交叉。但是之后:

if(userkey I ("shift" U "a")) {
    // pressed both "shift" and the "a" key.

所以I意味着取两组的交集……但是if在什么情况下执行代码块?如果交叉点是非空的?或者I实际上是在问“右边集合的所有成员都是左边集合的成员”并且有一些提示userkey在块的范围内被另一个值替换,实际上只是右边的集合。

我要去睡觉了。

于 2010-03-24T23:22:23.397 回答
4

老实说,我发现您的解释和示例很难理解(更新:您的博客要好得多,并且在那里阅读Statement Ordering我更加确信您的目标是一种数据流编程形式)。

但是,您的最终描述:

语言中陈述的一切都是“原样”,并且不断地积极执行。这表示; 程序员不知道元素的顺序(除非使用构造明确说明),也不知道语句何时执行。该语言与“时间”概念完全分离,即它是连续执行的:例如,说“a”是“b”而“b”是“a”是一个简单的循环结构。

.. 使我认为您正在搜索的通用术语是数据流编程(即使在更简单的数据流编程实例中不允许循环)。引用维基百科:

数据流是一种软件架构,其理念是改变变量的值应该自动强制重新计算依赖于其值的变量的值。

了解,反应式编程函数式反应式编程是同一主题的变体。

Icon 的目标导向评估在范围上受到更多限制(请参阅此Icon 简介目标导向评估机制所隐含的回溯仅限于它发生的表达式)。

另请参阅 Stackoverflow 上的这个问题:数据流编程语言

更新: Pindatjuh 在评论中询问“您能否评论一下,这种语言是否是数据流主题的新变体? ”。我认为是这样,但问题实际上是关于定义和共识。在最近关于数据流语言的调查中,数据流编程语言的进步(发表在ACM 计算调查,第 36 卷,第 1 期,2004 年 3 月)中,作者写道(第 10 页):

构成数据流语言的最佳特征列表由 Ackerman [1982] 提出,并由 Whiting 和 Pascoe [1994] 以及 Wail 和 Abramson [1995] 重申。此列表包括以下内容:

  1. 无副作用,
  2. 影响的局部性,
  3. 数据依赖等价于调度,
  4. 变量的单一赋值,
  5. 由于特征 1 和 4,迭代的不寻常表示法,
  6. 程序缺乏历史敏感性。

我没有阅读你所有的博客,只是轻轻地阅读了它,所以你比我更有资格判断你的编程语言(无论如何这是一个移动的目标)。

更新:我无意识地错过了你的问题中的“新”这个词“ ......这种语言是......”的变体。这是一项艰巨的任务:需要考虑迄今为止发明的所有数据流语言,并仔细检查它们的语义,以发现您的方法中的新奇之处。我现在肯定没有必要的知识。

于 2010-03-25T00:41:53.180 回答
3

您的示例和您的数学都可以使用一些工作,但在您博客上的至少一个示例中,您的使用与Icon 编程语言|中相同运算符(我相信称为“交替”)的 使用非常相似。

如果你打算在这个领域进行语言设计,你绝对应该阅读

于 2010-03-24T23:32:31.420 回答
3

C# 当然不具备您所描述的功能。你所说的似乎有点让人想起 Robin Milner 的 pi 演算;这一切都是关于定义一种用于描述并发进程的语言。如果您还没有,您可能会考虑对其进行一些研究。

于 2010-03-24T23:45:46.163 回答
3

您的语言功能类似于Perl 6 中的联结

在 Perl 5 中,有Quantum::Superpositions模块。

于 2010-03-25T01:01:58.660 回答
2

您应该发明自己的符号,即使只是为了示例。

看起来您正在尝试根据范围定义的需要进行动态更改的变量引用。这是一种非常微妙的技术,我不知道任何语言可以做到这一点。大多数语言都要求您明确地执行此操作,尽管我可以看到与闭包、生成器和回溯的相似之处。

你能解释一下驱动这种不寻常方法的背景吗?你的博客链接不是很有帮助。并且“连续编程”一词也没有定义或解释。

更新:

好的,看看你编辑的例子,我可以指出 Icon 有类似的东西。它不是您认为您所要求的,它并不常见,但它看起来很接近并且定义得更好。它被称为目标导向评估。

许多语言元素提供或允许您构建一个生成器,如果需要,它可以提供许多替代方案。您的示例和 Icon 之间的主要区别是您必须为语言提供上下文以继续尝试替代方案。分配不会这样做,但比较会。一旦生成器用完它可以提供的值,它就会失败。这也是普通比较的工作原理,整个功能很好地集成到更广泛的语言中。(我有时将其描述为微型例外。)

Python 和 Ruby 有一个yield非常相似的机制,并且可以说受到 Icon 的生成器的影响。

于 2010-03-24T23:31:58.853 回答
0

我建议您不要添加该语言功能。如果您执行以下“测试”,程序员将非常不清楚 x 的含义会发生变化:

if( x != a ) { ... }
于 2010-03-24T23:32:02.767 回答
0

Inform IF 创作语言具有此功能。来自DM

if (alpha == 3 or 4) print "Scott";

不过,它并没有真正深入人心,因为解析起来有点奇怪(您必须将每个or/|运算符与特定的所有者==/!=比较器相关联),并且在现代脚本语言中,它很容易替换为以下内容:

if alpha in (3, 4):
    print 'Scott';

(Python 示例。)

于 2010-03-24T23:33:09.127 回答
0

您似乎同时考虑了几个想法:

  • 一种列表语法,您可以在其中执行类似的操作 5 | 6 | 7
  • 使用你一直在写的外部产品 ::list:: + ::list::
  • 当一个或两个参数是一个列表时,仔细定义等式、不等式、赋值等运算符的含义。即::scalor:: == ::list::实现“is an element of”,依此类推

我不知道结合这些想法的单一语法特征,但我没有真正广泛的经验......

于 2010-03-24T23:48:24.050 回答
0

as3中存在“with”:

private var _a:Number = 0.0;
public function get a():Number{
// Do stuff
    return _a;
}
public function set a(value:Number):void{
// Do stuff
    _a=value;
}
于 2010-03-25T21:12:31.607 回答