Lisp是REPL的唯一语言吗?

如何解决Lisp是REPL的唯一语言吗?

| 除了Lisp(红宝石,斯卡拉)以外,还有其他语言说它们使用REPL(读,评估,打印,循环),但是目前还不清楚REPL的含义是否与Lisp相同。 Lisp REPL与非Lisp REPL有何不同?     

解决方法

REPL的想法来自Lisp社区。还有其他形式的文本交互界面,例如命令行界面。一些文本界面还允许执行某种编程语言的子集。 REPL代表READ EVAL PRINT LOOP :(循环(打印(评估(读取)))))。 上面四个函数中的每一个都是原始的Lisp函数。 在Lisp中,REPL不是命令行解释器(CLI)。
READ
不读取命令,REPL不执行命令。 “ 0”以s表达式格式读取输入数据并将其转换为内部数据。因此,“ 0”函数可以读取所有类型的s表达式-而不仅仅是Lisp代码。 READ读取一个S表达式。这是一种数据格式,也支持编码源代码。 READ返回Lisp数据。 EVAL以Lisp数据的形式获取Lisp源代码并对其进行评估。可能会发生副作用,并且EVAL返回一个或多个值。没有定义如何使用解释器或编译器实现EVAL。实现使用不同的策略。 PRINT获取Lisp数据并将其作为s表达式打印到输出流。 LOOP只是在此循环。在现实生活中,REPL更为复杂,并且包括错误处理和子循环,即所谓的中断循环。在发生错误的情况下,如果发生错误,则仅获取具有附加调试命令的另一个REPL。一次迭代中产生的值也可以重新用作下一次评估的输入。 由于Lisp都使用数据编码和功能元素,因此与其他编程语言略有不同。 相似的语言也将提供相似的交互界面。例如,Smalltalk还允许交互式执行,但它不像Lisp那样对I / O使用数据格式。对于任何Ruby / Python / ...交互式界面都相同。 题: 那么,阅读,评估和打印其价值的原始思想有多重要?与其他语言相比,这是否重要:读取文本,解析文本,执行文本,选择打印某些内容以及选择打印返回值?通常,返回值并未真正使用。 因此,有两个可能的答案: Lisp REPL与大多数其他文本交互界面不同,因为它基于s表达式的数据I / O并对其进行评估。 REPL是一个通用术语,描述了与编程语言实现或其子集相关的文本交互界面。 Lisp中的REPL 在实际的实现中,Lisp REPL具有复杂的实现并提供许多服务,直到输入和输出对象的可单击的表示形式(符号,CLIM,SLIME)。例如,高级REPL实现可在SLIME(Common Lisp的一种流行的基于Emacs的IDE),McLIM,LispWorks和Allegro CL中获得。 Lisp REPL交互的示例: 产品和价格清单:
CL-USER 1 > (setf *products* \'((shoe (100 euro))
                               (shirt (20 euro))
                               (cap (10 euro))))
((SHOE (100 EURO)) (SHIRT (20 EURO)) (CAP (10 EURO)))
订单,产品清单和金额:
CL-USER 2 > \'((3 shoe) (4 cap))
((3 SHOE) (4 CAP))
订单价格
*
是包含最后一个REPL值的变量。它不包含此值作为字符串,而是实际的实际数据。
CL-USER 3 > (loop for (n product) in *
                  sum (* n (first (second (find product *products*
                                                :key \'first)))))
340
但是您也可以计算Lisp代码: 让我们来看一个函数,将两个参数的平方相加:
CL-USER 4 > \'(defun foo (a b) (+ (* a a) (* b b))) 
(DEFUN FOO (A B) (+ (* A A) (* B B)))
第四个元素只是算术表达式。
*
是最后一个值:
CL-USER 5 > (fourth *)
(+ (* A A) (* B B))
现在我们在其周围添加一些代码,以将变量
a
b
绑定到一些数字。我们正在使用Lisp函数ѭ12create创建一个新列表。
CL-USER 6 > (list \'let \'((a 12) (b 10)) *)
(LET ((A 12) (B 10)) (+ (* A A) (* B B)))
然后,我们评估以上表达式。同样,
*
是最后一个值。
CL-USER 7 > (eval *)
244
每次ѭ16互动时,都会更新几个变量。先前的值示例为
*
**
***
。前一个输入也有
+
。这些变量的值不是字符串,而是数据对象。
+
将包含REPL读操作的最后结果。例: 变量
*print-length*
的值是多少?
CL-USER 8 > *print-length*
NIL
让我们看看如何读取和打印列表:
CL-USER 9 > \'(1 2 3 4 5)
(1 2 3 4 5)
现在,将上面的符号
*print-length*
设置为3。
++
指的是第二个先前输入的读取数据。
SET
设置符号值。
CL-USER 10 > (set ++ 3)
3
然后上面的列表以不同的方式打印。
**
表示第二个先前的结果-数据,而不是文本。
CL-USER 11 > **
(1 2 3 ...)
    ,看到REPL的概念只是阅读,评估,打印和循环,就不必太惊讶许多语言都有REPL: C / C ++ C#/ LINQ Erlang Haskell(在Windows上) 爪哇 Java脚本 佩尔 蟒蛇 红宝石 斯卡拉 Smalltalk-我是在REPL上学到的! 编辑我忘记了Java!     ,我认为比较两种方法很有趣。 Lisp系统中的裸露REPL循环如下所示:
(loop (print (eval (read))))
这是REPL循环的两个实际的Forth实现。我在这里什么都没留下-这是这些循环的完整代码。
: DO-QUIT   ( -- )  ( R:  i*x -- )
    EMPTYR
    0 >IN CELL+ !   \\ set SOURCE-ID to 0
    POSTPONE [
    BEGIN           \\ The loop starts here
        REFILL      \\ READ from standard input
    WHILE
        INTERPRET   \\ EVALUATE  what was read
        STATE @ 0= IF .\"  OK\" THEN  \\ PRINT
        CR
    REPEAT
;

: quit
  sp0 @ \'tib !
  blk off
  [compile] [
  begin
    rp0 @ rp!
    status
    query           \\ READ
    run             \\ EVALUATE
    state @ not
    if .\" ok\" then  \\ PRINT
  again             \\ LOOP
;
Lisp和Forth做的事情完全不同,特别是在EVAL部分,但在PRINT部分。但是,他们共享一个事实,两种语言的程序都是通过将其源代码提供给各自的循环来运行的,并且在两种情况下,代码都只是数据(尽管在Forth情况下,它更像是数据也在代码中)。 我怀疑有人说只有LISP具有REPL的原因是READ循环读取了由EVAL解析的DATA,并且由于CODE也是DATA而创建了一个程序。关于Lisp和其他语言之间的区别,这种区别在很多方面都很有趣,但是就REPL而言,这一点都没有关系。 让我们从外部考虑一下: READ-从stdin返回输入 EVAL-将所述输入作为语言中的表达式进行处理 打印-打印EVAL \的结果 循环-返回读取 如果不讨论实现细节,就无法将Lisp REPL与Ruby REPL区分开。作为功​​能,它们是相同的。     ,我猜您可能会说Scala的\“ REPL \\”是\\“ RCRPL \”:读取,编译,运行,打印。但是由于编译器会在内存中保持“高温”状态,因此对于进行中的交互来说非常快-只需几秒钟即可启动。     ,许多人认为REPL的行为必须与LISP中的行为完全一样,或者它不是真正的REPL。相反,他们认为它有些不同,例如CLI(命令行解释器)。老实说,我倾向于认为它遵循以下基本流程: 读取用户的输入 评估输入 打印输出 循环回到读取 那就是REPL。如前所述,许多语言都具有上述功能。 有关此类讨论的示例,请参见此reddit线程。     ,有一个名为ѭ33的不错的项目,它通过Node.JS公开了各种REPL: https://github.com/evilhackerdude/multi-repl 如果您查看受支持的语言列表,则很显然,不仅Lisp具有REPL的概念。 clj(clojure) ghci(ghc) ipython的 irb(红宝石) js(spidermonkey) 节点 蟒蛇 sbcl v8 实际上,在Ruby中实现琐碎的事情相当容易:
repl = -> prompt { print prompt; puts(\" => %s\" % eval(gets.chomp!)) }
loop { repl[\">> \"] }
    ,  Lisp REPL与非Lisp REPL有何不同? 让我们将Common Lisp的REPL与Python的IPython进行比较。 主要两点是: Lisp是一种基于图像的语言。更改后,无需重新启动进程/ REPL /整个应用程序。我们按函数编译代码函数(带有编译器警告等)。 我们不放松状态。更重要的是,当我们更新类定义时,REPL中的对象也会按照我们控制的规则进行更新。这样,我们可以在正在运行的系统中热重载代码。 通常,在Python中,您启动IPython或放入ipdb。您定义一些数据,直到尝试新功能。您编辑了源代码,然后想再试一次,因此退出IPython,然后重新开始整个过程​​。在Lisp(主要是Common Lisp)中,根本没有互动性。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-