老古董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.pswp.cn/web/46395.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/46395.shtml
英文地址,請注明出處:http://en.pswp.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;演…