什么是交互式回复IO功能?

什么是交互式回复IO功能?,io,common-lisp,read-eval-print-loop,Io,Common Lisp,Read Eval Print Loop,我学习CommonLisp已经有一段时间了,我遇到了一个问题 我如何实现这样一个功能,允许用户输入一些单词,直到用户输入退出。 (实际上我想知道什么样的命令行交互函数API适合这样的需求) e、 g。 提示“请输入一个单词:”在REPL中,然后将用户输入存储到全局“我的单词”中,当用户输入“退出”时退出。您的规范有点不完整(例如,您的问题中的单词由什么组成?如果用户添加多个单词怎么办?如果输入为空怎么办?)。下面我用它将输入拆分成不同的单词,并一次将它们全部添加,因为它在一般情况下似乎很有用。在

我学习CommonLisp已经有一段时间了,我遇到了一个问题 我如何实现这样一个功能,允许用户输入一些单词,直到用户输入退出。 (实际上我想知道什么样的命令行交互函数API适合这样的需求)

e、 g。
提示“请输入一个单词:”在REPL中,然后将用户输入存储到全局“我的单词”中,当用户输入“退出”时退出。

您的规范有点不完整(例如,您的问题中的单词由什么组成?如果用户添加多个单词怎么办?如果输入为空怎么办?)。下面我用它将输入拆分成不同的单词,并一次将它们全部添加,因为它在一般情况下似乎很有用。在您的情况下,您可能需要添加更多的错误检查

如果您想与用户交互,您应该在流中读写。在这里,我将根据您的要求提供一个带有全局变量的版本,以及另一个没有副作用的版本(除了输入/输出)

使用全局变量 定义全局变量并用空的可调数组初始化它。 我使用的是一个数组,这样很容易在末尾添加单词,但也可以使用队列

(defvar*my words*(生成数组10:填充指针0:可调t))
以下函数将对全局变量进行变异:

(defun副作用词repl()
(环路
(格式*查询io*“~&请输入一个单词:)
(完成输出*查询io*)
(让)字(ppcre:split
“(:1 nil:whitespace char类)
(读取行*查询io*))
(单字)
(当(字符串等于w“exit”);忽略大小写
(从副作用词repl返回)
(矢量推送扩展w*我的话*);“”)
  • 使用简单语法,其中只有表达式,没有特定于循环的关键字。我首先将提示写入
    *QUERY-IO*
    ~&
    指令执行与相同的操作。正如雷纳在评论中指出的那样,我们必须在用户回复之前打电话确保信息得到有效打印

  • 然后,我从同一个双向流中读取一整行,并将其拆分为一个单词列表,其中一个单词是一个非空白字符字符串

  • 使用,我迭代列表,并使用将单词添加到全局数组中。但一旦我遇到
    “exit”
    ,我就终止了循环;因为我依赖于,所以测试是不敏感地进行的

无副作用方法 不鼓励使用如上所述的全局变量。如果您只需要一个返回单词列表的提示,那么下面的内容就足够了。在这里,我使用/idiom来构建生成的单词列表

(定义纯词repl()
(让((结果“()))
(环路
(格式*查询io*“~&请输入一个单词:)
(完成输出*查询io*)
(让)字(ppcre:split
“(:1 nil:whitespace char类)
(读取行*查询io*))
(单字)
(当(字符串等于w“退出”)
(从纯单词repl(nreverse结果)返回)
(推送w结果(()())))
关于单词的注释 正如jkiiski所评论的,最好在
:单词边界处拆分单词。我尝试了不同的组合,下面的结果似乎满足于奇怪的示例字符串:

(mapcan(lambda(字符串)
(ppcre:拆分:字边界字符串))
(ppcre:split
“(:1 nil:whitespace char类)
“amzldk'amlzkd;:azdl-azdlk”))
=>(“amzldk”“amlzkd”“d”“;:“azdl”“azdlk”)

我首先删除所有空格,并将字符串拆分为一个字符串列表,其中可以包含标点符号。然后,每个字符串本身在
:单词边界处拆分,并与连接以形成一个单独单词的列表。但是,我无法真正猜测您的实际需要是什么,因此您可能应该定义自己的
拆分为单词
函数来验证和拆分输入字符串。

您的规范有点不完整(例如,问题中的单词是什么?如果用户添加多个单词怎么办?如果输入为空怎么办?)。下面我用它将输入拆分成不同的单词,并一次将它们全部添加,因为它在一般情况下似乎很有用。在您的情况下,您可能需要添加更多的错误检查

CL-USER 23 > (progn
               (format t "~%enter a list of words:~%")
               (finish-output)
               (setf my-words (read))
               (terpri))

enter a list of words:
(foo bar baz)
如果您想与用户交互,您应该在流中读写。在这里,我将根据您的要求提供一个带有全局变量的版本,以及另一个没有副作用的版本(除了输入/输出)

使用全局变量 定义全局变量并用空的可调数组初始化它。 我使用的是一个数组,这样很容易在末尾添加单词,但也可以使用队列

(defvar*my words*(生成数组10:填充指针0:可调t))
以下函数将对全局变量进行变异:

(defun副作用词repl()
(环路
(格式*查询io*“~&请输入一个单词:)
(完成输出*查询io*)
(让)字(ppcre:split
“(:1 nil:whitespace char类)
(读取行*查询io*))
(单字)
(当(字符串等于w“exit”);忽略大小写
(从副作用词repl返回)
(矢量推送扩展w*我的话*);“”)
  • 使用简单语法,其中只有表达式,没有特定于循环的关键字。我首先将提示写入
    *QUERY-IO*
    ~&
    指令执行与相同的操作。正如雷纳在评论中指出的那样,我们必须在用户回复之前打电话确保信息得到有效打印

  • 然后,我读了一整行文章
    CL-USER 28 > (loop with word = nil
    
                       do
                       (format t "~%enter a word or exit:~%")
                       (finish-output)
    
                       (setf word (read))
                       (terpri)
    
                       until (eql word 'exit)
    
                       collect word)
    
    enter a word or exit:
    foo
    
    
    enter a word or exit:
    bar
    
    
    enter a word or exit:
    baz
    
    
    enter a word or exit:
    exit
    
    (FOO BAR BAZ)