尝试用kawa布置网页服务

Author: R.W.Flurando

Tags: java, jvm, kawa, scheme, 网页

怎么扯到这里来的

前几天写了一通js,就是那个本意写作业的失败项目。

现在我又没事干了,不是不知道做什么,而是水平不够很多想实现的东西无从下手。

具体有

  1. 用guile chickadee制作一个2d格斗游戏。

    别说格斗了,我动画功能都只有最简陋的几十张png帧循环绘制的demo,抽象API还没有想好。

    游戏内要哪些变量我也不清楚,感觉得先看看别人实现的做个参考,但我手上只有castagne的源码,问题是它用Godot语言写的我是半行看不下去。

    只好搁置,等哪天我想到怎么实现再说。

  2. 用guile-web等基本库写一个类似Python Flask、Ruby on Rails、Rust Rocket的后端框架。

    目前guile只有artanis,但artanis走得是monolithic风格,和我的极简追求不符。虽然guile自带的web模块就是极简主义,但是它过于硬核了,以至于在我的水平下就是没法用。

    artanis想用就得展开一个大文件夹,还夹带着i18n和数据库模块,连Nginx适配都内置,而我只是想测试一个刚从网上抄来的动态页面效果。

    guile-web呢,另一个极端,帮忙把socket之类的工作做完了,其他一概不管。收一个请求和可能的体,要返回一个回复和可能的体,再加上一个把路径里的斜杠省略号等展开的函数,没了。

    关键是什么呢,guile社区两级分化严重,有能力用guile-web开服务的都不觉得需要Flask平替,因为对他们来说用guile-web和Flask没有什么区别,甚至会搬出Lisp金句“需要什么功能自己实现啊”。没能力用guile-web开服务的当然更没能力编个guile-flask出来。

    也搁置了,以后再说。

  3. 用guile hoot写一个调用前端js库的库

    这个不说了,就是用wasm跑的guile scheme。

    限制有点多,不仅我的水平摆在那里,而且浏览器wasm功能并不支持尾递归之类FR语言的刚需。

    所以这条想归想,必要时可以改成“参与实现一个跑沙盒r7rs-small子集而不是js的浏览器”。

  4. 用guile goblin写一个分布式的游戏

    这个在spritely网站上可以看到demo,但有一说一我没懂怎么弄的,教程也没明白。

    以后再说。

这些目前是一筹莫展,我也总得找点事情做吧。

一直玩的都是解释性语言,编译成exe只在梦里有,正好空下来我就想拿可以编译成机器码的语言玩一玩。

C++和C目前没有动力深究,一是我现在写代码只有geiser基础的变量补全,C、Go、Rust、Java需要的lsp支持整行整段补全我是根本不知道如何给emacs配置,vscode由于大量需要本地命令支持而与guix系统不兼容大多数时间是摆设。

所以决定还是在Lisp这边找,候选是scheme、common lisp和clojure。

其中clojure名声比较大,算是Lisp世界的Go语言了,并行什么的一套一套。但是我弄了半天,还不知道怎么装那些jar依赖,看样子还需要用Java里的maven或ant,我哪里会。

于是又回到scheme,准确说是可以编译成zip包的Kawa Scheme。

由于标准存在,Kawa的语法和Guile还是很像的,具体区别在于Guile独有的define-module、use-module、#:something标志和Kawa独有的:调用、something:标志、直接引用Java库。 可以说无伤大雅,可以接受。

Kawa让我不舒服的一点是,只能编译成用kawa.repl.jar解释运行,而无法由jre直接运行。准确说是文档闪烁其词,声称可以,但我捣鼓半天,结论是不行,除非你用ant或maven把项目和kawa的jar包一起打包。

但是,直接调用Java库还是很神奇的。

如果我不会装依赖,干JVM环境能干什么

当然是做网页服务啦!

装好JRE或JDE,比如icedtea实现,以及kawa,我们就可以开始。

按照Kawa教程,在一个空文件夹里创建一个叫“+default+”的文件,里面写上

;; This is -*- scheme -*-
(define current-date (java.util.Date))

#<h1>Debug</h1>
#<ul><li>request-URI: &{(request-URI)}</li><li>request-path: &{(request-path)}</li><li>request-url: &{(request-url)}</li><li>request-context-path: &{(request-context-path)}</li><li>request-script-path: &{(request-script-path)}</li><li>request-local-path: &{(request-local-path)}</li><li>request-query-string: &{(request-query-string)}</li>
</ul>

#<footer>
  <p>Just a Test Page sent at &{current-date}</p>
</footer>

这个叫web script,也就是用于动态生成页面的脚本,远古战神php就是用这种方式组成网页。

接下来在这个文件夹里运行kawa --http-auto-handler / . --http-start 8000启动服务, 在浏览器访问http://127.0.0.1:8000/下任意路径均可看到相应返回。

这种方式确实简单,适合对后端无定制要求,前端无迁移要求的项目,很容易的就是一个SSR(ServerSideRenderring服务器端渲染)网页服务。如果搭配Tomcat之类的,放到生产环境没有问题。

你看,不仅有scheme的简单,还有JVM的兜底,要不是没法打包成jar,我不得高低调个项目出来。
可惜,目前这个cgi-bin风格的功能我不大需要,又不能变jar,那只有一篇博客了。

不过话说回来,JVM这里servlet服务用kawa并不用担心这个,只是我有点强迫症希望JVM的东西都能变jar。
这是因为kawa即便运行源代码形式,也是在初始化时编译缓存再继续,而编译对象就是直接的JVM字节码,速度完全不用担心。
所以如果现在我需要在JVM上运行网页服务,那kawa绝对是很特别的选择,更别谈对Java库的直接支持了。

感想

好的,体验到此结束。

再怎么说,我也是用过JVM的人了,感觉人都硬气得多。

你们记住了,本博主用过JVM。

至于这么闹半天也没打出机器码的问题嘛,我正在想

有没有可能
我就这么对着电脑发呆
突然就有一个项目蹦脸上
不用怎么学习就能做到README里吹嘘的内容
同时不限制任何用户自由,又方便改

要说有也确实有,但我要看的是别人的项目啊,怎么看来看去很多人水平似乎很高,但完全不会或不想教别人的样子。