3

级联语言有一些非常有趣的特性,例如能够组合不同数量的函数,并且能够分解出函数的任何部分。然而,许多人不屑一顾,因为它们使用了后缀表示法,而且很难阅读。另外,波兰人可能不喜欢人们倒着使用他们精心制作的符号。

那么,是否可以有前缀符号?如果是,那么权衡是什么?

我知道它是如何工作的,但我对连接语言没有经验,所以我可能遗漏了一些东西。基本上,一个函数将以相反的顺序被评估,而值将从堆栈中以相反的顺序被拉出。为了证明这一点,我将比较后缀和前缀的样子。以下是一些使用传统后缀表示法的连接表达式。

5 dup *                             ! Multiply 5 by itself
3 2 -                               ! Subtract 2 from 3
(1, 2, 3, 4, 5) [2 >] filter length ! Get the number of integers from 1 to 5
                                    ! that are greater than 2

表达式从左到右计算:在第一个示例中,5被压入堆栈,然后dup复制堆栈顶部的值,然后将堆栈*顶部的两个值相乘。函数首先从堆栈中提取最后一个参数:在第二个示例中,-调用时2位于堆栈顶部,但它是最后一个参数。

这是我认为前缀表示法的样子:

* dup 5
- 3 2
length filter (1, 2, 3, 4, 5) [< 2]

表达式从右到左求值,函数首先从堆栈中提取它们的第一个参数。请注意前缀过滤器示例如何与其描述更接近,并且看起来与应用样式相似。我注意到的一个问题是考虑因素可能没有那么有用。例如,在后缀表示法中,您可以2 -从中分解3 2 -以创建减法函数。在前缀表示法中,您可以从中分解- 3- 3 2创建一个subtractFromThree 函数,这似乎没有那么有用。

除非有任何明显的问题,否则使用前缀表示法的连接语言可能会赢得不喜欢后缀表示法的人的青睐。任何见解都值得赞赏。

4

4 回答 4

5

当然,如果你的话仍然是固定的,那么这只是从右到左执行标记的问题。

只是因为 n-arity 函数,前缀表示法意味着括号,并且只是因为希望人类“阅读顺序”与执行顺序相匹配,作为堆栈语言意味着后缀。

于 2012-09-03T16:27:21.777 回答
3

我现在正在编写这样一种语言,到目前为止,我喜欢使用前缀表示法的一些副作用。语义基于 Joy:

  • 文件从左到右解析,但从右到左执行。
  • 通过扩展,定义必须在使用它们的点之后。
  • 作为一个很好的副作用,注释只是被删除的列表。

这是阶乘函数,例如:

def 'fact [cond [* fact - 1 dup] [1 drop] dup]

我还发现在编写代码时更容易推理代码,但我在级联语言方面没有很强的背景。这是我对列表的 map 函数的(可能是天真的)推导。'nb' 函数会删除一些东西并用于注释。'stash [f]' 弹出一个临时文件,在堆栈的其余部分运行'f',然后将临时文件推回。

def 'map [q [cons map stash [head swap i] dup stash [tail dup]] [nb] is_cons nip]
nb [map [f] (cons x y) -> cons map [f] x f y
    stash [tail dup]    [f] (cons x y)       = [f] y (cons x y)
    dup                 [f] y (cons x y)     = [f] [f] y (cons x y)
    stash [head swap i] [f] [f] y (cons x y) = [f] x (f y)
    cons map            [f] x (f y)          = cons map [f] x f y

    map [f] [] -> []]
于 2012-05-22T10:56:43.830 回答
3

我刚读完关于Om 语言的文章

似乎正是你在说什么。从它的描述(强调我的):

Om 语言是:

  • 一种新颖的、最简单的连接、同音编程和算法符号语言,具有:
    • 最小的语法,仅包含三个元素。
    • 前缀表示法,其中函数操作程序本身的其余部分。[...]

它还表示它还没有完成,并且将经历很大的变化。

尽管如此,它似乎仍然有效,并且作为概念证明非常有趣。

于 2015-05-21T04:15:12.973 回答
1

我想象一种没有堆栈的连接前缀语言。它可以调用函数,然后它们自己会解释代码,直到获得所有需要的操作数。然后解释器将调用下一个函数。它只需要一个内存结构——结果。其他所有内容都可以在执行时从源代码中读取。您可能已经注意到,我说的是解释语言,而不是编译语言。

于 2012-03-08T19:41:52.693 回答