这种声明式I / O方法有什么问题

时间:2010-06-04 00:05:17

标签: functional-programming side-effects logic-programming declarative-programming

我不确定这与“程序语言设计”相反的“编程”究竟有多少。但问题是:

说,为了简单起见,我们有两个'特殊'列表/数组/向量/为简单起见我们只称为'端口',一个叫stdIn,另一个叫stdOut。这些概念上分别代表

  • 在程序持续时间内为程序提供的所有用户输入
  • 在程序期间写入终端的所有输出

在Haskell启发的伪代码中,应该可以创建这个完全声明的程序:

 let stdOut =   ["please input a number", 
                "and please input another number", 
                "The product of both numbers is: " ++ stdIn[0] * stdIn[1]]

哪个会做到预期,要求两个数字,并打印他们的产品。诀窍是stdOut表示在程序完成时写入终端的字符串列表,stdIn是输入字符串列表。键入错误以及为了简单起见,在输入新行之后只需打印下一行就需要一些安全措施,这可能很容易解决。

所以,在我实施这个想法之前,我忽略了任何陷阱吗?我不知道已经存在类似的结构,所以如果没有考虑到我忽略了一个明显的陷阱,那就太天真了。

否则,我当然知道:

 let stdOut =   [stdIn[50],"Hello, World!"]

如果这些结果需要以与上述类似的方式交织,那将是一个错误。

4 个答案:

答案 0 :(得分:6)

在Haskell的早期版本中使用了类似的方法,除了stdin和stdout通道的元素不是字符串而是通用IO'动作' - 实际上,输入和输出被推广为'响应'和'请求”。只要两个通道都是惰性的(即它们实际上是“迭代器”或“枚举器”),运行时就可以简单地遍历请求通道,对每个请求起作用并将适当的响应添加到响应通道上。不幸的是,该系统非常难以使用,因此它被废弃以支持monadic IO。见这些文件:

  • Hudak,P。和Sundaresh,R。关于纯功能I / O系统的表现力。技术。代表YALEU / DCS / RR-665,耶鲁大学计算机科学系,1989年3月。
  • Peyton Jones,S。解决尴尬小队:Haskell中的monadic输入/输出,并发,异常和外语调用。在工程理论的软件建设,2002年,第47-96页。

答案 1 :(得分:5)

您描述的方法听起来像“对话”。在他们屡获殊荣的1993年论文命令功能编程中,Phil Wadler和Simon Peyton Jones举了一些例子,其中对话框确实不能很好地工作,并且它们解释了为什么monadic I / O更好。

答案 2 :(得分:1)

与你自己的例子相比,我不知道你将如何编织他们:

let stdOut =   ["Welcome to the program which multiplies.",
                "please input a number", 
                "and please input another number", 
                "The product of both numbers is: " ++ stdIn[0] * stdIn[1]]

在输出一行(如您的示例中)或两行后,程序是否应提示stdIn[0]所代表的数字?如果索引0表示来自stdin的第0个输入,那么它看起来类似于:

let stdOut =   ["Welcome to the program which multiplies.",
                "please input a number",
                some_annotation(stdIn[0]),
                "and please input another number", 
                some_annotation(stdIn[1]),
                "The product of both numbers is: " ++ stdIn[0] * stdIn[1]]
为了协调输出和输入的时间,将需要

我喜欢你的主意。将some_annotation替换为您的偏好,或许类似于“同步?”我无法想出这个尖锐的词语。

答案 3 :(得分:1)

这种方法似乎是将I / O添加到纯粹的微积分中的“最明显的”方式,而其他人已经提到在Haskell和Miranda中尝试了这些方法。

但是,我知道一种语言,不是基于λ演算,仍使用非常相似的系统:

  

如何处理输入和输出   语言没有副作用?在一个   某种意义上,输入和输出不是   副作用;他们是,可以这么说   前后效应。 (...)[节目是]   来自太空的功能   对空间的可能输入   可能的产出。

     

输入和输出流是   表示为自然列表   数字从0到255,每个   对应一个字节。档案结尾   由值256表示,而不是   列表末尾。 (这是因为它是   通常更容易处理EOF   性格比特殊情况。   不过,我想知道是不是   最好使用列表末尾。)

(...)

  

写起来并不难   互动节目(......)[但]正在做   从技术上讲,这也是一种罪恶。   (...)在引用透明   语言,任何不明确的   同步是公平的游戏   任何顺序的评估,在   运行时系统的自由裁量权。

     

(...)最明显的写作方式   这个特别的计划是缺点   一起“你好,[名字]!”串   在一个被调节的表达中   收到换行符。如果你这样做   这是安全的,因为没有   任何评估者证明的方式   提前用户输入一个   换行符。

(...)

  

所以没有实际问题   互动软件。尽管如此,   有一些不愉快的事情   第二种情况被阻止的方式。一个   引用透明的程序   不应该依赖懒惰   评估才能正常运作。

     

如何摆脱这种道德困境?该   艰难的方法是切换到更多   也许是复杂的I / O系统   基于Haskell的,其中输入和   输出显式同步。   我不愿意这样做,因为   我更喜欢简单的   现行制度。简单的方法是   编写碰巧的批处理程序   交互式地工作。这是   主要只是一个没有提示的问题   用户。

也许你会喜欢在Lazy K做一些编程?