Planck Road Ahead
Planck 2 is currently in beta, and is closing in on a release. The main feature in Planck 2 will be support for Linux and there will be a future blog post about that aspect.
In the meanwhile, I wanted to describe a few of the new features in Planck 2 relative to Planck 1.17.
Async Shell
Thanks to contributions by Jonathan Leonard, the planck.shell
namespace gains the ability to execute long-running shell commands, calling back when complete.
cljs.user=> (require 'planck.shell)
nil
cljs.user=> (planck.shell/sh-async "sleep" "30" prn)
nil
cljs.user=> ;; 30 seconds go by
{:exit 0, :out "", :err ""}
This can be extremely useful when writing scripts given the lack of threads in ClojureScript.
Hi-Res Timer
In Planck 1.17, cljs.core/system-time
is at millisecond resolution:
cljs.user=> (system-time)
1485114862744
cljs.user=> (time (apply + (range 1e7)))
"Elapsed time: 17.000000 msecs"
49999995000000
Planck 2 monkey-patches cljs.core/system-time
with native code returning nanosecond-resolution timestamps:
cljs.user=> (system-time)
182818380.748193
cljs.user=> (time (apply + (range 1e7)))
"Elapsed time: 16.948683 msecs"
49999995000000
Interrupt Forms Generating Output
If you evaluate something like (range)
in a ClojureScript REPL, you are pretty much done. In Planck 1.17, because it is using Fipp, you at least get a stream of integers being printed.
In Planck 2, you can interrupt this stream by hitting Ctrl-C, and you will be returned to the REPL prompt with all of your REPL state intact:
cljs.user=> (def a 3)
#'cljs.user/a
cljs.user=> (range)
(0
1
2
3
4
...
4907
4908
4909
^C
cljs.user=> a
3
This mechanism doesn't work for forms that don't generate any printed output, like (apply + (range))
. This is because it hooks into the underlying print
call to check for Ctrl-C—and thanks to Fipp, large forms result in multiple print
calls.
This has been one of my favorite new features. I've found it to be useful surprisingly often: It works for large output forms (not-necessarily infinite), and I suppose I'm impatient at times, and just want to get back to the REPL prompt.
Source for REPL-defined forms
In Planck 1.17, the source
REPL special only works for def
forms that exist in namespaces that are loaded from source (either on disk, or JARs, or bundled with Planck).
Planck 2 extends this capability to forms interactively entered at the REPL:
cljs.user=> (defn square
#_=> [x]
#_=> (* x x))
#'cljs.user/square
cljs.user=> (square 3)
9
cljs.user=> (source square)
(defn square
[x]
(* x x))
nil
This works even if you redefine a def
that came from source (showing your REPl-entered definition). And, in that case, if you subsequently require
the namespace, passing the :reload
flag so that the def
reverts to the on-disk form, source
will reflect that.
Planck Classpath Environment Variable
If you have libraries that you frequently use, you can put them in PLANCK_CLASSPATH
and they will always be available, unless specifically overidden by -c
.
I find this useful in order to always have Andare always available in order to mess with core.async
or a locally-built copy of the port of test.check
to self-hosted ClojureScript available for use when messing with spec.
Trying it Out
If you'd like to try Planck 2 before it is released, on macOS, just do
brew install --devel planck
On Linux it is fairly easy as well, just clone the repo, ensure you have the needed deps, and build it:
cd planck
./script/build