向我解释连接语言,就像我是一个8岁的孩子

Jas*_*ker 27 programming-languages concatenative-language

我已经阅读了关于连接语言维基百科文章,现在我比起初时更加困惑.:-)

用愚蠢的人来说,什么是串联语言?

Aar*_*lla 18

在普通的编程语言中,您可以自由定义变量,并使用这些变量作为参数调用方法.这些很容易理解但有些限制.通常,很难重用现有方法,因为您根本无法将现有变量映射到方法所需的参数,或者方法A调用另一种方法B,如果只能替换对B的调用,则A对您来说是完美的.打电话给C.

连接语言使用固定的数据结构来保存值(通常是堆栈或列表).没有变数.这意味着许多方法和函数具有相同的"API":它们处理其他人留在堆栈中的内容.加上代码本身被认为是"数据",即编写可以自己修改或接受其他代码作为"参数"(即作为堆栈中的元素)的代码是很常见的.

这些属性使这些语言非常适合链接现有代码以创建新内容.内置重用.您可以编写一个接受列表和一段代码的函数,并为列表中的每个项调用代码.这将适用于任何类型的数据,只要它的行为类似于列表:数据库的结果,图像中的一行像素,字符串中的字符等.

最大的问题是你没有暗示发生了什么.只有几种数据类型(列表,字符串,数字),所以一切都映射到它.当您获得一条数据时,通常不关心它是什么或它来自何处.但这使得通过代码跟踪数据很难看到发生了什么.

我认为成功使用语言需要一定的心态.它们不适合所有人.

[编辑] Forth有一些渗透但不是那么多.您可以在任何现代激光打印机中找到PostScript.所以他们是利基语言.

从功能层面来看,它们与LISP,类C语言和SQL相同:所有这些都是Turing Complete,所以你可以计算任何东西.这只是你需要编写多少代码的问题.有些东西在LISP中更简单,有些在C中更简单,有些在查询语言中更简单.除非你有一个背景,否则"更好"的问题是徒劳的.

  • 很好的解释,但我想知道为什么应该使用连接语言代替像LISP这样的东西 - 它似乎只是基于列表的语言可以做的功能的一个子集.(换句话说,您是否可以详细说明串联语言的列表/堆栈处理是否只是其他语言的限制版本?) (2认同)
  • 另一个挑剔:SQL本身并不是图灵完整的.虽然大多数DBMS都有扩展,使得图灵完成(这就是T-SQL,pl/SQL等意思) (2认同)
  • @SamWatkins:RPN允许使用紧凑的代码但不易理解,因为你需要重新排序/模拟脑中的堆栈. (2认同)

cdi*_*ins 14

首先,我要对诺曼·拉姆齐的断言进行反驳,即没有理论.

连接语言理论

连接语言是一种函数式编程语言,默认操作(当两个术语并排时会发生什么)是函数组合而不是函数应用程序.它是如此简单.

因此,例如在SKI Combinator Calculus(最简单的函数语言之一)中,两个并排的术语相当于将第一个术语应用于第二个术语.例如:S K K相当于S(K)(K).

在连接语言S K K中将等同S . K . K于Haskell.

那有什么大不了的

纯连接语言具有有趣的特性,即术语评估的顺序无关紧要.在连接语言中(S K) K是相同的S (K K).这不适用于SKI微积分或任何其他基于功能应用的函数编程语言.

这一观察结果之一的一个原因很有意思,因为它揭示了在根据功能组成而不是应用表达的代码评估中进行并行化的机会.

现在为现实世界

支持高阶函数的基于堆栈的语言的语义可以使用连接微积分来解释.您只需将每个术语(命令/表达式/子程序)映射为一个函数,该函数将函数作为输入并将函数作为输出返回.整个程序实际上是单个堆栈转换功能.

现实情况是,在现实世界中事物总是被扭曲的(例如,FORTH有一个全局字典,PostScript做了评价顺序很重要的奇怪事情).大多数实用的编程语言并不完全符合理论模型.

最后的话

我不认为一个典型的程序员或8岁的人应该担心串联语言是什么.我也没有发现它对于鸽子洞编程语言特别有用,因为它是X型或Y型.


J. *_*fer 5

在阅读了http://concatenative.org/wiki/view/Concatenative%20language并借鉴了我记得在十几岁的时候摆弄Forth时,我认为关于连接编程的关键在于:

  • 根据特定数据堆栈上的值查看数据
  • 和函数根据在同一数据堆栈上弹出/推送值来操纵东西

查看以上网页上的这些引用:

有两个术语被抛出,堆栈语言和连接语言.两者都定义了相似但不相同的语言类.但在大多数情况下,它们是相同的.

今天广泛使用的大多数语言都是应用语言:语言中的中心构造是某种形式的函数调用,其中函数应用于一组参数,其中每个参数本身就是函数调用的结果,一个名称是变量或常数.在堆栈语言中,通过简单地写入函数的名称来进行函数调用; 参数是隐式的,并且在进行调用时它们必须已经在堆栈中.函数调用的结果(如果有的话)在函数返回后留在堆栈上,以供下一个函数使用,依此类推.因为函数只是通过提及它们的名称而不需要任何其他语法来调用,所以Forth和Factor将函数称为"单词",因为在语法中它们实际上只是单词.

这与将其功能直接应用于特定变量的应用语言形成对比.

示例:添加两个数字.

适用语言:

int foo(int a, int b)
{
    return a + b;
}

var c = 4;
var d = 3;
var g = foo(c,d);
Run Code Online (Sandbox Code Playgroud)

连接语言(我编写了,应该类似于Forth ...;))

push 4
push 3
+
pop
Run Code Online (Sandbox Code Playgroud)

虽然我不认为连接语言=堆栈语言,正如作者上面指出的那样,它看起来很相似.


Sam*_*ins 5

我认为主要的想法是 1. 我们可以简单地通过将其他程序连接在一起来创建新程序。

此外, 2. 程序的任何随机块都是有效的函数(或子程序)。

好的老纯 RPN Forth 具有这些属性,不包括任何随机的非 RPN 语法。

在程序 1 2 + 3 * 中,子程序 + 3 * 接受 2 个参数,并给出 1 个结果。子程序 2 取 0 个参数并返回 1 个结果。任何块都是一个函数,这很好!

您可以通过将两个或更多其他功能组合在一起来创建新功能,也可以选择使用少量胶水。如果类型匹配,它将效果最佳!

这些想法真的很好,我们重视简单。

它不限于 RPN Forth 风格的串行语言,也不限于命令式或函数式编程。这两种想法也适用于图形语言,其中程序单元可能是例如函数、过程、关系或过程。

在通信进程的网络中,每个子网络都可以像一个进程一样工作。

在数学关系图中,每个子图都是有效关系。

这些结构是“串联的”,我们可以以任何方式将它们分开(画圆圈),并以多种方式将它们连接在一起(画线)。

嗯,这就是我的看法。我敢肯定我已经错过了来自串联阵营的许多其他好主意。虽然我热衷于图形化编程,但我对这种对连接的关注还不熟悉。


Nor*_*sey 0

对于你的简单问题,这是一个主观且有争议的答案。

我查看了这篇文章和几个相关网页。这些网页本身就说不存在真正的理论,因此难怪人们很难想出一个精确且易于理解的定义。我想说,目前,将语言分类为“连接”或“非连接”是没有用的。

对我来说,这个术语似乎给曼弗雷德·冯·图恩 (Manfred von Thun)提供了一个立足之地,但对其他程序员来说可能没有用处。

虽然 PostScript 和 Forth 值得研究,但我在 Manfred von Thun 的 Joy 编程语言中没有看到任何非常新或有趣的东西。事实上,如果你读过 Chris Okasaki 的关于在 Haskell 中嵌入 Postfix 语言的技术的论文,你就可以在相对于 Joy 来说完全主流的环境中尝试所有这些东西。

所以我的答案是没有简单的解释,因为连接语言的想法没有成熟的理论基础。(正如爱因斯坦和费曼所说,如果你不能向大学新生解释你的想法,那么你就没有真正理解它。)我会更进一步说,尽管学习其中一些语言,如 Forth 和 PostScript,是一种充分利用时间,试图弄清楚人们说“连接”时的确切含义可能是浪费你的时间。

  • 我并没有说语言是浪费时间。PostScript 和 FORTH 是值得学习的好东西。我说试图弄清楚人们所说的“连接”到底是什么意思是浪费时间。 (3认同)
  • 我讨厌将此视为已接受的答案。这是不对的。连接只是具有这样的属性:_你可以砍掉它的一部分,它是一个有效的程序,然后连接程序并得到另一个程序_。如此简单,真的不需要太多解释。串联编程语言还有其他一些功能,但这是其定义功能。 (3认同)