像我 8 岁孩子一样向我解释连接语言
我读过关于连接语言的维基百科文章,我现在比以前更困惑我已开始。 :-)
用愚蠢的人的话来说,什么是连接语言?
I've read the Wikipedia article on concatenative languages, and I am now more confused than I was when I started. :-)
What is a concatenative language in stupid people terms?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
在普通的编程语言中,您可以自由定义变量,并使用这些变量作为参数来调用方法。 这些很容易理解,但有些局限性。 通常,很难重用现有方法,因为您根本无法将现有变量映射到方法所需的参数,或者方法 A 调用另一个方法 B,如果您只能替换对 B 的调用,那么 A 将是完美的选择通过调用 C。
连接语言使用固定的数据结构来保存值(通常是堆栈或列表)。 没有变量。 这意味着许多方法和函数具有相同的“API”:它们处理其他人留在堆栈上的东西。 加代码本身被认为是“数据”,即通常编写可以修改自身或接受其他代码作为“参数”(即作为堆栈上的元素)的代码。
这些属性使这种语言非常适合链接现有代码以创建新的东西。 重用是内置的。您可以编写一个函数,它接受一个列表和一段代码,并为列表中的每个项目调用代码。 现在,只要它的行为类似于列表,这将适用于任何类型的数据:来自数据库的结果、图像中的一行像素、字符串中的字符等。
最大的问题是您不知道发生了什么。 只有几种数据类型(列表、字符串、数字),因此所有内容都会映射到这些数据类型。 当您获得一段数据时,您通常不关心它是什么或它来自哪里。 但这使得很难通过代码跟踪数据来了解它发生了什么。
我相信成功使用这些语言需要一定的心态。 它们并不适合所有人。
[编辑] Forth 有一定的渗透力,但不是那么多。 您可以在任何现代激光打印机中找到 PostScript。 所以它们是小众语言。
从功能层面来看,它们与 LISP、类 C 语言和 SQL 相当:它们都是图灵完备,所以你可以计算任何东西。 这只是您需要编写多少代码的问题。 有些事情在 LISP 中更简单,有些在 C 中更简单,有些在查询语言中更简单。 除非你有上下文,否则“更好”的问题是徒劳的。
In normal programming languages, you have variables which can be defined freely and you call methods using these variables as arguments. These are simple to understand but somewhat limited. Often, it is hard to reuse an existing method because you simply can't map the existing variables into the parameters the method needs or the method A calls another method B and A would be perfect for you if you could only replace the call to B with a call to C.
Concatenative language use a fixed data structure to save values (usually a stack or a list). There are no variables. This means that many methods and functions have the same "API": They work on something which someone else left on the stack. Plus code itself is thought to be "data", i.e. it is common to write code which can modify itself or which accepts other code as a "parameter" (i.e. as an element on the stack).
These attributes make this languages perfect for chaining existing code to create something new. Reuse is built in. You can write a function which accepts a list and a piece of code and calls the code for each item in the list. This will now work on any kind of data as long it's behaves like a list: results from a database, a row of pixels from an image, characters in a string, etc.
The biggest problem is that you have no hint what's going on. There are only a couple of data types (list, string, number), so everything gets mapped to that. When you get a piece of data, you usually don't care what it is or where it comes from. But that makes it hard to follow data through the code to see what is happening to it.
I believe it takes a certain set of mind to use the languages successfully. They are not for everyone.
[EDIT] Forth has some penetration but not that much. You can find PostScript in any modern laser printer. So they are niche languages.
From a functional level, they are at par with LISP, C-like languages and SQL: All of them are Turing Complete, so you can compute anything. It's just a matter of how much code you have to write. Some things are more simple in LISP, some are more simple in C, some are more simple in query languages. The question which is "better" is futile unless you have a context.
首先我要反驳诺曼·拉姆齐关于不存在理论的断言。
连接语言理论
连接语言是一种函数式编程语言,其中默认操作(当两个项并排时发生的情况)是函数组合而不是函数应用。 它是如此简单。
例如,在 SKI Combinator Calculus(最简单的函数语言之一)中,并排的两个术语相当于将第一项应用于第二项。 例如:
SK K
相当于S(K)(K)
。在连接语言中
SK K
相当于S 。 K. Haskell 中的 K。
那么有什么大不了的
纯粹的连接语言有一个有趣的特性,即术语的求值顺序并不重要。 在连接语言中,
(SK) K
与S (KK)
相同。 这不适用于 SKI 微积分或任何其他基于函数应用的函数编程语言。这一观察结果很有趣的一个原因是,它揭示了在以函数组合而不是应用程序表示的代码评估中并行化的机会。
现在进入现实世界
支持高阶函数的基于堆栈的语言的语义可以使用串联演算来解释。 您只需将每个术语(命令/表达式/子程序)映射为一个函数,该函数将函数作为输入并返回函数作为输出。 整个程序实际上是一个堆栈转换函数。
现实情况是,现实世界中的事物总是被扭曲的(例如 FORTH 有一个全局字典,PostScript 在评估顺序很重要的情况下会做一些奇怪的事情)。 大多数实用的编程语言并不完全遵循理论模型。
结束语
我认为一个典型的程序员或 8 岁的孩子不应该担心什么是连接语言。 我也不认为它对于将编程语言划分为 X 型或 Y 型特别有用。
First I'm going to make a rebuttal to Norman Ramsey's assertion that there is no theory.
Theory of Concatenative Languages
A concatenative language is a functional programming language, where the default operation (what happens when two terms are side by side) is function composition instead of function application. It is as simple as that.
So for example in the SKI Combinator Calculus (one of the simplest functional languages) two terms side by side are equivalent to applying the first term to the second term. For example:
S K K
is equivalent toS(K)(K)
.In a concatenative language
S K K
would be equivalent toS . K . K
in Haskell.So what's the big deal
A pure concatenative language has the interesting property that the order of evaluation of terms does not matter. In a concatenative language
(S K) K
is the same asS (K K)
. This does not apply to the SKI Calculus or any other functional programming language based on function application.One reason this observation is interesting because it reveals opportunities for parallelization in the evaluation of code expressed in terms of function composition instead of application.
Now for the real world
The semantics of stack-based languages which support higher-order functions can be explained using a concatenative calculus. You simply map each term (command/expression/sub-program) to be a function that takes a function as input and returns a function as output. The entire program is effectively a single stack transformation function.
The reality is that things are always distorted in the real world (e.g. FORTH has a global dictionary, PostScript does weird things where the evaluation order matters). Most practical programming languages don't adhere perfectly to a theoretical model.
Final Words
I don't think a typical programmer or 8 year old should ever worry about what a concatenative language is. I also don't find it particularly useful to pigeon-hole programming languages as being type X or type Y.
阅读http://concatenative.org/wiki/view/Concatenative%20language并绘图后根据我对青少年时期摆弄 Forth 的记忆,我相信串联编程的关键在于:
查看上述网页中的这些引用:
这与将其函数直接应用于特定变量的应用语言形成鲜明对比。
示例:两个数字相加。
应用语言:
连接语言(我编的,应该与Forth类似......;))
虽然我不认为连接语言=堆栈语言,因为作者在上面指出,看起来很相似。
After reading http://concatenative.org/wiki/view/Concatenative%20language and drawing on what little I remember of fiddling around with Forth as a teenager, I believe that the key thing about concatenative programming has to do with:
Check out these quotes from the above webpage:
This is in contrast to applicative languages that apply their functions directly to specific variables.
Example: adding two numbers.
Applicative language:
Concatenative language (I made it up, supposed to be similar to Forth... ;) )
While I don't think concatenative language = stack language, as the authors point out above, it seems similar.
我认为主要思想是 1. 我们可以简单地通过将其他程序连接在一起来创建新程序。
另外,2. 程序的任何随机块都是有效函数(或子程序)。
好的旧的纯 RPN Forth 具有这些属性,不包括任何随机的非 RPN 语法。
在程序 1 2 + 3 * 中,子程序 + 3 * 采用 2 个参数,并给出 1 个结果。 子程序 2 采用 0 个参数并返回 1 个结果。 任何块都是一个函数,这很好!
您可以通过将两个或多个其他函数组合在一起(可以选择使用一点胶水)来创建新函数。 如果类型匹配的话效果最好!
这些想法确实很好,我们重视简单性。
它不限于 RPN Forth 风格的串行语言,也不限于命令式或函数式编程。 这两种想法也适用于图形语言,其中程序单元可以是例如函数、过程、关系或进程。
在通信进程的网络中,每个子网络都可以像一个进程一样运行。
在数学关系图中,每个子图都是有效关系。
这些结构是“连接的”,我们可以以任何方式将它们分开(画圆圈),并以多种方式将它们连接在一起(画线)。
嗯,我就是这么看的。 我确信我错过了来自串联阵营的许多其他好主意。 虽然我热衷于图形编程,但我对串联的关注还是陌生的。
I reckon the main idea is 1. We can create new programs simply by joining other programs together.
Also, 2. Any random chunk of the program is a valid function (or sub-program).
Good old pure RPN Forth has those properties, excluding any random non-RPN syntax.
In the program 1 2 + 3 *, the sub-program + 3 * takes 2 args, and gives 1 result. The sub-program 2 takes 0 args and returns 1 result. Any chunk is a function, and that is nice!
You can create new functions by lumping two or more others together, optionally with a little glue. It will work best if the types match!
These ideas are really good, we value simplicity.
It is not limited to RPN Forth-style serial language, nor imperative or functional programming. The two ideas also work for a graphical language, where program units might be for example functions, procedures, relations, or processes.
In a network of communicating processes, every sub-network can act like a process.
In a graph of mathematical relations, every sub-graph is a valid relation.
These structures are 'concatenative', we can break them apart in any way (draw circles), and join them together in many ways (draw lines).
Well, that's how I see it. I'm sure I've missed many other good ideas from the concatenative camp. While I'm keen on graphical programming, I'm new to this focus on concatenation.
我对串联编程的务实(和主观)定义(现在,您可以避免阅读其余部分):
-> 极端方式的函数组合(使用逆波兰表示法(RPN)语法):
-> 一切都是函数,或者至少可以是函数:
-> 参数通过函数隐式传递(好吧,这似乎是默认编程的定义),但是,Forth中的this:
可能在Lisp中:
所以,很容易生成不明确的代码......
您可以编写将 xt (执行令牌)压入堆栈的定义,并为“execute”定义一个小别名:
因此,您将得到:
My pragmatic (and subjective) definition for concatenative programming (now, you can avoid read the rest of it):
-> function composition in extreme ways (with Reverse Polish notation (RPN) syntax):
-> everything is a function, or at least, can be a function:
-> arguments are passed implicitly over functions (ok, it seems to be a definition for tacit-programming), but, this in Forth:
may be in Lisp:
so, it's easy to generate ambiguous code...
you can write definitions that push the xt (execution token) on stack and define a small alias for 'execute':
so, you'll get:
对于你的简单问题,这是一个主观且有争议的答案。
我查看了这篇文章和几个相关网页。 这些网页本身就说不存在真正的理论,因此难怪人们很难想出一个精确且易于理解的定义。 我想说,目前,将语言分类为“连接性”或“非连接性”没有用。
对我来说,它看起来像是一个术语,为曼弗雷德·冯·图恩提供了一个悬挂他的作品的地方帽子,但可能对其他程序员没有用。
虽然 PostScript 和 Forth 值得研究,但我在 Manfred von Thun 的 Joy 编程语言中没有看到任何非常新或有趣的东西。 事实上,如果您阅读 Chris Okasaki 的论文 在 Haskell 中嵌入 Postfix 语言的技术 你可以在相对于 Joy 来说完全主流的环境中尝试所有这些东西。
所以我的答案是没有简单的解释,因为连接语言的想法没有成熟的理论基础。 (正如爱因斯坦和费曼所说,如果你不能向大学新生解释你的想法,那么你就没有真正理解它。)我会更进一步说,尽管学习其中一些语言,如 Forth 和 PostScript,是一种充分利用时间,试图弄清楚人们说“连接”时的确切含义可能是浪费你的时间。
To your simple question, here's a subjective and argumentative answer.
I looked at the article and several related web pages. The web pages say themselves that there isn't a real theory, so it's no wonder that people are having a hard time coming up with a precise and understandable definition. I would say that at present, it is not useful to classify languages as "concatenative" or "not concatenative".
To me it looks like a term that gives Manfred von Thun a place to hang his hat but may not be useful for other programmers.
While PostScript and Forth are worth studying, I don't see anything terribly new or interesting in Manfred von Thun's Joy programming language. Indeed, if you read Chris Okasaki's paper on Techniques for Embedding Postfix Languages in Haskell you can try out all this stuff in a setting that, relative to Joy, is totally mainstream.
So my answer is there's no simple explanation because there's no mature theory underlying the idea of a concatenative language. (As Einstein and Feynman said, if you can't explain your idea to a college freshman, you don't really understand it.) I'll go further and say although studying some of these languages, like Forth and PostScript, is an excellent use of time, trying to figure out exactly what people mean when they say "concatenative" is probably a waste of your time.
你无法解释一种语言,只需获取一种语言(最好是 Factor)并尝试 一些教程。 教程比 StackOverflow 答案更好。
You can't explain a language, just get one (Factor, preferably) and try some tutorials on it. Tutorials are better than Stack Overflow answers.