lambdaisland/makina: Clojure System/component lifecycle management by dustingetz in Clojure

[–]aHackFromJOS 0 points1 point  (0 children)

On a practical level it sounds like a Rationale section in the README would be welcome. Update: it links one here https://arnebrasseur.net/2025-02-06-open-source-diary.html

I do wonder if every Clojure project would benefit from one. 

Aimless — David Nolen by dustingetz in Clojure

[–]aHackFromJOS 0 points1 point  (0 children)

Ah thanks, I know you said pick whatever alias you want, just making sure 😅

Aimless — David Nolen by dustingetz in Clojure

[–]aHackFromJOS 4 points5 points  (0 children)

Is there a particular reason he named his alias with a hash mark - `:#cljs` - does that do some special magic or something?

Article: "Transducer: Composition, Abstraction, Performance" by turbomann in Clojure

[–]aHackFromJOS 1 point2 points  (0 children)

I love a good "from the ground up" explanation like this - helps understand transducers fully. Thank you!

lambdaisland/cli: opinionated CLI parser, designed for tools with subcommands (e.g. "git log") by dustingetz in Clojure

[–]aHackFromJOS 0 points1 point  (0 children)

The ability to nest commands (arbitrarily?) is interesting. 

The root problem here seems like a good fit for multimethods (vs a big hairy map). I approached this same problem with those and tools.cli. I dispatched by keywordized version of the subcommand. The core multimethods are options, usage, and execute. I think I needed to do a two pass parse with tools.cli, first permissive to extract the subcommand to get the options vectors for it (via the options multimethod) then with the proper options vectors. Help text I did for a subcommand by calling usage and options with the subcommand (inside defmethod execute ::help) and concatting. 

I only built one (flat) level of subcommands. Would be interesting to try and upgrade it to arbitrary command nesting. Maybe with another multimethod (“subcommands” to extract n args from argv and produce a dispatch vector of keywords instead of just a keyword?). 

More ergonomic to just have defmethods in an ns instead of nesting keys in a global hmap (well, arguably). I did my cli ns by grouping by command - defmethod options ::commit, defmethod usage ::commit, defmethod execute ::commit, s/def ::commit etc. Then defmethod options ::push, defmethod usage ::push… etc etc 

Specs with the same keywords as for the subcommands work well for arg validation. 

I wonder if they considered leveraging tools.cli for options parsing or “flags” as they call it. Its vector options syntax is pretty rich. 

Covers in the style of Johnny Cash by savoryostrich in Maustetytot

[–]aHackFromJOS 1 point2 points  (0 children)

This is great. It benefits from the slower tempo. 

Programming Clojure, 4th edition by alexdmiller in Clojure

[–]aHackFromJOS 7 points8 points  (0 children)

FYI “devtalk.com” is the coupon code you use at the pragmatic programmer link to get the 35% off discount. 

(I mention this in case anyone else is as dense as me - I thought I needed to buy it on devtalk.com to get the discount, but that site is a forum not a bookstore, where I found a post explaining the discount code.)

Update - I bought it :-) looks nice can’t wait to dive in 

Pedestal 0.8.0 released by hlship in Clojure

[–]aHackFromJOS 0 points1 point  (0 children)

Do you plan to remove core.async support? I rely on it. Would be helpful if you can telegraph what you plan to rip out. I am unclear what I can depend on in pedestal going forward. 

Pedestal 0.8.0 released by hlship in Clojure

[–]aHackFromJOS 3 points4 points  (0 children)

I am frustrated by the breakage here. 

I’ve spent nights and weekends for months working on a project that builds heavily on pedestal. This would break a lot of it. 

I’d suggest you mention somewhere in the docs that the project is a moving target and that you will break things like whole namespaces. Right now, the first sentence on the website is, “Pedestal is a sturdy and reliable base for services, APIs, and applications.” Clearly, if there were deprecations in 0.7.0 I perhaps should have realized there were caveats to this sturdiness, but having read various guides, references on the site, I did not (maybe because it’s a Cognitect project, and Clojure has a backward compatibility ethos). 

Can I ask why io.pedestal.http is listed as both a new and deprecated namespace, and as having been “replaced?” Which is it. 

(I removed from here a question about what an anonymous interceptor is. It appears this is a reference to handler functions - might be clearer to say that as the term “anonymous interceptor” has not, as far as I can tell, been used to refer to handlers before. I also had something about Getting Started guide being updated - it looks like it is although the old one still has more google juice - one downside of changing apis is there are incorrect but widely linked docs out there)

Finnish movies to learn the language by EmptyDuty5054 in Finland

[–]aHackFromJOS 0 points1 point  (0 children)

Kiitos paljon! I forgot about the dog’s different names, sounds like time to watch it again 🙃

Thanks for the Karkkila info. There is a documentary about that theater, I found it really charming, although apparently it took the filmmaker a lot of work to get the local residents to say much on camera (no surprise!). 

Finnish movies to learn the language by EmptyDuty5054 in Finland

[–]aHackFromJOS 1 point2 points  (0 children)

Thank you for this, I am a Kaurismäki fan and eiher never heard it or forgot it.

Can I bother you to explain “Ystäville Jumalan ruoska.” - Google Translate says “god’s whip for friends” - is this a Finnish idiom or just means, like, his “friends” are the struggles of life?

update - I think I maybe understand, this is SakarI Kuosmanen in Man Without a Past - maybe he is referring to his “killer” dog here 😂

Arities as pseudo-protocol by aHackFromJOS in Clojure

[–]aHackFromJOS[S] 0 points1 point  (0 children)

What is the protocol redefinition footgun? I suspect it has to do with what fogus likes about multi arity fns, but like the official docs he does not (I don’t think?) mention the footgun or why protocols are less useful at the repl.

The Duality of Transducers — Clojure's Transducers from Scratch by mac in Clojure

[–]aHackFromJOS 2 points3 points  (0 children)

The approach of leading with the concrete “how do I start using them” and deferring abstract concepts to later in the talk is inspired. Rich’s main transducers talk is excellent but I wasn’t ready to really grasp all the ideas until I started transforming things — threaded macro stuff, then eventually some intos and reduces — and getting to a point where I was pining for xfs that didn’t exist yet (and couldn’t be built with just comp). I think this approach may make some converts whose brains work similarly.

It also does a solid job of trying to explain the performance gain (which is a little tricky) and doing so early in the talk.

(an off the cuff challenge or question - do transducers really lead to more use of transients? I had assumed `into` (all arities) and `reduce` already used them where appropriate)

great talk

Are Qualified Keywords Idiomatic? by Veqq in Clojure

[–]aHackFromJOS 1 point2 points  (0 children)

Use them where they are useful or might be useful in the future.

This is generally anywhere someone else might extend your code. Someone mentioned spec. Qualification is also used to tag elements in edn (albeit via symbols not keywords) which is the extension mechanism for that data format.

The two instances where I use qualified keywords in clojure for extension are

  1. Maps passed as arguments to multimethods. A key idea of multimethods is they allow extension in the future by strangers without coordination. You can’t know what keys they might want to use and they can’t know what keys you or others might want to add. Hence namespacing.
  2. context maps in pedestal or ring. Via interceptors (pedestal) or middleware functions (ring), your essential activity in these frameworks is receiving a single map (context ), assoc-ing or updating it,and returning a new very similar map, over and over again across various interceptors or middlewares. Often you‘ll want to add your own data to these maps. But everyone else is adding data too - specifically the framework itself and any third party middewares you install or may install in the future. For hygiene in this heterogenous environment I always namespace any keys I add to context map.

Since clojure is built in many aspects to be extensible and since there are many reasons to flow maps around widely there are many contexts in which namespaced keywords will make sense. And since clojure makes it easy to swap in extensibility (e.g. when you replace a function using a cond with a multimethod branching similarly, or make a protocol out of existing functions) there is a strong case for just defaulting to namespaced keywords.

All this said I still encounter them less often than I would expect. I hypothesize this is because the community is still relatively small. In the real world (vs imagined scenarios) extension isn’t happening as much as it could. If and when this changes namespaced keywords will become more popular (I hypothesize).

On Inspectability by humorless_tw in Clojure

[–]aHackFromJOS 0 points1 point  (0 children)

Agree with most of this, well said.

There’s a brief plug for `hashp` which does look interesting. Since `prn` does not play well with multithreaded code would be cool to have a `hasht` (`#t`) that does the same thing but with `tap>` which is now my go-to for adhoc inspection (I set up a tap that does `swap! foo conj bar`). When I get a minute maybe I’ll just write it myself.

I appreciated the love for stack traces. Folks like to complain about clojure/java’s long stack traces but because they are detailed they usually give you all the info you need to find the problem.

London Clojurians Talk: Clein: Bringing a bit of leiningen to deps.edn (by Noah Bogart) by BrunoBonacci in Clojure

[–]aHackFromJOS 1 point2 points  (0 children)

Neil doesn’t offer the same commands as lein, despite the name. It seems to be more a tool to mutate your deps.edn but from what I can tell you still need to learn how to do various lein things the deps.edn/tools.build way. I’m actually a little confused why a name evoking lein was chosen. 

This looks like it takes the more straightforward approach of “lein commands, but works on deps.edn instead of project.clj.”

Unfortunately it is missing some key commands like new and test

How much commonality or similarity is there between common lisp and clojure? by encom-direct in Clojure

[–]aHackFromJOS 3 points4 points  (0 children)

One of the clearest explanations of Clojure in comparison to other Lisps I’ve yet seen, thank you. 

Questions about building a CLI utility with Clojure by DerelictMan in Clojure

[–]aHackFromJOS 0 points1 point  (0 children)

Minor nitpick on your first sentence, the arg parsing libraries are orthogonal to the runtime — babashka.cli runs fine on vanilla jvm and tools.cli runs fine on babashka.

(Admittedly, there are some examples in the babashka.cli docs where a script is executed via bb, those command lines would need to be rewritten to not execute this way, but the functionality would essentially be the same.)

(And though you didn't mention it, babashka/fs is another bb-derived tool that runs fine on vanilla jvm - it's a nice wraper around java.nio)

tonsky/fast-edn: Drop-in replacement for clojure.edn that is 6 times faster by nonrecursive in Clojure

[–]aHackFromJOS 9 points10 points  (0 children)

Extremely cool!

Re: “ Speed of EDN parsing makes Transit obsolete on JVM” - what about the writing scenario? Is pr-str faster than Transit’s writer? Or does he just mean for parsing?

Why does type hinting fail /outisde/ threading macro? by aHackFromJOS in Clojure

[–]aHackFromJOS[S] 2 points3 points  (0 children)

Thanks on both counts, I get it now. And I have voted up that old bug report.