内容简介:A few years back, I wroteThat said, as that article discussed, Clojure is aThere is one area in which Clojure and Python seem to have a gulf between them, for a seemingly minor (but, in practice, major) technical reason. Clojure, being a JVM language, inhe
A few years back, I wrote Clojonic: Pythonic Clojure , which compares Clojure to Python, and concluded:
My exploration of Clojure so far has made me realize that the languages share surprisingly more in common than I originally thought as an outside observer. Indeed, I think Clojure may be the most “Pythonic” language running on the JVM today (short of Jython, of course).
That said, as that article discussed, Clojure is a very different language than Python. As Rich Hickey, the creator of Clojure, put it in his “A History of Clojure” :
Most developers come to Clojure from Java, JavaScript, Python, Ruby and other OO languages. [… T]he most significant […] problem [in adopting Clojure] is learning functional programming. Clojure is not multiparadigm, it is FP or nothing. None of the imperative techniques they are used to are available. That said, the language is small and the data structure set evident. Clojure has a reputation for being opinionated, opinionated languages being those that somewhat force a particular development style or strategy, which I will graciously accept as meaning the idioms are clear, and somewhat inescapable.
There is one area in which Clojure and Python seem to have a gulf between them, for a seemingly minor (but, in practice, major) technical reason. Clojure, being a JVM language, inherits the JVM’s slow startup time, especially for short-lived scripts, as is common for UNIX CLI tools and scripts.
As a result, though Clojure is a relatively popular general purpose programming language — and, indeed, one of the most popular dynamic functional programming languages in existence — it is still notably unpopular for writing quick scripts and commonly-used CLI tools. But, in theory, this needn’t be the case!
If you’re a regular UNIX user, you probably have come across hundreds of scripts with a “shebang”
, e.g. something like #!/usr/bin/env python3
at the top of Python 3 scripts or #!/bin/bash
for bash scripts. But I bet you have rarely, perhaps never, come across something like #!/usr/bin/env java
or #!/usr/bin/env clojure
. It’s not that either of these is impossible
or unworkable
. No, they are simply unergonomic
. Thus, they aren’t preferred.
The lack of ergonomics stems from a number of reasons inherent to the JVM, notably slow startup time and complex system-level classpath/dependency management.
Given Clojure’s concision, readability, and dynamism, it might be a nice language for scripting and CLI tools, if we could only get around that slow startup time problem. Could we somehow leverage the Clojure standard library and a subset of the Java standard library as a “batteries included” default environment, and have it all compiled into a fast-launching native binary?
Well, it turns out, someone else had this idea, and went ahead and implemented it. Enter babashka .
To quote the README:
Babashka is implemented using the Small Clojure Interpreter
. This means that a snippet or script is not compiled to JVM bytecode, but executed form by form by a runtime which implements a sufficiently large subset of Clojure. Babashka is compiled to a native binary using GraalVM
. It comes with a selection of built-in namespaces and functions from Clojure and other useful libraries. The data types (numbers, strings, persistent collections) are the same. Multi-threading is supported ( pmap
, future
). Babashka includes a pre-selected set of Java classes; you cannot add Java classes at runtime.
Wow! That’s a pretty neat trick. If you install babashka
— which is available as a native binary for Windows, macOS, and Linux — you’ll be able to run bb
to try it out. For example:
$ bb Babashka v0.1.3 REPL. Use :repl/quit or :repl/exit to quit the REPL. Clojure rocks, Bash reaches. user=> (+ 2 2) 4 user=> (println (range 5)) (0 1 2 3 4) nil user=> :repl/quit $
And, the fast startup time is legit. For example, here’s a simple “Hello, world!” in Clojure stored in hello.clj
:
(println "Hello, world!")
Now compare:
$ multitime -n 10 -s 1 clojure hello.clj ... Mean Std.Dev. Min Median Max user 1.753 0.090 1.613 1.740 1.954 ... $ multitime -n 10 -s 1 bb hello.clj ... Mean Std.Dev. Min Median Max user 0.004 0.005 0.000 0.004 0.012 ...
That’s a pretty big difference on my modern machine! That’s a median startup time of 1.7 seconds using the JVM version, and a median startup time of 0.004 seconds — that is, four one-thousandths
of a second, or 4 milliseconds — using bb
, the Babashka version! The JVM version is almost 500x slower!
How does this compare to Python?
$ multitime -n 10 -s 1 python 3 hello.py ... Mean Std.Dev. Min Median Max user 0.012 0.004 0.006 0.011 0.018 ...
So, bb
‘s startup is as fast as, perhaps even a little faster than, Python 3. Pretty cool!
All that said, the creator of Babashka has said, publicly:
It’s not targeted at Python programmers or Go programmers. I just want to use Clojure. The target audience for Babashka is people who want to use Clojure to build scripts and CLI tools.
Fair enough. But, as Rich Hickey said, there can be really good reasons for Python, Ruby, and Go programmers to take a peek at Clojure. There are some situations in which it could really simplify your code or approach. Not always, but there are certainly some strengths. Here’s what Hickey had to say about it:
[New Clojure users often] find the amount of code they have to write is significantly reduced, 2—5x or more. A much higher percentage of the code they are writing is related to their problem domain.
Aside from being a useful tool for this niche, bb
is also just a fascinating F/OSS research project. For example, the way it manages to pull off native binaries across platforms is via the GraalVM native-image facility
. Studying GraalVM native-image is interesting in itself, but bb
makes use of this facility and makes its benefit accessible to Clojure programmers without resorting to complex build toolchains.
With bb
now stable, its creator took a stab at rewriting the clojure
wrapper script itself in Babashka. That is, Clojure programmers may not have realized that when they invoke clojure
on Linux, what’s really happening is that they are calling out to a bash script
that then detects the local JVM and classpath, and then execs out to the java
CLI for the JVM itself. On Windows, that same clojure
wrapper script is implemented in PowerShell, pretty much by necessity, and serves the same purpose as the Linux bash script, but is totally different code. Well, now there’s something called deps.clj
, which eliminates the need to use bash and PowerShell here, and uses Babashka-flavored Clojure code instead. See the deps.clj rationale in the README
for more on that.
If you want a simple real-world example of a full-fledged Babashka-flavored Clojure program that does something useful at the command-line, you can take look at clj-kondo
, a simple command-line Clojure linter
(akin to pyflakes
or flake8
in the Python community), which is also by the same author.
Overall, Babashka is not just a really cool hack, but also a very useful tool in the Clojurist’s toolbelt. I’ve become a convert and evangelist, as well as a happy user. Congrats to Michiel Borkent on a very interesting and powerful piece of open source software!
Note : Some of my understanding of Babashka solidified when hearing Michiel describe his project at the Clojure NYC virtual meetup . The meeting was recorded, so I’ll update this blog post when the talk is available.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
社交电商
[美] Stephan Spencer(斯蒂芬.斯宾塞)、[美] Jimmy Harding(吉米.哈丁)、[美] Jennifer Sheahan(詹尼弗.希汉) / 谭磊 / 电子工业出版社 / 2015-3 / 69.00元
你想要在互联网上赚钱吗?想要做好电子商务吗?那么你一定不能忽视社交媒体的力量。不管你想要营销的是实物商品、电子类产品还是本地的服务,这本书会教你怎么做。 《社交电商》全面介绍形形色色的社交媒体以及如何利用这些社交媒体来为你的企业做好服务。如果你经营得不好,在社交媒体上散发出的只是噪声而不是真正的信息。 而如果做得好,社交媒体会成为你最有效的营销工具,帮助你赢得老客户的拥戴,获得新的客户。 ......一起来看看 《社交电商》 这本书的介绍吧!