【问题标题】:Running LISP code via CLISP on Linux (Ubuntu WSL)在 Linux (Ubuntu WSL) 上通过 CLISP 运行 LISP 代码
【发布时间】:2021-05-15 22:15:14
【问题描述】:

我是 LISP 新手,想知道如何在 Ubuntu Linux 上正确运行一个简单的 lisp 程序。目前,我有一个名为“intmax.lisp”的 LISP 文件,其中包含以下代码:

(defun intmax (x y) (if (> x y) x y))

但是,当我转到命令行并运行时:

clisp intmax 2 4

为了比较 2 和 4,我没有得到任何输出。关于我做错了什么有什么建议吗?

【问题讨论】:

标签: linux lisp common-lisp windows-subsystem-for-linux clisp


【解决方案1】:

要开始使用,请使用 REPL。这不是 shell 命令行,而是类似于 Lisp 内部的命令行。

启动 Lisp 系统:

clisp

您会收到如下提示:

[1]>

加载您的文件:

[1]> (load "intmax.lisp")

现在你可以调用你的函数了:

[2]> (intmax 2 4)

它会打印出来:

4

再次提示:

[3]>

您可能想稍后了解包和系统,以便组织您的代码。

如果你想从命令行调用东西,你需要告诉 clisp 加载需要的东西,然后执行一个 lisp 命令。查看手册页。示例:

clisp -q -i intmax.lisp -x '(intmax 2 4)'

【讨论】:

    【解决方案2】:

    clisp 可执行文件不会将其参数转换为函数调用。但是,您可以制作执行此操作的 CLISP 程序。我为 Lisp 应用程序的许可后端做了这样的事情。我想要一种简单的管理命令语言来从系统提示符中查找用户并授予他们许可证和类似的东西。所以我只写了一个 shim,它将单个命令行参数转换为 Lisp 对象,并收集到一个 List 中,并将其作为或多或少的函数进行调度。

    让我们通过在一个名为clisp-dispatch.lisp的文件中制作这个程序来热身:

    #!/usr/bin/env clisp
      
    (print *args*)
    

    当我们像这样运行它时,我们看到*args* 提供了对参数的访问:

    $ chmod a+x clisp-dispatch.lisp # give it exec permission
    $ ./clisp-dispatch.lisp
    
    NIL
    $ ./clisp-dispatch.lisp a b c 1 2 3
    ("a" "b" "c" "1" "2" "3") 
    

    非常好。现在我们希望看到的是列表(A B C 1 2 3):符号和数字的列表,而不是字符串的列表。让我们稍微修改一下代码:

    #!/usr/bin/env clisp
      
    (print (mapcar #'read-from-string *args*))
    

    read-from-string 函数使用 Lisp 阅读器扫描字符串,返回其语法所暗示的 Lisp 对象。如果语法看起来像一个符号,则返回一个符号;如果是数字,则返回一个数字,依此类推。例如(read-from-string "(1 2 3")) 产生列表(1 2 3)。这样,我们得到:

    $ ./clisp-dispatch.lisp a b c 1 2 3
    
    (A B C 1 2 3) 
    

    非常好!所以剩下的就是将此列表视为 Lisp 代码,为此我们只需将其传递给 eval 函数。让我们保留print,但将其用于eval 的结果:

    #!/usr/bin/env clisp
    
    (print (eval (mapcar #'read-from-string *args*)))
    

    现在我们可以这样做了:

    $ ./clisp-dispatch.lisp + 2 2
    
    4 
    $ ./clisp-dispatch.lisp list 1 2 3
    
    (1 2 3) 
    $ ./clisp-dispatch.lisp cons "'a" 3
    
    (A . 3) 
    

    因此,如果我们定义一个intmax 函数,我们可以从系统提示符处调用它。

    #!/usr/bin/env clisp
    
    (defun intmax (a b)
      (max a b))
    
    (print (eval (mapcar #'read-from-string *args*)))
    
    $ ./clisp-dispatch.lisp intmax 3 1
    
    3 
    $ ./clisp-dispatch.lisp intmax 7 10
    
    10 
    

    不过,您最好从 Lisp 中探索 Lisp,而不是像这样从命令行间接调用它。一方面,每次我们运行这个程序时,都会启动一个新的 Lisp 映像。我们无法与环境互动。我们还必须对某些语法使用非常笨拙的引用,例如我使用 "'a"'a 传递给 Lisp 的方式。

    我们所做的是以一种在clisp 可执行文件中不直接支持的非常特殊的方式使用 Lisp:像 Lisp 对象一样解析参数,然后将结果视为函数调用。无论如何,任何想像他一样“滥用” Lisp 的人都可以编写上面的小程序。

    还要注意我是如何定义intmax 的,只需调用max。重点是Common Lisp中不需要定义intmax;内置的max 函数接受一个或多个参数并返回最大值:(max 1 3 2) 产生3。因为(int-max x y) 只是(max x y),所以int-max 没有理由存在。它只是 max 的一个受损同义词,它需要多输入四个字符,并且不需要超过两个参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-07-19
      • 1970-01-01
      • 2022-11-05
      • 2011-04-24
      • 2012-08-22
      • 1970-01-01
      • 2015-08-19
      相关资源
      最近更新 更多