天天看点

REPL概述优势实现

概述

REPL(read-eval-print-loop)是一个简单,交互式的计算机编程环境。这个术语经常在Lisp交互式环境中被引用,但是它可以被应用到命令行界面(command line shell),或者在类似的编程环境中,其同义词是交互式编程环境(interactive toplevel)和Language Shell,如下语言都具备这样的环境(APL, BASIC, F#, Haskell, J , Perl, PHP, Python, Ruby, Prolog, Scala, Smalltalk, Tcl, Standard ML).

REPL适用于探索性的编程和调试,因为它通常比传统的edit-compile-run loop快。在REPL中,程序员输入一个或多个表达式(不是一个编译单元),然后代码被解析并打印结果。REPL这一术语来自于Lisp中实现这一功能的函数。

        read函数接受一个用户输入的表达式,在内存中将其解析为一个数据结构。例如,当用户输入s-expression (+ 1 2 3),它被解析成一个拥有四个元素的链表

        eval函数输入上述内部数据结构并分析它。在lisp中,分析到一个s-expression以函数名开始意味着调用该函数,并且以该表达式剩余部分作为参数;因此上述表达式意味着以 1 2 3作为参数调用函数+,最后得到的结果为6

        print函数获取eval函数的输出作为输入,并将其打印出来。如果结果为一个复杂的表达式,为了便于理解,可能需要做一些转换。这个例子中,结果比较简单,不需要转换。

优势

REPL可以作为学习一门新语言的非常重要的一个工具,因为它可以对用户的输入做出快速反馈。很多软件套件和编程语言都适用REPL提供算法学习和调试,例如MATLAB, ROOT, Scipy和Ipython。Python的doctest模块可以非常容易的捕获REPL命令行的输出结果并用于测试。

由于print函数输出的数据格式和read函数输入的数据格式相同,大部分结果可以被重新输入到REPL中。然而,有时也需要打印不能重新输入到REPL中的数据格式,如socket句柄和复杂的对象实例。在这些情况下,需要一种用于不可读对象的语法。在Python中,相应的用法为<__module__.class instance>,在common lisp中,格式为#<whatever>.

实现

实现一个Lisp REPL,需要实现三个函数和一个无限循环(一般情况下,eval的实现会比较复杂,由于它必须实现所有基本函数(如car和+)和特殊操作(如if))。eval的一种可能实现方式是实现一个作用于read产生的语法树上的递归解释器,另一种实现方式是将语法树编译成机器码并运行。

Lisp实际的REPL实现非常复杂,它包括以下典型功能:

1. 输入输出的历史信息

2. 设置变量,这些变量可以在输入表达式和输出结果中使用,这些变量可以在REPL中使用,如在Common Lisp中,* 代表上一个输出结果

3.REPL级别,在许多Lisp系统中,read,evaluation或者print阶段的任何一个阶段出错,系统并不会将错误消息抛出到顶层。

4.错误处理

上一篇: REPL

继续阅读