老古董Lisp(1):粗鲁先生Lisp再出发

粗鲁先生Lisp再出发

开始的原因

目标和梦想是最近考虑的一个问题。什么是目标?什么是梦想?梦想可以激励改变,目标才能实现改变。

开始这个部分的时候,我的梦想是什么?我的目标是什么?我想要什么?我要做什么?

  • 逃避手头的项目
  • 逃避手头的工作

学习Lisp可以回溯到大学时期,为什么要学这么奇怪的东西呢?也看过《画家和黑客》这本书,时断时续地看过一些比较外围的Lisp博客,甚至书籍。但是Lisp从来没有成为生产力工具,也没有形成任何成果。

那么,到底行不行呢?

所以,这次被手头的工作压垮的时候,我又退回到曾经的路径,逃避到学习一个新的、或者旧的编程语言上。好多编程语言就是这样学会的……这个策略就跟失眠就去学微积分一样,要么学了一点人类最高级的智慧,要么困了就睡着了。

那么这一次Lisp的学习,又会怎么样呢?能不能让我在被死线压垮的时候,摆一个更加优雅的姿势呢?希望能够吧……Lisp如此优雅,这次我一定会死得很优雅吧。

实用的目标

跟以前学习Lisp不同的是,这次我想选择一个更加实用的目标。第一时间想到的是,我要不要把我经常写给别人的小工具,用Lisp来实现呢?通常,我用Python来写这些,但是给别人的时候总是有这样那样的问题。

比如说,真的很多人根本不可能装Python,所以我会感染每一个我接触的电脑,我用过之后,这些电脑上总是被被装上Python。

我会用pyinstaller打包,但是Pyinstaller打包的过程和结果,总是让人有一点点不放心。每次成功了我总是会觉得自己很幸运。

那么,Lisp是不是一个很好的选择呢?

根据我那些远古时代关于Lisp的记忆,加上一点点搜索,结论是:相当行。只要你能跟Lisp在一定的程度上不相互抵触……

这次重新开始Lisp,我准备戴上一顶粗鲁先生的帽子,简单粗暴地对待Lisp,毫不理会Lisp那些优雅、美好的特性,只要能用就行。

开始的过程

稍微看一下,现在开发Lisp大概有两个主要的流派(单纯是个人观点):

  1. Emacs Lisp
  2. Common Lisp

开发环境同样有两个主要的流派:

  1. Emacs
  2. VSCode

这两个并不是完全对应的,因为Emacs啥都行,VSCode搞Emacs Lisp估计比较抽象。

我选择的是Common Lisp和VSCode。至于Common Lisp的实现,直接说结论:SBCL。

  1. 安装SBCL
  2. 安装VSCode
  3. 安装alive插件
    1. 安装quicklisp
    2. 安装alive-lsp
    3. 安装alive插件
  4. 开始写代码
  5. 产生一个可执行文件

SBCL安装

SBCL是Steel Bank Common Lisp的缩写,是一个Common Lisp的实现。在这里可以找到各种平台的安装方法。

或者,如果不是windows,可以直接用包管理器安装:

sudo apt-get install sbcl

安装好之后,可以考虑把SBCL的路径加到环境变量里面。之后就能在任意地方打开终端,输入sbcl,就能进入SBCL的REPL了。

This is SBCL 2.4.6, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
*

这就是成功安装的标志。在这个星号后面,就可以输入Lisp代码了。比如输入(print "Hello, World!"),然后回车,就会输出"Hello, World!"。输入(quit)或者(exit),就会退出SBCL的REPL。后面还有一堆需要在这个REPL里面输入的命令。每次看到REPL,那就是说的这个东西。

SBCL软件的配置文件位置为~/.sbclrc,可以在这个文件中配置SBCL的一些参数。下面安装过程中会涉及这个文件。

VSCode安装

VSCode是微软出品的一个编辑器,可以在这里下载。这个就不需要我多说了,安装方法也很简单。

alive插件安装

Alive插件本身是VSCode的一个插件,可以在插件市场直接搜索安装。但是Alive的正常运行就不是一个那么简单的事情了。

Alive的功能依赖于LSP,并不是lao se pi,是Language Server Protocol,是实现通用编辑软件中不同类型编程语言的语法分析和自动补全的协议。

所以,我们需要安装一个LSP的实现,这个实现就是alive-lsp。那么Common Lisp的软件包怎么管理呢?优雅的Common Lisp的软件包管理工具就是quicklisp。

quicklisp安装
  1. 下载quicklisp.lisp文件,可以在这里找到,具体的下载链接是这里,另存在一个目录下,比如~/Downloads
  2. 在这个目录中打开终端,或者打开终端,切换到第一步的目录。
  3. 输入sbcl --load quicklisp.lisp,然后就会进入SBCL的REPL。
  4. 输入(quicklisp-quickstart:install),然后就会开始安装quicklisp。
  5. 安装完成之后,输入(ql:add-to-init-file),然后就会把quicklisp的初始化代码加到~/.sbclrc文件中,这里有一个确认的过程,不要以为不动了,按一下回车就行。
  6. 输入(quit),退出SBCL的REPL。

这个过程简单粗暴。貌似这几个网站访问也很正常,不想大型交友网站github那样,需要上科学技术。

唯一值得一提的是,quicklisp.lisp文件只有1757行,还真是一个小巧的东西,等我带上知识先生的帽子,也许我要好好读一读这个文件。

在SBCL的配置文件中,quicklisp加了几行:

;;; The following lines added by ql:add-to-init-file:
#-quicklisp
(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp"(user-homedir-pathname))))(when (probe-file quicklisp-init)(load quicklisp-init)))

quicklisp会给你的主文件夹下面生成一个~/quicklisp文件夹。从SBCL的配置文件可以看到,这个文件夹里面有一个setup.lisp文件,这个文件是quicklisp的初始化文件,可以用来加载quicklisp的软件包。

alive-lsp安装

这个插件是目前VSCode上可以用的Common Lisp实现,但是这个玩意有两个问题:

  1. 不会自动安装SBCL
  2. 不会自动安装alive-lsp
  3. 自己不在quicklisp的软件库里

除此之外,这个软件目前看起来还是挺完美的。

所以,我们需要手动安装alive-lsp。不然的话,我们会一次一次看到报错“MISSING DEPENDENCY USOCKET”之类的。大概一共有四五个缺失的包,每次都要手动安装,然后重启VSCode,再次报错另外一个包,再次手动安装,再次重启VSCode……

鉴于我戴了粗鲁先生的帽子,智商的缺陷简直是肉眼可见。在我把上面的过程全部搞了一遍之后,我才想到可能直接安装alive-lsp可能是我所需要的,然后就发现quicklisp里面根本没有alive-lsp这个包。

(ql:quickload :alive-lsp)      ;; 安装alive-lsp
(ql:system-apropos "alive")    ;; 查找alive包

最后,大型交友网站上看到alive-lsp,跑去看了Alive-LSP的文章。好的,这个玩意还需要自己去装。

倒是也不亏,学会了一个把自己的包弄到quicklisp里面的方法。

这几回到前面提到的文件夹~/quicklisp,这个文件夹里面有一个local-projects文件夹,把alive-lsp的文件夹放到这个文件夹里面,然后再次进入SBCL的REPL,输入(ql:quickload :alive-lsp),就会自动安装alive-lsp了。

网络状态稳定的话,就在这个目录下使用下面的命令:

C:\Users\<<username>>\quicklisp\local-projects> git clone https://github.com/nobody-famous/alive-lsp.git

要把<<username>>替换成你的用户名。

如果网络不稳定,那么下面的链接是alive-lsp的压缩包,这个是我用git archive命令生成的:

git archive --format=zip --output=alive-lsp.zip HEAD

alive-lisp.zip CSDN下载

alive插件使用

Alive插件的安装就很简单了,直接在VSCode的插件市场搜索安装就行。

安装好了之后,打开一个Lisp文件,然后就会自动启动alive-lsp,然后就可以使用LSP的功能了。

比如下面的命令面板里面增加了一个REPL的标签,可以直接在这个标签里面输入Lisp代码,然后执行。

一个小工具的实现

这部分部分就不用深入到uiop或者语法,或者什么SBCL了,只是展示可能性。

这里,实现一个统计软件行数的工具,整好写软件著作权也需要这个东西。

;; lc.lisp
;; 从命令行获得一个表达式,然后统计这个表达式的文件的行数,列出每个文件的行数,最后列出总行数(require :uiop)(defun get-expr ()"Get the expression to find files, default is *.lisp"(let ((expr (uiop:command-line-arguments)))(if (null expr)"*.lisp"(car expr))))(defun get-files (expr)(uiop/filesystem:directory-files#P"./"expr));; count lines in a file
(defun count-lines (file)(with-open-file (stream file)(loop for line = (read-line stream nil)while linecount line)));; catch count-lines io errors
(defun count-lines-with-error (file)(handler-case(count-lines file)(error (c)(format t "=====~%Error: ~A~%======~%" c)0)));; count lines in files print each number and sum them
(defun main ()(let ((expr (get-expr)))(let ((sum 0))(dolist (file (get-files expr))(let ((lines (count-lines-with-error file)))(format t "~A: ~A~%" file lines)(incf sum lines)))(format t "Total: ~A~%" sum))))

好了这个软件已经写完了。接下来就是如何产生一个可执行文件。

;; compile-lc.lisp
;; 产生一个可执行文件
(load "lc.lisp")
(sb-ext:save-lisp-and-die#p"lc.exe":toplevel #'main:executable t)

有了这两个文件,就可以在这两个文件所在的目录下启动SBCL,然后输入(load "compile-lc.lisp"),就会在这个目录下生成一个lc.exe文件,这个文件可以在任何地方使用(SBCL对应的平台)。

或者直接执行sbcl --load compile-lc.lisp,也会生成一个lc.exe文件。

CSDN下载命令行工具:代码行数统计lc

最后就是这个软件的使用:

(base) PS C:\lisp-revisit> lc
C:/lisp-revisit/compile-helloworld.lisp: 5
C:/lisp-revisit/compile-lc.lisp: 5
C:/lisp-revisit/helloworld.lisp: 17
C:/lisp-revisit/lc.lisp: 39
Total: 66

这也挺不错的不是吗?这个跟lc *.lisp效果是一样的。

或者,还能统计子目录:

(base) PS C:\lisp-revisit> lc **/*.lisp
C:/lisp-revisit/.vscode/alive/fasl/tmp.lisp: 5
C:/lisp-revisit/compile-helloworld.lisp: 5
C:/lisp-revisit/compile-lc.lisp: 5
C:/lisp-revisit/helloworld.lisp: 17
C:/lisp-revisit/lc.lisp: 39
Total: 71

这个效果在windows的PowerShell和cmd上都可以使用。

总结

Common Lisp其实挺好用的。

  1. 使用SBCL作为Common Lisp的实现
  2. 使用VSCode作为编辑器
  3. 使用quicklisp作为软件包管理工具
  4. 使用alive-lsp作为LSP的实现,配合alive插件
  5. SBCL可以直接产生可执行文件,无依赖,单文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/46395.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

libwebrtc.a+exosip连接fS 环境部署tips

//运行FS服务器 sudo ./freeswitch -nc -nonat //公网sudo ./freeswitch //运行客户端 sudo ./fs_cli //加载模块 load mod_av load mod_verto0.Invite交互过程 1.fs码率设置 2.用户密码改动 3.数字签名的摘要 4.FS收不到ACK 5.公网部署 6.查看frewswitch都占用哪些端口 7.日志…

Java(二十一)---栈的使用和模拟实现

文章目录 前言1.什么是栈(Stack)?2. 栈的模拟实现3.stack的使用![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/80c82d22f3ee49cfaa2915d1c961573e.png)4.关于栈的oj题4.1.有效的括号4.2.逆波兰表达式4.3.栈的压入、弹出序列4.4.最小栈 前言 前面几篇我们学习了顺序…

Vue--Router(路由)

目录 一 Router(路由) 1.作用 2.实现步骤 3.注意 一 Router(路由) 1.作用 Router又叫做路由&#xff0c;简单来说&#xff0c;就是用来实现vue的页面之间跳转的。 我们都知道&#xff0c;使用vue必然会涉及到很多个组件&#xff0c;也就是页面&#xff0c;而页面之间肯定需…

RK3588读取不到显示器edid

问题描述 3588HDMIout接老的显示器或者HDMI转DVI接DVI显示器显示不了或者显示内容是彩色条纹,但是这种显示器测试过如果接笔记本或者主机是可以直接显示的。这一类问题是HDMI下的i2c与显示器通讯没成功,读取不到设备的edid。问题包括全志的H3 、AML的S905都有遇到 测试环境…

Qt-事件与信号

事件和信号的区别在于&#xff0c;事件通常是由窗口系统或应用程序产生的&#xff0c;信号则是Qt定义或用户自定义的。Qt为界面组件定义的信号往往通常是对事件的封装&#xff0c;如QPushButton的clicked()信号可以看做对QEvent::MouseButtonRelease类事件的封装。 在使用界面组…

【QGroundControl二次开发】二.使用QT编译QGC(Windows)

【QGroundControl二次开发】一.开发环境准备&#xff08;Windows&#xff09; 二. 使用QT编译QGC&#xff08;Windows&#xff09; 2.1 打开QT Creator&#xff0c;选择打开项目&#xff0c;打开之前下载的QGC项目源码。 编译器选择Desktop Qt 6.6.3 MSVC2019 64bit。 点击运…

vue3-tree-org实现带照片的组织架构图

官方文档&#xff1a;vue3-tree-org 显示照片需要注意的地方 使用步骤 下载 npm install vue3-tree-org --save 在main.js中引入 import "vue3-tree-org/lib/vue3-tree-org.css"; import vue3TreeOrg from vue3-tree-org;app.use(vue3TreeOrg) 实现代码 <tem…

level 6 day2 网络基础2

1.socket&#xff08;三种套接字&#xff1a;认真看&#xff09; 套接字就是在这个应用空间和内核空间的一个接口&#xff0c;如下图 原始套接字可以从应用层直接访问到网络层&#xff0c;跳过了传输层&#xff0c;比如在ubtan里面直接ping 一个ip地址,他没有经过TCP或者UDP的数…

解决TypeError: __init__() takes 1 positional argument but 2 were given

问题描述&#xff1a; 如下图&#xff0c;在使用torch.nn.Sigmoid非线性激活时报错 源代码&#xff1a; class testrelu(nn.Module):def __init__(self):super().__init__()self.sigmoid Sigmoid()def forward(self, input):output self.sigmoid(input)return outputwriter…

记录贴-芋道源码

环境搭建 文字讲解 链接: 芋道源码-环境搭建&#xff08;一&#xff09;后端 链接: 芋道源码-环境搭建&#xff08;二&#xff09;前端 链接: 基于FastGPT和芋道源码挑战一句话生成代码 视频讲解 链接: 芋道源码零基础启动教程&#xff08;上&#xff09; 链接: 芋道源码零基…

Blackbox AI:你的智能编程伙伴

目录 Blackbox AI 产品介绍 Blackbox AI 产品使用教程 Blackbox AI体验 AI问答 代码验证 实时搜索 探索&代理 拓展集成 总结 Blackbox AI 产品介绍 Blackbox是专门为程序员量身定制的语言大模型&#xff0c;它针对20多种编程语言进行了特别训练和深度优化&#xff0c;在AI代…

React 从入门到实战 一一开发环境基础搭建(小白篇)

React 从入门到实战一一开发环境基础搭建&#xff08;小白篇&#xff09; React 介绍什么是 react &#xff1f;react 主要功能react 框架特点 开发工具渲染测试 React 介绍 最近两年&#xff0c;react 也愈来愈火热&#xff0c;想要在里面分一杯羹&#xff0c;那肯定逃不过 r…

UFS协议

1. 名词解释 UFS: universal flash storage SCSI&#xff1a;小型计算机系统接口 SPC&#xff1a;SCSI Primary Commands SBC&#xff1a; SCSI Block Commands Application Client&#xff1a;作为主机中SCSI命令和任务管理功能请求源的实体。 Device Server&#xff1a;设备…

高级java每日一道面试题-2024年7月17日(java内存模型-后期完善)

面试官: 你对java内存模型了解多少? 我回答: Java内存模型&#xff08;JMM&#xff0c;Java Memory Model&#xff09;是Java虚拟机&#xff08;JVM&#xff09;规范的一部分&#xff0c;它定义了线程之间的内存可见性和并发执行时的原子性、有序性和可见性等特性。理解JMM对…

Windows下使用Cygwin创建rsync服务端

1 下载Cygwin 访问官网Cygwin&#xff0c;点击setup-X86_64.exe即可开始下载 2 安装 前面全部默认。路径可以自己选择&#xff0c;站点选阿里云的&#xff0c;等待安装即可 3 配置 使用打开Cygwin安装后创建的快捷方式窗口&#xff0c;输入下面的指令将windows用户导入到cyg…

C语言中常见库函数(1)——字符函数和字符串函数

文章目录 前言1.字符分类函数2.字符转换函数3.strlen的使用和模拟实现4.strcpy的使用和模拟实现5.strcat的使用和模拟实现6.strncmp的使用和模拟实现7.strncpy函数的使用8.strncat函数的使用9.strncmp函数的使用10.strstr的使用和模拟实现11.strtok函数的使用12.strerror函数的…

物联网平台有哪些?

随着科技的不断进步&#xff0c;物联网&#xff08;IoT&#xff09;已经成为我们生活中不可或缺的一部分。物联网平台作为连接设备、数据和应用的桥梁&#xff0c;扮演着至关重要的角色。本文将介绍一些主流的物联网平台&#xff0c;并特别关注ThingsKit物联网平台。 物联网平…

UE4-系统默认天空球的使用

当我们在调整平行光的时候&#xff0c;会发现场景中的光照改变了&#xff0c;但是太阳的位置并没有改变&#xff0c;此时就需要用到系统默认的天空球中的&#xff1a; 但是只有在选中是由平行光的改变而改变的情况下才会发生改变&#xff0c;如果没有选择或者选择其他的光源&am…

基恩士扫码头程序开发日记

需要获取基恩士扫码枪的扫描数据&#xff0c;并实现与access数据库中的数据进行比对。 一. 引用 下到了的SDK&#xff0c;还选择了Anycpu. 引用中添加了这个dll文件 Communication.dll Keyence.AutoID.SDK.dll VncClientControlCommon.dll using Keyence.AutoID.SDK; 二.遇到…

github.com/antchfx/jsonquery基本使用

要在 GitHub 上使用 antchfx/jsonquery 库来查找 JSON 文档中的元素&#xff0c;首先需要了解这个库的基本用法。jsonquery 是一个用于查询 JSON 数据的 Go 语言库&#xff0c;允许使用 XPath 表达式来查找和选择 JSON 数据中的元素。 以下是一些基本步骤和示例&#xff0c;演…