hlship

Joined 10 years ago

Karma
163
Submissions
45
Member since
May 3
Senior Staff Software Engineer at NuBank NA.

Doing all the Clojure.

Remember Apache Tapestry? That was me.

View on Hacker News

Recent submissions

Comment · 1 year ago
I've been working in Clojure now for about 12 years. Maybe 12+ years of Java prior to that.

I've created some great apps, and great libraries (in both Clojure and Java).

I often describe Clojure as "the least worst programming language", which is an off-handed complement, but I think accurate. Things you don't like can generally be fixed (at least locally) using macros and libraries. The core is strong, a good basis for building things ... and as described all over this thread, stable.

As you master your tools, you gain a level of speed and precision in your work that I have not found elsewhere. The REPL-oriented workflow is a central value proposition in Clojure, and many features (and a few limitations) of the language exist to properly support it.

Working in Clojure feels like I'm working "with" my code, molding it like clay. My prior experiences in Java and Objective-C were so much slower, with long code-compile-test-debug cycles that are compressed down to instantaneous responses in the running REPL.

Comment · 1 year ago
The cli/deps.edn tooling is different from Leiningen, and far, far less complicated IMO. I've written a good number of Leiningen plugins and it was always brutal to get anything to work properly, especially in combination with other plugins.

Leiningen attempts to be everything to everyone in terms of building, testing, and packaging Clojure code. It's Clojure's version of Maven.

cli/deps.edn effectively reduces things down to a) what should be on the classpath and b) what should get executed. Working inside an IDE? You just want it to download the dependencies and build a classpath. Running nREPL? Add that to the classpath, and set the starting namespace to start nREPL. Packaging an application? Run dependencies that do that work, based on the clojure.tools.build library.

I was there myself; I used Leiningen and didn't take the time to figure out deps.edn --- until I did, saw the light, and converted all of Walmart's projects to use deps.edn, which greatly sped up our build and improved our dev experience.

Comment · 1 year ago
~ > time bb -e '(println "Hello World")' Hello World bb -e '(println "Hello World")' 0.01s user 0.03s system 18% cpu 0.212 total

bb is Babashka: a pre-compiled (using Graal), interpreted, scripting language version of Clojure.

In terms of realistic work:

~/workspaces/github/pedestal/tests > time clj -X:test {:in user/eval2321, :line 13, :thread "main", :dev-mode? false}

Running tests in #{"test"}

...

Testing io.pedestal.test-test

Ran 391 tests containing 1180 assertions. 0 failures, 0 errors. clj -X:test 30.15s user 2.04s system 203% cpu 15.838 total ~/workspaces/github/pedestal/tests > java -version openjdk version "23.0.2" 2025-01-21 OpenJDK Runtime Environment Corretto-23.0.2.7.1 (build 23.0.2+7-FR) OpenJDK 64-Bit Server VM Corretto-23.0.2.7.1 (build 23.0.2+7-FR, mixed mode, sharing)

That's on my Intel MacBook Pro. Pedestal's test suite loads a good amount of Java classes and Clojure namespaces.

To make things faster, there's ahead-of-time compilation (which basically captures the read-eval-create-bytecode part of loading a Clojure namespace as Java .class files that can be packaged into your app).

Comment · 1 year ago
It's based on unification, like a Prolog. It does backtracking, like a Prolog. It has something akin to Prolog "cuts". It's equally not Markdown. What it is, is the sensibilities of Prolog (for parsing words into player intent - actions) and for implementing a world model, and for inferring facts from other facts ... and also the text-foremost sensibility of Markdown.

I love it. I've put considerable effort into building tools around it, and to building up a library of extensions.

Comment · 1 year ago
That was my frustration as well; and it comes up in discussions. Simple to medium complex things are easy in Inform7, but when you start hitting the edges, you find out that its expressive English-like syntax is in the uncanny valley and exactly how you phrase things becomes vitally important and difficult to discern, even from the mounds of documentation it generates from your story file and from the standard library and extensions.
Comment · 1 year ago
Comment · 1 year ago
Comment · 2 years ago
Comment · 2 years ago
Comment · 2 years ago
Nubank purchased Cognitect (the consulting company behind Clojure) in 2020, as well as Platformatec (employers of Jose Valim); the latter was for access to Platformatec's project management expertise (see https://building.nubank.com.br/tech-perspectives-behind-nuba... there is no Elixir code running at Nubank AFAIK.

There is Python on the "other side" of the ETL pipeline, but everything user-facing is (again AFAIK) Clojure on the backend and TypeScript in the Android and iOS apps.

Comment · 2 years ago
In traditional databases, only the database engine has a scalable view of the data - that’s why you send SQL to it and stream back the response data set. With Datomic, the peer has the same level of read access as the transactor; it’s like the database comes to you.

In this read and update scenario, the peer will, at its leisure, read existing data and put together update data; some careful use of compare and set, or a custom transaction function, can ensure that the database has not changed between read and writes in such a way that the update is improper, when that is even a possibility - a rarity.

At scale, you want to minimize the amount of work the transactor must perform, since it so aggressively single threaded. Off loading work to the peer is amazingly effective.

Comment · 2 years ago
It's actually quite a bit more than REBL; the description downplays something quite significant ... it can run as a client against a running Clojure in a separate process. Although that sounds simple ("it's just data") the number of edge cases involving everything from infinite lists, to dealing with functions as elements in the data, to differences in what's on the classpath between client and server, has impacted the implementation.
Comment · 2 years ago
That's not a very helpful, or accurate, comment.
Comment · 2 years ago
Babashka has unlocked so much power for me. Clojure and the JVM simply aren't set up for rapid start up, Babashka is instant. Bash scripting is alien, ugly, and hazard prone for me - Babashka makes it totally familiar, since it's virtually identical to Clojure. That is the definition of "have my cake and eat it too".

The end result is that anything the least bit non-trivial becomes a Babashka script, and I've created tools containing dozens (or potentially, hundreds) of sub-commands.

Joyful is the correct adjective.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton