Recently I've used babashka/fs a little bit, here are some quick notes for it:
Path vs File. Use Path whenever possible, according to this SO answer to "Java: Path vs File". This is actually Java related. It's ok to use a path as a key for a clojure map. At my first try, I somehow came to the conclusion that it's not ok, while I was refactoring the live reload for clay.
[Read More]
Doing Unit test in Clojure Is Easy
While refactoring the live reload feature of Clay, I realized I'd better break long functions into smaller and functional ones (as many as I can), which is also a common practice in the clojure community.
Small pure functions not only are easy to verify on the development process (using a REPL), but also are easy to test. And unit tests are easy to write in clojure, just use deftest from clojure.
[Read More]
clj-async-profiler Rocks
While developing the live reload feature for Clay, a minimalistic Clojure tool for data visualization and literate programming, I found that it constantly takes ~1 minute for beholder to watch a directory. After some code inspect, I was still having no idea why it happened.
So I decided to use a profiler to find out what's going one under the hood, and Google immediately took me to clj-async-profiler. It's easy to set up following its basic usage docs:
[Read More]
Adding Clojure Dependencies from the Command Line
While debugging a live reload issue of Clay a few days ago, I learned from Markus Agwin that we can actually add dependencies on the fly from the command line, just like this: clj -Sdeps "{:deps {org.scicloj/clay {:mvn/version \"2-beta21\"}}}".
Even better, we can add dependency from a Git repo and specify the commit hash: clj -Sdeps "{:deps {io.github.scicloj/clay {:git/url \"https://github.com/scicloj/clay.git\" :git/sha \"35a46541db66ae6b4e1af628b7c24c42d3be418f\"}}}", which is really helpful for experimenting and verifying things.
[Read More]
Bitten by Lazy Sequence of map
While impletenting the live reload feature for Clay a few weeks ago, unfortunately, I was bitten by the laziness of map. It seems quite obvious we all know that its result is a lazy sequence, but I just can't help fall into the "trap".
At that time I was adding a vector to keep track of all beholder instances watching file changes in user specified directories. So then when it's time to stop all the watchers, I used something like to achieve the goal:
[Read More]
Anonymous Functions in Thread Macros
While adding the live reload feature to Clay, I encountered a problem of applying anonymous functions to thread macros. For example, below is a simple snippet trying to wrap the input directory as a vector with the help of thread macro, but surprisingly, it errors out. After some searching, I figured out that I need to put the anonymous function into another pair of parentheses:
(-> "/tmp/" #(if (vector? %) % [%])) ;; => Syntax error (ClassCastException) compiling fn* at (simple4all.
[Read More]
Start a Clojure nREPL in the Command Line for Cider
While troubleshooting and fixing a live reload bug in Clay today, which requires to start a minimal Clojure environment, I figured out how to start a nREPL from the command line. Instead of using M-x cider-jack-in-clj directly from Emacs, actually we can manully bring up an nREPL with this: clj -Sdeps "{:deps {org.scicloj/clay {:mvn/version \"2-beta21\"} cider/cider-nrepl {:mvn/version \"0.50.2\"}}}" -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware]" (The clay part is only necessary for this debugging), and then connect to this nREPL using the Emacs command M-x cider-connect-clj.
[Read More]
Clojure reduce: one case for text processing
As a practice, I managed to illustrate Clojure files using illustrate.clj, but my original idea was to annotate org-mode files of blogs. It's not uncommon that a blog post has some code snippets.
But it missed the feature until last night, as I wasn't sure how to implement it appropriately before and didn't have enough time.
For example, I may have an org-mode like this:
sum of two numbers: #+begin_src clojure (+ 1 2) #+end_src I want to have a result comment ((;; => 3)) after each top-level form after using illustrate.
[Read More]
illustrate.clj to Illustrate Clojure Snippet
To get my hands dirty with Clojure, I am trying to find or implement Clojure's string functions in the sense of Python. Python has powerful string APIs, and I also want to see how powerful Clojure could be in this field. That would be interesting.
As shown in the cheatsheet, Clojure has implemented most of them, and there are some that I have to implement myself, like title-case.
Along the way, I found it was a little cumbersome to append the evaluation result and the result of calling them, for example,
[Read More]
String Title Case in Clojure
These days I like to write scripts for some tasks in Python instead of shell. One important reason I think that's because Python is powerful at string manipulation.
Recently I'm learning Clojure, and I'm trying to find similar ways in Clojure, one of them is s.title() for getting a title-cased version of a string. For example,
>>> ' Hello world'.title() ' Hello World' How to do that in Clojure? To make the problem simple, let's assume that the input string only has letters and spaces, that is, [a-zA-Z ] in regex pattern.
[Read More]