不久前,我在新加坡Zenika的内部活动中发表了演讲。 我们可以自由选择一个主题,所以我选择了一些我认为我还不了解的东西–在Clojure中构建Web应用程序的感觉。 这篇文章是演讲的笔录。 我将详细介绍Clojure,您可以使用哪些库来构建Web应用程序,以及所有这些对我的感觉。
Clojure
Clojure是一种LISP方言,它通过ClojureScript针对JVM,Microsoft的CLR和JavaScript。 它是一种功能性的动态语言。 它的特色之一是在添加或删除元素时依赖结构共享的不可变数据结构。 即使保持不变,这也可以提供良好的性能。
我主要对Clojure感兴趣,因为
- 它与周围所有基于C的语言有很大的不同
- 仍然是通用语言
由于其某些功能,例如软件事务存储(STM)和原子,它特别适合构建正确的并发应用程序。
我认为也很重要的一个方面:这似乎是一个非常友好的社区,我喜欢我参加过的两个用户组, 柏林Clojure和新加坡Clojure聚会 。
如果您想开始使用Clojure,最好从非常常用的构建工具Leinigen开始 。 它提供了一种简单的方法,可以独立或在REPL中构建和运行项目,而LISP方言通常使用此功能。
仅使用REPL和Leiningen并不能满足您的需要,您至少需要一些编辑文件的工具。 自然地,许多人似乎都在使用emacs,此外还有Cursive (基于IntelliJ构建), Lighttable (实验性IDE)和Nightcode (具有REPL内置的非常简单的编辑器)。
要开始一个项目,您只需安装Leiningen并使用lein repl
启动REPL lein repl
开始。
让我们从一个简单的操作开始,将两个数字相加。
user=> (+ 2 3 ) 5
这已经显示出Clojure的两个比较特殊的功能。 首先,所有代码都表示为一个列表。 这就是为什么甚至将操作都括在方括号中的原因。 其次,即使涉及数学运算,Clojure也会使用前缀表示法。 但这还有一个好处,就是您只需增加添加操作的参数数量即可。
user=> (+ 2 3 4 5 ) 14
而且,如果您考虑一下:一点也不奇怪。 如果您看到+作为函数名称(即函数名称),则这与您使用类似ac的语言调用函数的方式非常相似。
plus( 2 , 3 , 4 , 5 )
当然,您也可以将计算结果分配给变量。
user=> (def result (+ 2 3 4 5 )) #'user/result user=> result 14 user=> (- result 1 ) 13
除了数字值外,还可以使用其他数据类型,例如字符串和布尔值。
创建函数也非常容易。
user=> (defn append-mod [val] (str val "-mod" )) #'user/append-mod user=> (append-mod "some-value" ) "some-value-mod"
更有趣的数据结构是集合。 有用于顺序数据的向量。
user=> (def characters [ "a" "b" "c" ]) #'user/characters user=> (characters 0 ) "a" user=> (characters 1 ) "b"
还有一些地图,通常将所谓的关键字用作键。
user=> (def my-map {:key "value" :foo "bar" }) #'user/my-map user=> (my-map :key) "value"
作为一种功能语言,很常见的是对集合进行转换,例如使用map操作。 通过传递upper-case
功能,这也显示了将函数用作头等公民upper-case
。
userer=> (map clojure.string/upper- case characters) ( "A" "B" "C" )
重要提示:这不会修改现有的收藏集-它会创建一个新的收藏集。 由于数据结构的有效实施,一切皆有可能。
挑战性
确实,Clojure具有简单的语法,可以轻松上手。 但是仍然有很多东西要学习,开始时,不管是语法,宏还是库调用都没关系。 有时可能会有相关但不同的概念,这尤其令人困惑。 例如,这些都是创建函数的所有不同方法,但目的不同。
-
(defn name [] (body))
-
(def name (fn [] (body)))
-
#(body)
对我来说仍然困难的一件事是决定如何在Clojure中构造程序。 在同一个名称空间中具有很多功能似乎很常见。 我想很难决定哪个功能负责哪个数据或任务。
最后,至少对我来说,这些文档可能会令人困惑。
建立网路应用程式
作为一种通用语言,Clojure当然可以并且也经常用于构建Web应用程序。 与Java环境相比,选择要少得多,一种非常常见的组合是使用三个库: Ring作为核心库, Compojure用于路由选择,而Hiccup用于模板。
环实现为管道。 首先,有一个适配器,用于映射到内部请求/响应表示形式,并适应现有的Web运行时。 有一个使用Jetty的适配器,或者另一个仅依赖Servlet API的适配器,这使得可以将Ring应用程序部署到任何servlet容器。
接下来是中间件。 这些就像Java servlet世界中的过滤器,可以用来增强应用程序。 默认情况下,配置了一些中间件,例如用于处理参数,会话或cookie。
最后,请求到达处理程序,该处理程序将请求转换为响应。
Compojure可以帮助您实现这些处理程序的路由。 这是一个简单的示例,它创建了一条成功的路由和一个函数来处理未找到的路径。
(defroutes app
(GET "/" [] "Hello World
" )
(route/not-found "Page not found
" ))
如果您想自己入门,最简单的方法是使用为您创建应用程序框架的leiningen-compojure模板 。
lein new compojure my_project_name
这将创建必要的文件夹结构,leiningen文件,处理程序和测试。
如果您不想像上面的示例一样自己用Strings编写所有html,那么该使用模板库了。 打ic是经常与Ring和Compojure结合使用的一种。 它允许您编写正在转换为HTML的Clojure代码。
user=> (html [:span {: class "foo" } "bar" ]) "bar"
我使用这些库开发了一个非常简单的应用程序:一种用于查看和添加词汇的工具。 开始后,您可以查看词汇表,添加更多单词并查找翻译。 我不会说它现在已经可以生产了,原因之一是它仅将所有数据存储在内存中:)您可以在Github上找到源代码 。
它包含一个GET和POST路由,用于读取列表并添加单词和打ic模板。
结论
使用新语言很有趣,并且掌握了Clojure的基础知识之后,就很容易开始使用Webapp,这主要是因为Leiningen Compojure模板可以轻松地建立新项目。 Ring中间件中有很多现成的功能可用。 打ic仍然让我感到有些奇怪,我不确定很多前端开发人员是否热衷于使用它。
我希望我能有更多的时间准备这次演讲并为该示例工作。 我还有很多事情不知道,我希望我能找到一些时间继续学习。 即使我不希望很快在工作中的项目中使用Clojure,学习新方法也会非常有益-您对某些语言功能的看法可能会改变。
如果您也想开始使用Clojure,我特别推荐基础知识Aphyrs系列 。 这些年来,我看到不同的InnoQ人士发表了有益的演讲,特别涉及Web库。 YouTube上有Michael Vitz的录音 。
翻译自: https://www.javacodegeeks.com/2017/10/learning-build-clojure-webapps.html