Fork me on GitHub

Got to go have a tooth extracted in a couple of hours :( anyone having a worse afternoon? I see lots of ice cream and beer in my immediate future tonight.

Alex Miller (Clojure team)20:01:51

I think you've just noticed the ever ongoing surge of mini lisps; it doesn't really stop

😂 3

yeah, there have been toy lisps on a pretty regular schedule since lisp


one of my favorites lately is fennel, janet, from the same original author, is pretty cool too

eccentric J23:01:14

Yes! I love fennel, it’s been a ton of fun hacking on spacehammer with it.

Alex Miller (Clojure team)20:01:42

I mean this is already the 3rd or 4th from Tim :)


i miss him being in the community


what happened?

eccentric J23:01:45

To put it as mutually respectful and briefly as I am able: Tim is in that class of devs who has strong opinions about language design\contribution since he is also a language designer. He holds conflicting ideas in how the contribution process to core should operate.


His Clojure tutorials live on, some good stuff in there

👍 3

accidentally hit the "sort lines" button in my text editor... what great code popped out of that

😂 3

alphabetically-oriented programming


if your codebase isn't stable under sort, are you really a programmer?


if you use FP you could also use uniq after the sort :D


is it a stable sort?


FP stands for fixed point. (= code (sort code))


ITYM (comp (partial apply =) (juxt identity sort))


"You haven't mastered a tool until you understand when it should not be used." – Kelsey Hightower
I stumbled upon this quote and it got me thinking. What are some things you wouldn’t recommend Clojure for? What is Clojure not so good at or when shouldn’t you use Clojure?


if your primary constraints include • low memory usage • predictable response time • high numeric throughput • fast startup • static assurances about data types you probably don't want clojure various experts might disagree about how many you need before it's a definite no, hopefully none would use clojure when checking all of the boxes

🙏 6

Is the predictable response time shortcoming simply due to GC or sth else?


not just gc, but the degree to which nearly everything you do in clojure uses gc

👀 3

Thanks! I've long wondered if that can be addressed somehow without boiling the oceans. Perhaps if one didn't use clojure.core, and similarly refrained from using most libs out there, one could get a Java-with-clojure-syntax? e.g. (refer-clojure :only []) and for every function you intend to pull/reimplement, review carefully if suits the perf budget


it's hard, because the core design features that make clojure (and most lisps) so elegant tend to increase gc pressure

👍 3

there was an old lisp, which attempted to offer lispy syntax / macros without the overhead of gc, I had some fun playing with it for a while but in the end it was just writing c with a weird syntax... let me see if I can recall the name


there are old things like which attempt to basically bake in reference counting


back in the day I saw some discussion of "cons free code" for tight loops in common lisp - writing cons free (or really "new" free) in clojure would be an interesting exercise


but you have kind of a stack, gc'ed languages aren't known for predictable response times -> the jvm is not known for predictable response times -> clojure is not known for predictable response times


G1 has made things a lot better on the jvm (and for clojure too)


and to some(small) degree I think C has started to grapple with predictable response times


that's true, and it also reminds me of another source of unpredictability - many algorithms that the jvm optimize amortized time, which trades occasional larger pauses (eg. reallocating a buffer) for throughput


and sometimes the pause length is a bigger problem than the lower throughput was


(many c / c++ libs do a lot of those same average case / worst case tradeoffs, but not as aggressively as the jvm that I know of)


because while gc is part of it, it is really sort of the tower of abstractions you build on, each layer tends to amplify sources of unpredictability, and C and modern hardware are not as close as they once were

💯 3

there was a talk at a conj a while back "clojure: programming with hand tools", which I very much enjoyed which kind of focused on the idea of building things out of simple stuff. but I remember after the talk someone(maybe aphyr?) tweeted something like(I really don't recall the exact words) "if these guys think the jvm is simple I got news for you"

Ben Sless08:01:43

You also have Carp which has Clojure like syntax, an interpreter, but the compiled image uses an ownership model instead of GC


• low memory usage - agree • predictable response time - I agree with the GC argument, but there’s GC solutions on the JVM (azul, etc) which allow for more predictable response times; another option is turning off GC completely and letting the system just crash out of memory (OK for some types of problems)) • high numeric throughput - I would agree about that in terms of community/library support but not because of a fundamental limitation of the language (see ) • fast startup - that’s fair (possibly use ClojureScript?) • static assurances - that’s fair (I would question the “constraint” in the first place, but that’s a whole another discussion 🙂 )

👍 3

@U050KSS8M you can improve the predictability of gc, but consider if your domain was eg. a low power software defined radio - any gc in your main loop is a problem period, and "run until you crash" still uses the allocator which still causes periodic pauses on numeric throughput, it's simply easier to write a java class that crunches numbers efficiently than it is to write clojure code that properly unboxes and eliminates runtime reflection, perhaps I'm too dumb to know how my graph algorithm could have used matrices, but I can tell you it got 32x faster and stopped being a bottleneck when it was replaced by 40 lines of very readable procedural java code


(graphs don't really parallelize / vectorize like matrix math does)


@U051SS2EU good points, I agree; limited Java in the right places can definitely be useful for optimization.


• “fast startup - that’s fair (possibly use ClojureScript?)” Two of the kinda-fast-startup Clojure variants of which I’m aware are and The former is much more like Clojure itself AFAICT, as it’s based on GraalVM, a type of JVM. The latter is an interpreter written in Golang. Included in the canonical build is a startup accelerator I wrote, which seems to make it fairly “competitive” with babashka, though perhaps using slightly less resources (probably due to having no JIT or equivalent whatsoever). Someday I hope to investigate whether startup time can be reduced even further, as it still seems slower than necessary to me.


that's true, and they introduce their own tradeoffs - they are not appropriate for the kind of high throughput app that clojure excells with


eg. you can use cljs instead of clj in an aws lambda, but it only saves you total time if your job is short and computationally simple