使用 Clojure 一个月后的想法
My thoughts after using Clojure for about a month

原始链接: https://www.acdw.net/clojure/

在最近使用 Clojure 重写个人网站后,作者分享了学习该语言一个月后的积极感想。他指出了 Clojure 相比其他 Lisp 方言的三大主要优势: * **内聚性:** 与感觉像是“委员会设计”产物的 Common Lisp 不同,Clojure 提供了统一的“序列(seq)”抽象和标准化的操作,使用起来更为顺手。 * **实用性:** Scheme 虽然简洁但往往缺乏必要功能,而 Clojure 则是“内置电池”,拥有庞大的标准库,并能利用广阔的 JVM 生态系统。 * **数据结构:** Clojure 将向量、哈希映射和集合提升为一等公民,创造了比传统 Lisp“万物皆列表”方案更实用的开发体验。 尽管最初对复杂的语法(多种括号类型)以及最终需要了解底层 Java 生态系统存有顾虑,但作者认为 Clojure 既有趣又强大。他总结称,Clojure 是进行 Web 开发和脚本编写的高效工具,并计划通过解决 Project Euler 问题来继续他的学习之旅。

Hacker News 最新 | 过往 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 使用 Clojure 约一个月后的想法 (acdw.net) 18 分,speckx 发布于 1 小时前 | 隐藏 | 过往 | 收藏 | 讨论 | 帮助 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

I am now generating this website with Clojure (yes, right after rewriting it in GNU Make and shell; I have a problem, ok?). In a personal tradition, I used writing a static site generator as the project to play with and learn Clojure as a new language. While I’ve long scoffed at Clojure for its copious syntax (three types of brackets!?), it turns out to be pretty ergonomic and powerful. Here are my impressions after playing around with Clojure for about a month.

More cohesive than Common Lisp

Common Lisp is so called because it’s a compromise among roughly all the extant lisps when it was written in the early 80s. As such, it’s a weird mashup of programming paradigms and name schemes. Instead of map-ing a function over a list, for example, you mapcar it. Instead of filter, you write remove-if-not, with all the confusion of a double-negative. Overall, Common Lisp has a strong feeling of being designed by committee, whch makes sense, because it was.

Because Clojure is newer and the brainchild of one person, it’s more cohesive as a language. The seq abstraction, for example, means I usually don’t have to worry about what kind of sequence I’m dealing with. Instead of having to remember aref for arrays and nth for lists, I just use nth for everything. It also makes mapping easier: instead of having to remember

;; This is real syntax!
(loop for k being the hash-keys
      using (hash-value v) of hash-table
      ...)

;; OK, you could also use
(maphash (lambda (k v) ...) hash-table)

I can simply call (map (fn [[k v] ...]) hash-table) and be done with it. And remember, map works with any collection.

It’s the same with equality: instead of having to remember the fine distinctions between eq, eql, equal, equalp, and more that are type-specific, I can just call = (or == if comparing numerical values, or identical? to see if values are identical). To be fair, there are caveats, but I haven’t run into them in a month. I had to learn the different equality forms immediately to get going with Lisp.

More “batteries included” than Scheme

Scheme was also built by committee, but you could argue it’s even more cohesive than Clojure. However, it’s “cohesive” in the way that a bicycle is cohesive: it includes very little in the way of ergonomics, paring down the language to its barest bones. Indeed, the introduction to every revision of the Scheme Report begins:

Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary.

Schemers often boast that the R5RS spec fits within 50 pages, which is impressive, but basic functionality like error handling, file handling, and even hash-maps are missing from the core language. While R6RS added plenty of functionality, it also caused a huge rift in the community that R7RS is trying to heal, but it’s slow going.

Scheme is like this beautiful jewel, an implementation of a pure programming ideal. Clojure, on the other hand, is pragmatic: it has a large standard library and is hosted on the JVM, so there’s probably a library for whatever domain you’re working in. Especially as a hobbyist programmer, I appreciate the ecosystem.

Ergonomic data structures

One of the things that first drew me to Lisp is that it’s an “everything-is-a” language. You know, like

  • Lua: everything is a table
  • Tcl: everything is a string
  • Lisp: everything is a list

I just love languages where there’s one Big Idea and it’s taken all the way to the bank.

However, in “real life,” everything is not a list. There are, for example, vectors (random-access lists), or dictionaries (association lists). Non-Clojure lisps have these, but Clojure makes them first-class and ergonomic. This is the thing about Clojure that took me the longest to like, because I really like the “everything-is-a-list”-ness of Lisp. But the four basic data types of Clojure—the list (yay!), the vector, the hash-map, and the set—are well-chosen and are treated equally by the core language, which is key to their ergonomics.

No programming language is perfect, of course, and there are some pain points I’ve found with Clojure so far.

Too much syntax

I promise I’m not joking with this one. One thing I really like about Lisp is its uniformity of syntax: it’s all parens and spaces. The only language with less syntax is Forth, as far as I know.

Even though it’s a Lisp (don’t @ me), Clojure has a lot more syntax than say, Scheme. There’s (), [], {}, and #{} for sequences; . and / in symbol names have special meaning; and honestly, a huge turn-off for me for a while was the unquote syntax ~. I really like the symmetry of ` and ,!

However, I admit that I’ve gotten used to the syntax over time, and even appreciate it now (see above). I do wish there were an easier way to move in the ]}]})))}-ness of block ends though.

I don’t know any Java

Clojure makes a big point of being a hosted language, that is, a language that runs on a premade runtime. For OG Clojure, that runtime is the JVM, which by all accounts is a fine and fast runtime. However, I do not know a lick of Java, except that it’s allegedly verbose. These first weeks of using Clojure, I haven’t had a great need to learn Java, but the feeling that I should learn it persists. At least I’ve (mostly) figured out the interop calling convention.

All of this being said, I’m going to stick with Clojure for the time being. It’s fun, fairly easy to use, and with projects like babashka, fast and amenable to scripting. Plus, I figure it’s never a bad idea to get more familiar with the Java ecosystem.

To get more experience than writing a site build system, I’m doing Project Euler in Clojure. Be my Euley friend with this code:

2304741_7MlSvxoUOKyle32IQjYszcAAsJDCVji1
联系我们 contact @ memedata.com