其实外部语言, 主要还是看外部语言的生态, 语言之前风格切换都是可以克服的。
比如Python, 一旦互调用起来, 基本不用管生态的问题, 啥库都有。
NeoVim 那些人对接了Lua后, 其实也发展很好, Lua的生态还不如 Python, 主打一个执行速度快。
其实外部语言, 主要还是看外部语言的生态, 语言之前风格切换都是可以克服的。
比如Python, 一旦互调用起来, 基本不用管生态的问题, 啥库都有。
NeoVim 那些人对接了Lua后, 其实也发展很好, Lua的生态还不如 Python, 主打一个执行速度快。
感觉Clojure很不活跃,用户太少了,案例太少了。
我简单的目测了一下 clomacs 的源代码, 我觉得 clomacs 那样实现的性能是很有问题的。
colmacs 虽然有 async 的 callback, 但是我觉得它的思想还是启动一个 nrepl 的 server, 然后一条一条的执行 Emacs 发过来的 Clojure 函数代码, 这样不管 colmacs 的 sync 还是 async 设计, 本质 nrepl 是 block 的, 一旦某一个 Clojure 的计算量大了以后, 虽然不卡Emacs, 但是结果半天也返回不了, 甚至是多条 Clojure 计算任务, 只要中间某一个 Clojure 函数太耗时, 其他任务也会卡住。
可以认为 Colmacs 的设计现在是一个外部进程的 node.js 协程设计, 虽然不卡Emacs, 但是它自己一条一条的执行会卡住。
我的设想是: 开发调试时, 依然用 Cider 去一条一条的测试, 就像我们有时候在终端用 ipython 测试 Python 想法一样
但是真正的扩展框架应该像 lsp-bridge 那样去设计:
这样设计应该可以实现和 lsp-bridge 一模一样的性能, 同时让外部扩展程序也是 Lisp 风格。
猫大这是想引入JVM生态吗?
是呀,我觉得啥语言都试一下,这样emacs慢慢地就又快又有库生态了
引入一个lisp语言扩展想法挺好,贡献者会多不少。只是JVM的话有点太笨重了,可能比node还不受待见
真的笨重,用过cider就知道起一个repl要眼睁睁等上老半天
能先启动外部进程,不用的用户,做再多他都不会用。
也不是 clojure 启动慢,大部分 Java 应用启动都慢
我有点儿好奇,使用 clojure 真的能加速 Emacs 吗🤔 在 Emacs 中 Elisp 总是写得最称心的语言,我有点儿怀疑并没有那么多愿意使用 Clojure 扩展 Emacs 的开发者,也很难建立起像 python-bridge 那样的社区。
这个不必担心吧。就好像 C 火起来是因为 unix,python 火起来是机器学习,只要有一个足够强大用的人足够多的产品,自然有人来为这个环境买单。
有多线程的语言都可以加速,只是编写体感的差别。
clojure 的话,可以使用 Java 的 virtual thread,类似 goroutine 的东西,每个任务一个线程呢。
不过与其做成任务,是不是做成连线会更好?主线程接受配置请求设置全局配置,接受连线请求构建一个新的子线程再与客户端连线,客户端收到子线程的 id 之后都与子线程沟通。这样一个 server 可以同时启动多个分离的连接,而每个客户端也可以有多个插件,每个插件都好像和单独的 clojure 实例沟通一样。
当然这样实现比较复杂可能涉及协议,可能不如服务端不保留状态的实现起来简单。
另外 clojure 和 emacs 的沟通格式,都不妨设置一种转接器,内部都是用顺序表和散列表,沟通中使用 Json 还是 S Expr 甚至 XML 都可以,转接器能把中间状态转回内部顺序表和散列表就好了。
设计一套类似于LSP的协议?然后就语言无关了。这套内部机制最好用C或者rust来搞,性能和扩展性都有了
非也,只是 clojure 和 emacs 间沟通的,与其说是 LSP 更像是 tcp。建立连接后这套协议就不管事了,客户端和服务端到底发送什么消息往来他们自己决定。
感觉还是缺少一些更加实际一点的应用例子?
外部进程完全可以解决启动慢这个问题, 比如在 Emacs 启动的时候去判断是否有一个 lisp server 在运行, 若无则再新建一个 (简单用的启动代码):
;; emacs lisp
(condition-case nil
(sly-connect "localhost" 4005)
(error
(message "SLY not connected. ")
(when (string= "y"
(completing-read "Create a Lisp backend? [y/n]: " '("y" "n")
nil t "y"))
(shell-command
(concat "screen -dmS sbcl " ;; 用 screen 让 SBCL 在后台运行
"sbcl --dynamic-space-size 2048 " ;; 这里完全可以用 dump image 来加速启动
"--eval \"(ql:quickload :slynk)\" "
"--eval \"(slynk:create-server :dont-close t :port 4005)\""))
(run-with-idle-timer
1 nil #'(lambda () (sly-connect "localhost" 4005))))))
(Clojure 没怎么用过, 我记得应该 nrepl 的实现里面也有连接到现有的 Clojure 环境中的操作)
是的,编程框架和LSP不一样。
LSP有特定功能,编程框架更像是TCP链接,借助外部语言的多线程能力。
clojure的最佳编辑器是emacs。有共同的群众基础。
我倒觉得可以扩展下思路