Portacle
是一个完整的通用语言集成开发环境, 你可以用U
盘携带.
它是多平台的, 可以在 Windows
, OS X
和Linux
上运行. 由于它不需要任何复杂的安装过程, 它可以在短时间内完成设置并运行.
它很适合Lisp
的需要好起点的初学者, 也适合想尽量减少准备一切的时间的高级用户.
以下是Portacle
中包含的软件包.
Emacs
; Emacs是一个非常灵活和可扩展的编辑器, 已经存在了很长时间. 由于它的历史和巨大的社区, 它能够覆盖几乎所有的编程领域, 甚至更多. 与Emacs捆绑在一起的是一些非常有用的软件包, 其中主要的是Slime
,Magit
和Company
.SBCL
; SBCL是当今最快和最有能力的Lisp实现之一. Steel Bank Common LispQuicklisp
;Quicklisp
是标准的Lisp
软件包管理器, 它允许你通过寥寥数键来检索和管理一千多个库.Git
;Git
可能是当今使用最广泛的版本控制系统. 它允许你快速有效地管理各种大小项目中的代码变化.
根据平台下载安装之后, 打开运行.
窗口应该被划分为两个区域, 每个区域都显示一个叫做缓冲区
(buffer)的东西.
显示CL-USER>
的那个, 是Lisp
命令行. 另一个是scratch
(草稿)缓冲区, 应该包含一些关于如何查看参考指南的提示.
作为测试, 在Lisp
命令行缓冲区内点击, 并输入以下代码.
(progn (format T "Hey, what's your name?~%")
(format T "Hello, ~a" (read-line)))
你会注意到它会自动为你插入结尾的圆括号和引号. 要运行它, 通过点击或方向键将光标移到末尾, 然后按下回车键.
祝贺你 你刚刚在Portacle
中运行了你的第一个程序.
你可能还应该配置一下Portacle
的默认设置. 按下Alt+X
(Mac上为⌘+X
), 然后输入portacle-configure
, 按下回车.
然后会在窗口的底部看到提示, 在一个叫做 minibuffer
的区域.
回答所有的问题, Portacle
应该就设置好了.
请确保阅读帮助文件. 它应该解释所有关于如何使用编辑器的基本术语和命令. 要访问它, 请按Ctrl+H H
.
在Linux
和OS X
上, 我们将使用SBCL
作为通用语言的实现.
要在Ubuntu/Debian
上安装SBCL
, 只需运行.
sudo apt-get install sbcl
Arch Linux
由于SBCL
可以从官方软件库中获得, 你可以用以下方式安装它.
sudo pacman -S sbcl
OS X
要在OS X
上安装SBCL
, 只需进行以下操作.
brew install sbcl
接下来, 我们设置Quicklisp
, 即软件包管理器, 同样很简单.
curl -o /tmp/ql.lisp http://beta.quicklisp.org/quicklisp.lisp
sbcl --no-sysinit --no-userinit --load /tmp/ql.lisp \
--eval '(quicklisp-quickstart:install :path "~/.quicklisp")' \
--eval '(ql:add-to-init-file)' \
--quit
这将把 Quicklisp
安装到 ~/.quicklisp/
目录中.
SLIME: The Superior Lisp Interaction Mode for Emacs
SLIME
是一个用于Common Lisp
开发的Emacs mode
, 即建立在 Emacs
上的Common Lisp
IDE(集成开发环境).
受现有系统的启发, 如Emacs Lisp
和ILISP
, 我们正在努力创造一个环境, 以便在其中集成Common Lisp
.
slime-mode
; 一个Emacs
的minor
模式, 用来增强lisp-mode
的功能.- 代码运行, 编译和宏展开.
- 在线文档(
describe
,apropos
,hyperspec
). - 定义查找(又名
Meta-Point
, 或M-
). - 符号和包名补全.
- 自动宏缩进, 基于
&body
. - 交叉引用界面(
WHO-CALLS
, 等等).
SLDB
: Common Lisp debugger , 具有基于Emacs
的用户接口.REPL
:Read-Eval-Print Loop
(top-leve)是用Emacs Lisp
写的, 以便与Emacs
更紧密地结合.REPL
也有类似McCLIM
监听器的内置快捷键
命令.Compilation notes
.SLIME
能够接受编译器信息, 并将其直接注释到源代码缓冲区.Inspector
.Emacs
缓冲区中的交互式对象检查器.
你可以用Quicklisp
来安装它.
sbcl --eval '(ql:quickload :quicklisp-slime-helper)' --quit
# 删除请使用:
sbcl --eval '(ql:uninstall :quicklisp-slime-helper)' --quit
然后, 在你的 ~/.emacs.d/init.el
中添加这个内容.
(load (expand-file-name "~/.quicklisp/slime-helper.el"))
(setq inferior-lisp-program "sbcl")
Emacs编辑器 安装:
sudo apt-get install emacs
-nw, --no-window-system
; 告诉Emacs不要创建一个图形框架. 如果你在从xterm(1)
窗口调用Emacs
时使用这个开关, 那么将显示命令行界面.
emacs 自带的简单入门教程 emacs 自带的简单入门教程 一年成为Emacs高手
常用快捷键: C
表示Ctrl
, M
(Meta)表示Alt
C
的操作大部分跟单个字符有关, M
按键大部分跟单词的操作有关.
C-g
; 放弃命令C-x C-c
; 退出C-v
; 向下移动屏幕M-v
; 向上移动屏幕C-l
; 定位到屏幕中间C-p,n,f,b
; 上下左右导航按键.C-a
; 移动到行首C-e
; 移动到行尾M-a
; 移回句首M-e
; 移到句尾M-<,M->
; 移动到文件头和末尾C-u 8 C-f
; 重复8
次某个命令C-space
; 可视化选取,C-w
删除选中的部分C-y
; 粘贴寄存器中保留的删除段落.M-y
; 循环粘贴之前删掉的.C-x u
; 取消之前的命令.c-x c-f
; 打开文件.C-x C-s
; 保存文件. 如果不幸被冻结, 可以输入C-q
安装完Emacs
之后, 还需要安装一个自动补全(可以自动补全关键字, 文本等)的扩展, 名叫company-mode官网:
Emacs
里有个安装扩展的列表, 有点类似 Debian系列的 apt-get
和 Redhat系列的 yum
这样的包管理工具, 所以我们只需要按步骤安装:
- 按下
M-x
来调出命令输入 (在Windows下就是Alt + x 键) - 输入
list-packages
, 回车 - 在出现的列表里, 点击
company
- 在右边出现的新缓冲区里点击
Install
code
中安装插件, ailisp:Common Lisp
然后按照插件作者的教程配置.
先安装roswell
: https://github.com/roswell/roswell/wiki/Installation#building-from-source
Roswell
是一个 Lisp
实现的安装/管理程序, 启动程序, 以及更多的东西.
Roswell最初是一个命令行工具, 目的是使安装和管理Common Lisp
变得非常简单和容易.
现在, Roswell
已经发展成为一个用于普通Lisp
开发的全栈环境, 并具有许多功能, 使测试, 共享和分发你的Lisp应用程序变得容易.
Roswell目前在类Unix
的平台上运行良好, 如Linux
, Mac OS X
和FreeBSD
.
如果你对缺少的东西感兴趣, 请查看问题列表.
安装roswell
后, 不要错过推荐的设置. 以便用Slime
安装软件包时在Roswell
的上下文中进行.
注意:这可能是你第一次使用Lisp
的经验, 你可能已经尝试了你在互联网上找到的其他方法/教程(没有一个对你有用).
或者, 你可能已经设法使它工作, 但没有信心, 只是后来你发现了roswell
.
我们的建议是, 你最好删除你以前做的任何事情, 否则你最终会有两个重复的lisp
实现/quicklisp
/asdf
, 这使问题更加复杂.
在ubuntu
下需要进行手动编译. 安装为system-wide
sudo apt-get -y install git build-essential automake libcurl4-openssl-dev
git clone -b release https://github.com/roswell/roswell.git
cd roswell
sh bootstrap
./configure
make
sudo make install
ros setup
如果不想安装为系统应用
, 安装到用户目录:
git clone -b release https://github.com/roswell/roswell.git
cd roswell
sh bootstrap
./configure --prefix=$HOME/.local
make
make install
# 添加到系统变量, 也可以手动添加
echo 'PATH=$HOME/.local/bin:$PATH' >> ~/.profile
PATH=$HOME/.local/bin:$PATH ros setup
安装完成后, 使用ros
安装cl-lsp
, 还需要另外两个, 因为原始包在prepl
中没有readline
支持.
ros install ailisp/linedit
ros install ailisp/prepl
ros install ailisp/cl-lsp
- (推荐)安装
strict-paredit-vscode
, 它提供了接近Emacs
的最佳括号编辑体验. 在vscode
中按下Ctrl+P
(VS Code Quick Open ), 输入
ext install ailisp.strict-paredit
- (推荐)在
roswell
中使用sbcl
而不是sbcl_bin
, 这样可以跳转到common-lisp
包中的符号定义.
ros install sbcl
ros use sbcl
Lisp
的语法非常简单: 需要记住的规则很少.
语法是由S-表达式
组成的, Symbol-expression. S-表达式
要么是一个原子
(atom), 要么是一个列表
(list).
原子可以是数字
, 如10
, 3.14
, 或符号
, 如t
(真值常数), +
, my-variable
.
还有一种特殊的符号叫做关键字, 它是以冒号为前缀的符号, 如 :thing
或 :keyword
. 关键词运算为自身: 你可以把它们理解成是枚举.
;; 单行注释用; 开头,可以从一行的任意位置开始
#|
多行注释
#|
多行注释可以嵌套
|#
|#
严格说起来, 代码格式化既不是句法层面也不是语法层面上的事情, 好的格式化对于阅读和编写流利而又地道的代码而言非常重要.
格式化 Lisp
代码的关键在于正确缩进它. 这一缩进应当反映出代码结构, 这样就不需要通过数括号来查看代码究竟写到哪儿了.
一般而言, 每一个新的嵌套层次都需要多缩进一点儿, 并且如果折行是必需的, 位于同一个嵌套层次
的项应当按行对齐. 这样, 一个需要跨越多行的函数调用可能会被写成这样:
(some-function arg-with-a-long-name
another-arg-with-an-even-longer-name)
那些实现控制结构的宏和特殊形式在缩进上稍有不同: body
相对于整个form
的开放括号缩进两个空格
. 就像这样:
(defun print-list (list)
(dolist (i list)
(format t "item: ~a~%" i)))
尽管如此, 但也不需要太担心这些规则, 因为一个像 SLIME
这样的优秀 Lisp
环境将会帮你做到这点.
事实上, Lisp 正则语法的优势之一就在于, 它可以让诸如编辑器这样的软件相对容易地知道应当如何缩进.
由于缩进的本意是反映代码的结构, 而结构是由括号来标记的, 因此很容易让编辑器帮你缩进代码.
有经验的 Lisp
程序员们倾向于依赖的编辑器来自动处理缩进, 不但可以确保代码美观, 还可以检测笔误:
一旦熟悉了代码该如何缩进, 那么一个错误放置的括号就将立即由于编辑器所给出的奇怪缩进而被发现. 例如, 假设要编写一个如下所示函数:
(defun foo ()
(if (test)
(do-one-thing)
(do-another-thing)))
现在假设你不小心忘记了 test
后面的闭合括号. 如果不去数括号的话, 那么很可能会在 DEFUN
形式的结尾处添加一个额外的括号.
如果一直都在每行的开始处按 Tab 来缩进的话, 你将得到如下的代码:
(defun foo ()
(if (test
(do-one-thing)
(do-another-thing))))
看到 then
和 else
子句被缩进到了条件语句的位置, 而不是仅仅相对于IF
稍微缩进了一点, 你将立即看出有错误发生.
另一个重要的格式化规则是, 闭合的括号总是位于与它们所闭合的列表最后一个元素相同的行. 也就是说, 不要写成这样:
(defun foo ()
(dotimes (i 10)
(format t "~d. hello~%" i)
)
)
而一定要写成这样:
(defun foo ()
(dotimes (i 10)
(format t "~d. hello~%" i)))
结尾处的 )))
可能看起来令人生畏, 但是一旦代码缩进正确, 那么括号的意义就不存在了——没有必要通过将它们分散在多行来加以突出.
最后, 注释应该根据其适用范围被前置一到四个分号, 如同下面所说明的:
;;;; 四个分号用于文件头注释.
;;; 一个带有三个分号的注释将通常作为段落注释应用到接下来的一大段代码上
(defun foo (x)
(dotimes (i x)
;; 两个分号说明该注释应用于接下来的代码上.
;; 注意到该注释处在与其所应用的代码相同的缩进上.
(some-function-call)
(another i) ; 本注释仅用于此行
(and-another) ; 本注释仅用于此行
(baz)))