我最近受到了Haskell博客活动1的启发,试图在Haskell中编写类似Forth的DSL.我采取的方法既简单又令人困惑:
{-# LANGUAGE TypeOperators, RankNTypes, ImpredicativeTypes #-}
-- a :~> b represents a "stack transformation"
-- from stack type "a" to stack type "b"
-- a :> b represents a "stack" where the top element is of type "b"
-- and the "rest" of the stack has type "a"
type s :~> s' = forall r. s -> (s' -> r) -> r
data a :> b = a :> b deriving Show
infixl 4 :>
Run Code Online (Sandbox Code Playgroud)
对于做简单的事情,这非常有效:
start …Run Code Online (Sandbox Code Playgroud) polymorphism haskell concatenative-language higher-order-functions impredicativetypes
我读过(来自Slava Pestov)因为Lisp影响了因子,但我不确定我能理解怎么样?他们的编程语言不是很不一样吗?
因子手册的这一页讨论了存储在continuation中的这些类型的堆栈:
这些堆栈究竟拥有什么?对我来说最令人困惑的三个是callstack,retainstack和namestack.
我正在学习连接语言的基础知识,其最初的想法是函数名称连接与函数组合相同,而不是像Haskell中那样是函数应用程序.
Joy,Forth或Factor是postfix,这意味着基于堆栈,但也有一些前缀连接语言,如Om.
我想知道Haskell变体理论上是否可以通过将组合优先级(现在为9)与函数应用程序优先级(现在为10)进行交换(甚至等于)来进行连接语言.
如果Haskell中的值只是零参数函数,为什么函数应用程序与函数组合不同?,函数应用程序与零参数函数组合相同吗?
是否有可能以简单的方式创建一个解释器或预编译器,它通过定义具有不同优先级的新组合和应用程序运算符将连接语法转换为Haskell语法,并假设没有括号的简单连接是组合?我认为这只是一个语法问题,我错了吗?它会避免许多我们必须在Haskell中使用括号或$运算符的情况.或者它是一个更基本的问题,而不仅仅是语法和优先级?
提示:假设Haskell中的每个函数和运算符都是前缀,我们可以忘记这个关于中缀符号和各种"语法糖"的练习.
haskell operator-precedence concatenative-language polish-notation
连接语言具有一些非常有趣的特性,例如能够组合不同元数的函数以及能够分解出函数的任何部分。然而,许多人因为它们使用后缀表示法并且难以阅读而忽略它们。另外,波兰人可能不欣赏人们反向使用他们精心制作的符号。
那么,是否有可能有前缀符号?如果是这样,权衡是什么?
我知道它是如何工作的,但我没有使用连接语言的经验,所以我可能遗漏了一些东西。基本上,一个函数会以相反的顺序进行评估,而值会以相反的顺序从堆栈中取出。为了证明这一点,我将后缀与前缀的外观进行比较。以下是一些使用传统后缀表示法的连接表达式。
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
Run Code Online (Sandbox Code Playgroud)
表达式从左到右计算:在第一个示例中,5被压入堆栈,然后dup复制堆栈顶部的值,然后将堆栈*顶部的两个值相乘。函数首先从堆栈中取出最后一个参数:在第二个示例中,当-被调用时,2位于堆栈顶部,但它是最后一个参数。
这是我认为前缀符号的样子:
* dup 5
- 3 2
length filter (1, 2, 3, 4, 5) [< 2]
Run Code Online (Sandbox Code Playgroud)
表达式从右到左计算,函数首先从堆栈中取出它们的第一个参数。请注意前缀过滤器示例如何与其描述更接近,并且看起来与应用样式相似。我注意到的一个问题是,将事情分解出来可能没有那么有用。例如,在后缀表示法中,您可以从中提取2 -出来3 2 -创建一个减法函数。在前缀表示法中,您可以从中提取 …
programming-languages postfix-notation concatenative-language factor-lang
Forth有一个堆栈和一个返回堆栈.
据我所知,返回堆栈的重点是存储程序计数器的先前值.
C程序将程序计数器的先前值放在堆栈上,并且不使用返回堆栈.
Forth只需要一个返回堆栈,因为它会在堆栈上返回结果,因此程序计数器的先前值可能会被掩埋吗?