clojure

amano 2025-10-11T09:39:03.034289Z

Does clojure require nearly full test coverage? Or, is it okay to add tests for critical parts?

amano 2025-10-13T08:31:34.637699Z

I will try minimal unit/property tests. If I need more, I will write more.

gtrak 2025-10-13T20:20:48.684569Z

Game programming is one area where Rust is sometimes counterproductive, actually. https://deadmoney.gg/news/articles/migrating-away-from-rust I think doing that with any immutable discipline is going to be too hard sometimes.

gtrak 2025-10-13T20:22:12.392769Z

I don't quite get zig, but I like it as a rust cross-compile linker.

gtrak 2025-10-13T20:28:49.453889Z

I think zig is a little better at unsafe low-level coding and not suited at all for high level coding

gtrak 2025-10-13T20:36:40.925229Z

Some people prefer to pass an allocator around and complain that rust can implicitly panic on an OOM. And that is just not something I'm concerned about at the moment, but I guess zig is designed around no hidden allocations better.

gtrak 2025-10-13T20:37:18.465869Z

I spend no time thinking about manual memory management.

gtrak 2025-10-13T20:43:00.066699Z

Everything is on the stack unless it's wrapped by a reference type, usually for cocurrent shared state. Also use references in function args for big things, and try to avoid calling clone(). If you're fighting with the borrow checker maybe reevaluate if the design is wrong. That's pretty much it.

gtrak 2025-10-13T20:45:00.035919Z

Strings, vecs and other days structures do their own heap stuff

gtrak 2025-10-13T21:01:05.292229Z

If you're writing good clojure already, you likely can live without reference cycles and GC. Reference-counted smart pointers are sufficient.

amano 2025-10-14T03:43:43.792809Z

I don't like Rust. I like clojure. This slack community is a wrong place to advertise Rust. Clojure programmers want simple languages which Rust is not. I read counter arguments like "garbage collectors just hide complexity under the rug". I prefer garbage collector to rust's compilation-time memory management which forces programmers to manage memory manually. If I didn't like garbage collector, I might as well write web services in Zig. People used to write web applications in C and C++. That's a step backward. Writing a web application in a low-level system programming langauge is a step backward. I don't want to deal with low-level concerns all the time. I don't need to aim for minimal memory consumption and maximum performance for a web application. That's not my use case. Even python is enough to serve my use case. There is a reason that people are tired of Rust evangelism. Rust evangelists push Rust where it doesn't belong, such as high-level web programming and scripting. Clojure programmers are here precisely because they don't want to deal with low-level concerns all the time. At least, clojure programmers don't push clojure where it doesn't belong. If I didn't use clojure, I would rather use python and javascript than rust. Rust would be my last choice for web development.

amano 2025-10-14T03:55:29.435649Z

If I used Rust for web development, I will need to use async rust which forces me to learn rust memory management as well. Async rust is painful at this moment. I want garbage collector. I'm okay with world-stopping GC from time to time. Why would I want to torture myself with Rust for web development?

amano 2025-10-14T04:04:20.907649Z

I ditched Haskell after finishing a 7k LoC haskell program because of its complex type system and cumbersome monad transformers. I don't want to go back to that level of complexity again unless I absolutely have to. I hate the complexity that comes with high levels of type safety. Garbage collector provides memory safety at the cost of stopping the world from time to time. My use case doesn't require ultra low latency. I don't want to pay for safety at the cost of simplicity. I would note that Rust doesn't prevent memory leaks, either.

gtrak 2025-10-14T04:08:41.449589Z

I'm more trying to explain what it's actually like to use it than I am trying to persuade you. But I guess the dead horse is beaten enough.

gtrak 2025-10-14T04:11:08.382599Z

I created a reddit thread, which is probably a better place to have this discussion: https://www.reddit.com/r/rust/comments/1o4fmlg/rust_is_a_lowlevel_systems_language_not/

amano 2025-10-14T04:11:23.283799Z

I also prefer JVM's virtual thread to rust async. I don't like async which colors functions. Rust can't have virtual threads because it doesn't have a runtime.

gtrak 2025-10-14T04:12:24.961189Z

Virtual threads are pretty cool!

amano 2025-10-14T04:13:48.824679Z

Rust also doesn't enforce persistent data structures by default. Why would I want to ditch clojure for something that doesn't come with persistent data structures by default?

amano 2025-10-14T04:14:18.709109Z

It sounds like a huge step backward.

gtrak 2025-10-14T04:16:23.329099Z

I changed my mind on those when I did full-time work in ocaml. Stack-allocation is faster than what the JVM does, starting with the assumption that everything's a heap object but some can get optimized to stack. Most concrete data structures are small enough to fit in cache and if it's bigger than that, you probably want a database anyway. Persistent data structures are for medium-size-data, which is not really in the programs I write. You likely don't have very wide maps, do you? You have high-levels of nested trees with low cardinality, so you're not benefitting from the logN.

gtrak 2025-10-14T04:16:52.497559Z

send the pitchforks

amano 2025-10-14T04:16:58.651819Z

Persistent data structures are for peace of mind. I get weird bugs without persistent data structures even in small programs.

gtrak 2025-10-14T04:17:32.097679Z

oh, I mean, immutable data is great! I just don't care for the HAMT tries

gtrak 2025-10-14T04:17:41.427729Z

just make copies

amano 2025-10-14T04:18:00.803249Z

And, you give up the performance advantages of Rust by making copies.

amano 2025-10-14T04:18:27.888759Z

You are merely addicted to Rust. I'm not addicted to clojure or anything.

gtrak 2025-10-14T04:18:42.365239Z

I was addicted to clojure

amano 2025-10-14T04:19:00.694109Z

To me, clojure is just a boring language I have to get done with and move on from.

gtrak 2025-10-14T04:19:04.742739Z

performance of copies is faster than you'd think if you aren't on a JVM

amano 2025-10-14T04:19:43.777639Z

I think Rust can be fun, but I don't want fun. I want simplicity and utility. Rust is anything but simple.

gtrak 2025-10-14T04:20:19.202299Z

It's a complex compiler, but much simpler at runtime, since there's no runtime

amano 2025-10-14T04:20:42.046579Z

I think you should really go to Rust community if you want to talk about Rust that much.

amano 2025-10-14T04:21:02.816409Z

I would consider Rust if it was a particularly good fit for my use case, but it's not. You are merely trying to use Rust everywhere because it's fun.

gtrak 2025-10-14T04:21:23.758329Z

I think I'm just not making my point clear, but that's ok. ¯\(ツ)

gtrak 2025-10-14T04:23:52.441569Z

I'm just asking you to expand your view, for example there's some fun nuggets in that reddit thread: > (some guy's) opinion about garbage collection is and has always been that it's a bad resource management solution because it only cares about memory, which is almost always not even the most limited resource on the system, and the only thing that it really does is prevent memory leaks, which are not even undefined behavior, at the cost of not making object destruction and resource deallocation predictable. These facts often force working against the garbage collector itself by implementing strategies to guarantee that even if an object is referenced somewhere, its resources are predictably deallocated, so there's absolutely no benefit in garbage collection that is also not provided by reference counting with weak referencing.

amano 2025-10-14T04:24:09.108149Z

I don't need to expand my view. I just want to write something in a sane manner and be done. The exploration phase was finished a long time ago.

2025-10-14T04:24:19.592049Z

Isn't Rust's whole deal that if you can statically prove that nothing else is mutating the same thing, then mutate away? Which means it would be pretty different in practice in that you'd still be writing mostly imperative code no?

gtrak 2025-10-14T04:24:55.840469Z

You don't have to mutate things if you don't want to. No one is forcing you to use STM in clojure, either.

2025-10-14T04:25:17.916879Z

Sure, but I mean, the main ergonomics of the language would be imperative no?

2025-10-14T04:26:04.425169Z

Like mutable variables, for-loops, while-loops, if/else statements, mutable structs, mutable lists, maps, and so on? Or am I off base?

gtrak 2025-10-14T04:26:58.583599Z

It depends on what you're doing, but I think the imperative parts are stricter than something like java, and it's just a different experience.

amano 2025-10-14T04:28:19.449939Z

I had no problem with janet's garbage collector. It releases memory in a timely manner. I also never had problem with python's garbage collector.

gtrak 2025-10-14T04:28:46.627509Z

ah, python is refcounted!

2025-10-14T04:29:04.706469Z

Well, I know it's not classic OOP like Java, and more uses Trait polymorphism and interfaces. But it seems the experience would be very different from a functional language like Clojure, as it would really just be imperative programming.

gtrak 2025-10-14T04:29:37.115439Z

It's like an unholy marriage of ocaml and C++, I guess. Not quite as FP as haskell, the monads are not in your face at all.

amano 2025-10-14T04:30:35.930379Z

FP doesn't require monad, and monad transformers suck. I prefer STM to monad state transformers.

gtrak 2025-10-14T04:31:03.057079Z

More expressions than statements, eg break is an expression. So is if/else

gtrak 2025-10-14T04:31:26.414909Z

let result = loop {
    if b > 10 {
        break b;
    }
    let c = a + b;
    a = b;
    b = c;
};

1
gtrak 2025-10-14T04:31:32.416029Z

valid

2025-10-14T04:32:15.239469Z

Ya, I guess I see it has let, match, ref, which maybe can make it feel a bit more expression-ish, but I also see statement if, loop, for, mut, return and so on.

2025-10-14T04:33:15.620879Z

lol, what would the result value be? The value of "c" ?

2025-10-14T04:33:39.132449Z

Oh, the value of b when it breaks out of the loop

2025-10-14T04:34:06.577389Z

Not gonna lie, that looks a bit gnarly 😛

gtrak 2025-10-14T04:34:22.388889Z

it'll loop forever unless you hit break, so it works out!

gtrak 2025-10-14T04:34:56.099879Z

What's fun about that one is I just guessed it might work and stumbled into it one day

2025-10-14T04:35:05.300529Z

Ya, but also nothing would stop you from say doing:

mut lol = 0
let result = loop {
    if b > 10 {
        break b;
    }
    let c = a + b;
    mut = c;
    a = b;
    b = c;
};

👍 1
amano 2025-10-14T04:36:07.141439Z

I want to be a businessman. You want to program for fun. We are doing two entirely different things. I already decided to use clojure, clojurescript, and python. There is no point in expanding my view, exploring things, or whatever. I want to focus on my business.

👍 1
gtrak 2025-10-14T04:36:51.079069Z

I'm a professional programmer, not a businessman, that's an interesting point, but I'm not sure clojure is the most pragmatic for founders unless you just know it the best already

amano 2025-10-14T04:37:05.099589Z

I used to write clojure and haskell, and I got fed up with haskell. I already don't like Rust before even learning it because I got fed up with complexity.

gtrak 2025-10-14T04:38:58.283269Z

Neither is rust, tbh. Probably typescript.

amano 2025-10-14T04:39:42.133099Z

I didn't like Raku for its complex syntax. Rust's syntax doesn't look no less complex than Raku's. Rust looks more complex than Scala.

2025-10-14T04:40:02.717599Z

I think when people say Rust and Clojure share similarities, or are more similar than you think. It's because they share a bit of the same ideals. 1. Not into classical OOP 2. Thinks mutation is too hard to track in concurrent/parallel contexts 3. Likes macros But I feel they approach that from opposite sides.

💯 1
gtrak 2025-10-14T04:41:14.421929Z

never heard of raku 👀

amano 2025-10-14T04:41:36.883809Z

Raku is perl's cousin. Perl was also known for complex syntax, but Raku's syntax is just more complex.

2025-10-14T04:42:16.886439Z

But Rust kind of misses on some of Clojure's ideal too: 1. Platforms are the future (hosted nature), access to tons of existing stuff 2. Lisp <-- probably the big one 😛 3. Functional But then Rust also has: 1. Zero-cost abstractions 2. As fast as C++ 3. Can go down to lowest-level

amano 2025-10-14T04:42:53.978199Z

I precisely want to avoid low-level access which increase complexity. The combination of zero-cost abstractions, performance, and low-level access increases complexity.

gtrak 2025-10-14T04:43:21.743289Z

The platform hosted-language thing is a false economy. Java can catch up, clojure struggles to have a killer app that needs to be written in clojure instead of java.

amano 2025-10-14T04:43:41.533399Z

Clojure's killer app is web development. I use clojure where it shines.

gtrak 2025-10-14T04:44:28.390229Z

Kotlin is a JVM language, but it has a standalone native compiler

gtrak 2025-10-14T04:44:35.171359Z

Why did they bother?

amano 2025-10-14T04:44:49.899709Z

They bothered because they are idiots with a lot of money.

🤣 1
gtrak 2025-10-14T04:44:52.711409Z

https://kotlinlang.org/docs/native-overview.html

amano 2025-10-14T04:46:58.656829Z

Even if I had 10 billion dollars, I wouldn't do something like that probably.

amano 2025-10-14T04:48:18.338379Z

If Rust is your choice, then stick to it, but don't talk me into using it. Use Rust for web development, or go fishing. I don't care either way.

amano 2025-10-14T04:49:27.278699Z

Just pick one language, and work on it.

2025-10-14T04:51:13.510139Z

Java can't really "catch up". Unless it too became a functional lisp with a REPL 😛

2025-10-14T04:52:50.007159Z

The reason Kotlin did native I'd imagine is iOS 😛. Because iOS doesn't allow VMs like Python or Java on it.

2025-10-14T05:02:18.105349Z

For me, I'd need a Lisp with good live REPL workflow to consider an alternative. There is Carp, it advertises itself still as very experimental, so I haven't tried it yet. I feel like the "needs to be written in" idea does't really make sense to me. You can kind of write anything in anything really nowadays. The real constraints are more compatibility, like targeting the browser, targeting a game engine, a specific OS, platform, hardware, etc. Certain specific runtime characteristics it's possible some runtimes behave better, super fast startup, crazy small bundles, super low memory footprint, and what not. But in practice you can still make the same app and live with it. Which is why I optimize for my own joy when coding, the interactivity of the experience, the expressive power, the editing ergonomics of navigating and modifying the source code, etc.

amano 2025-10-14T05:03:06.211679Z

Carp isn't good for me.

2025-10-14T05:03:28.272769Z

In that sense, if I couldn't choose Clojure because of a hostile to it work environment, it be more that maybe I'd be attracted to Rust over Java. In that sense I feel Rust compete more with Java than Clojure, Clojure is much more unique in look and feel.

amano 2025-10-14T05:05:17.719749Z

You don't get to choose a language you like. The choices are forced upon you by the kind of things you write.

1
amano 2025-10-14T05:05:46.334069Z

I just happen to like clojure and clojure happens to be a good fit for web development. I couldn't force clojure in system scripting because I had to write an entirely new clojure dialect for system scripting from scratch.

amano 2025-10-14T05:07:18.558979Z

It's million times easier to change what you like than to force what you like to work for your use cases. I don't like Rust, and I don't have to force Rust to work for web development.

💯 1
2025-10-14T05:07:42.880009Z

Well, that's the ideal. But I feel you can more often than you think pick the language you like for anything you want to write, if you're okay with the trade-offs or dealing with sometimes less than ideal setups. Like you can use Clojure for scripting, but you didn't want to let go the system package managers. Which I totally respect.

amano 2025-10-14T05:09:00.280779Z

I would still force myself to like Rust if Rust is a good fit for my personal use case.

2025-10-14T05:09:16.999019Z

Oh for sure haha. But I sometimes go the extra mile to use what I like 😛. I wouldn't have attempted to bring in all of the Clojure deps into Linux package managers, so ya that I agree, too much work. But you know, dealing with Graal and native-image, dealing with ClojureScript pains, things like that though I endure 😛

amano 2025-10-14T05:09:54.156049Z

I forced myself to like janet instead of shoving clojure into system scripting niche.

amano 2025-10-14T05:11:51.189449Z

Babashka is a project scripting language, and it can produce uberscripts and uberjars which can be run by babashka. Thus, you can kind of get portable babashka programs because you can carry uberjars and uberscripts, but it is not a system application. It's a portable application. If you are okay with portable applications, you can use babashka.

2025-10-14T05:13:38.453009Z

Alright, time for bed for me. TTYL

gtrak 2025-10-14T06:02:16.745319Z

I am writing rust on the only clojure team in a java-centric org, so I'm both trying to enjoy writing clojure again and trying to find more ways to use rust.

gtrak 2025-10-14T06:04:33.667399Z

There is a kubernetes cluster that is so overprovisioned with JVMs that they think they can't afford to run our rust http sidecar, so instead I gave them a JNA FFI jar over the rust. It still amazes me it works at all, but why so many jvms?

gtrak 2025-10-14T06:05:31.334989Z

My thing handles 10k req/s on 20 threads and uses 50 megabytes of memory total.

gtrak 2025-10-14T06:06:31.767299Z

Can a java program run with less than 1GB these days?

gtrak 2025-10-14T06:08:14.148699Z

I don't care about the perf. I care about reliability and not getting woken up at night.

gtrak 2025-10-14T06:09:10.011029Z

Oh and they're stuck on java8 :P

gtrak 2025-10-14T06:20:01.053219Z

We have a large clojure test suite that a/b tests this rust impl and the earlier clojure impl that preceded it (that happens to use different ffi to rust as well)

gtrak 2025-10-14T06:21:32.933619Z

The punchline is I've found and fixed more inconsistencies in the clojure by bringing in that rust lib than the clojure tests have found bugs in the rust.

2025-10-12T14:56:48.408079Z

I can't speak for Haskell or OCAML, but for Java and Scala, we didn't have anymore tests on our Clojure code base than our Java or Scala code base. If you go and look at a lot of the open source Clojure libraries too, I feel there's not a whole lot of tests either.

2025-10-12T14:59:08.610229Z

To be clear, I'm not saying I have no tests. But a happy path test generally is good enough. And for certain things where there's very important nuanced edge cases test for those to be sure they're not accidentally regressed on.

2025-10-12T15:00:48.322369Z

Happy path tests are going to give you the "type regression" check you need.

amano 2025-10-13T00:11:43.772759Z

What is happy path?

2025-10-13T00:13:19.717119Z

Happy path is like testing the typical use. Say you have a test for + Happy path test would be like (= 10 (+ 1 2 3 4)) Where edge case test would be like (= ? (+)) (= ? (+ 1)) (= ? (+ -1)) (= ? (+ nil)) (= ? (+ "1" 1))

amano 2025-10-13T02:05:55.007859Z

To me, happy path is no test and no bug and no problem.

amano 2025-10-13T02:38:52.411879Z

I think clojure offers a practical tradeoff between freedom and discipline and safety. It doesn't obsess with total safety as haskell and rust do. The attempt to achieve total safety increases complexity, reduces freedom of expression, and doesn't actually make code safe. Total safety is impossible. Rust is not safe. Haskell is not safe. Both languages have to provide escape hatches that people can abuse anytime. Transient data structures, persistent data structures, GC, and STM provide discipline and enough safety without sacrificing freedom of expressing actual logic. A complex type system and memory safety without GC restrict freedom or make coding cumbersome. I don't need to ditch garbage collector because I'm not writing a real-time game engine that can't have world-stopping GC. There is no substitute for developer discipline. If you don't hire a disciplined developer, you will get shitty code in any language. A developers doesn't have to be the best, but has to be disciplined. Don't chase total safety. Don't chase safety at the expense of freedom. Even in real world, the pursuit of total safety doesn't make people actually safe and only erodes freedom. There is no substitute for discipline and freedom. If you chase safety at the expense of freedom, you lose both.

🤘 1
2025-10-13T03:19:47.963449Z

Haha, well I mean specifically "happy path testing". But yes, the happiest path is it all just works 😁 I agree about the sweet spot trade-off.

amano 2025-10-13T03:30:05.604729Z

That said, for low-level system programming and game engine, I don't mind rust or zig. Zig is much simpler than rust while providing some memory safety without GC. For high-level system programming, jank and basilisp can be used. Babashka can't be used as a system programming language. It is a project programming language or a scripting language. I don't see the advantage of web development in Rust. We already have clojure and clojurescript. In the future, we might even have basilisp for web backend programming.

raspasov 2025-10-13T04:54:44.413479Z

One thing worth noting about Clojure is that it's strong, dynamic, and idiomatically functional + immutable, a relatively rare combination (only Erlang and Elixir immediately come to mind). That specific combination excludes a whole variety of bugs, and particularly those related to state.

raspasov 2025-10-13T05:03:05.593989Z

In terms of tests, my default recommendation is to invest time in property-based testing if you care about correctness. Unit tests will catch trivial bugs and errors, but their ability to catch subtle cases is about 10x-100x less effective than property-based testing (anecdotal estimate). Of course, unit tests are also much more trivial to write. Nowadays, any decent LLM can write you a working unit test almost always on the first try.

amano 2025-10-14T07:24:51.815419Z

I still don't care. You are in a company that can afford to hire multiple developers. Each developer can specialize in a different language that's good for different things. You want me to write Rust? Pay me a lot.

amano 2025-10-14T07:27:39.567819Z

As I wrote above, Rust can be used for squeezing performance in a company that's in high demand. I can always hire a Rust/C/C++/whatever developer later. Safety and reliability come with their own cost. You are only looking at benefits and ignoring the costs. I can even justify haskell if I was only considering benefits and ignoring the costs. I can justify haskell all day if I really wanted. I will still consider Haskell in the right contexts, but I will not usually even think about Haskell. I can give you endless reasons that you should use haskell instead of rust, but I won't.

amano 2025-10-14T07:30:02.408479Z

Please stop pushing Rust so hard in clojurian slack. It's obvious that you are pushing Rust hard.

amano 2025-10-14T07:31:47.033599Z

Clojure and java are good at certain things and bad at other niches. I'm aware of that. Haskell may be suitable in some contexts, but I don't like Haskell and Rust personally. If Rust is actually a good fit and not using Rust is the the difference that kills my business, I will gladly force myself to learn and like Rust. But, until that happens, I won't consider it.

amano 2025-10-14T07:33:27.970769Z

To me, clojure is just a stepping stone and just a tool. I like it, but I am not going to push it where it doesn't belong.

amano 2025-10-14T07:35:09.290069Z

Don't push specific things where they don't make sense right now. Right now, Rust doesn't make sense to me. I don't know when it will make sense. Don't give me scenarios that I won't find myself in anytime soon.

amano 2025-10-14T07:36:13.843649Z

Python, Raku, Haskell, Rust, etc,.. I don't care. Just get the job done quickly. I will do whatever makes sense "right now". Rust isn't a particularly good fit for web development. It can be used for web development just as C, C++, and Zig can be. But, that doesn't mean these languages are my default choices for web development from the beginning. I wouldn't choose C, C++, Zig, Nim, Rust, Racket, guile, etc, ... as default choices for web development.

amano 2025-10-14T07:41:13.440149Z

You are just making artificial reasons to use Rust. I want you to go to Rust community if you want to continue preaching Rust. I don't want to hear more of Rust sermon.

amano 2025-10-14T07:48:16.786429Z

If you are frustrated by the fact that you aren't allowed to write Rust as much as you want, then find a new job, or create a Rust business, or write Rust as a hobbyist. Don't come here to tell others to use Rust. What do you think Rust is? Is it the thing that's going to save the world from destruction? Get a new job, or create your own business, man.

amano 2025-10-14T07:51:29.863649Z

How annoying would it be if a clojure developer is nagging other people to use clojure in a ruby shop that writes ruby on rails? Everything is already written in Ruby, and you want us to adopt clojure? I wouldn't suggest that. Get a new job.

amano 2025-10-14T07:54:56.506369Z

I hate Rust evangelism culture. I didn't care much about Rust. Now, I actively want to avoid Rust because of the community. Don't bother other people.

amano 2025-10-14T07:58:16.844439Z

If Rust was so great, then we would be the ones who are banging on your door for advice?

raspasov 2025-10-14T10:01:24.108399Z

ZGC on Java 25 is an effectively pauseless GC (it comes with the JVM, but it's still not the default; use a flag to enable it). In my tests, it's pretty impressive so far. No hard stop-the-world pauses, just short slowdowns while the GC is running, even when calling (System/gc).

amano 2025-10-14T11:21:15.068679Z

One more reason to prefer GC to Rust borrow checker.

🎯 1
raspasov 2025-10-14T11:52:00.010369Z

From my brief research in Rust, to implement persistent data structures (similar to Clojure), one has to use Rust's Arc (and not their default borrow checker). Arc runs at runtime (!), unlike the borrow checker, which is "cost-free" (in terms of performance). But I far from a Rust expert, so would love to be corrected if necessary. https://github.com/orium/rpds

raspasov 2025-10-14T11:56:51.140239Z

And when we start talking about Arc, some anecdotal reports say it's actually worse than GC in many cases, especially once memory gets fragmented, etc, etc. It's uncanny what the JVM can do because it has total control over the location of objects: it can shift them to new memory addresses as it sees fit, compacting memory to reduce fragmentation. In Rust/C/etc that's "your problem" (again, that's my outsider's understanding).

gtrak 2025-10-14T12:19:47.410989Z

Hmm, the reason to use it was not arbitrary. People before me decided to build around Cedar https://docs.cedarpolicy.com/policies/syntax-operators.html I expect as time goes on, there's going to be more key functionality in different domains where the rust impl wins.

gtrak 2025-10-14T12:22:16.181789Z

Here's the persistent data structures I've seen but have no need to use https://docs.rs/im/latest/im/ , and i felt the same way in ocaml

gtrak 2025-10-14T12:23:26.151579Z

Arc is a reference-counted smart pointer. It's ok to build around. It's not zero cost, but it's fine.

gtrak 2025-10-14T12:24:36.387489Z

You can replace glibc allocator with a different one if you need to, but in 8k lines i have like 10 Arcs.

gtrak 2025-10-14T12:28:55.078909Z

You would be surprised how much you can get done with predominantly stack allocation

2025-10-14T16:55:37.570439Z

You can run JVM apps with under 50mb of memory. Bigger apps might need to be under 250mb and so on. If you native compile them they run with even less. Of course you incur more garbage collection passes. That's the trade off with explicit memory management or reference counting. But you get to just never have to worry about it, no wondering if you have cycles, no thinking if you have a graph and need Rc, and so on.

amano 2025-10-14T17:11:29.332649Z

No. No....

amano 2025-10-14T17:11:33.039819Z

Stop talking about Rust here. I am notified of new comments on this thread.

amano 2025-10-14T17:12:16.316149Z

Go somewhere else.

gtrak 2025-10-14T17:12:22.600219Z

Just admit that the general perception of mutability and the value of GC clojurists tend to take is based on how it goes wrong in java

gtrak 2025-10-14T17:13:25.490599Z

The majority of people I meet who aren't on the JVM actively avoid JVMs

amano 2025-10-14T17:13:56.903109Z

I don't use clojure because of JVM. I couldn't care less about JVM although virtual threads are cool.

amano 2025-10-14T17:17:36.369399Z

If clojure wasn't hosted on JVM, I wouldn't touch JVM.

gtrak 2025-10-14T17:18:22.678899Z

Yeah, I'm curious to see how jank-lang does

gtrak 2025-10-14T17:19:41.012899Z

I like repls and s-expressions. ¯\(ツ)

gtrak 2025-10-14T17:20:54.290079Z

typed racket might not be so bad, except no one uses it

amano 2025-10-14T17:21:17.907959Z

Typed racket is not worth thinking about.

amano 2025-10-14T17:23:53.980959Z

@gtrak I urge you to stop trying to expand your mind with new programming languages. Typed racket is just another distraction. Just pick one language and one niche, and stick with it. You don't live 10,000 years and get to live the first 1,000 years freely sponsored by someone else. If you screw up the next few years, your life will be ruined. You live on human timescale. You probably only have 10 years to shit your shit together. Focus on being useful to other people. Typed racket and other programming languages won't help you become useful to other people.

gtrak 2025-10-14T17:25:57.733409Z

clojure had to justify its existence not too far back, and I would prefer if it got better. What if everyone thought like that and stuck to java?

amano 2025-10-14T17:26:15.744669Z

I don't care. It doesn't matter in the grand scheme of things. If there was only java, I would still force myself to like java.

amano 2025-10-14T17:26:46.370109Z

Clojure just happens to be a good boring language for web dev.

amano 2025-10-14T17:28:08.606999Z

Linus torvalds picked C language and linux kernel as his niche. Rich hickey picked clojure and never looked back.

amano 2025-10-14T17:28:26.768639Z

Pick one. Only add more after you stabilize your niche for years.

gtrak 2025-10-14T17:28:39.093749Z

A lot of people did the same and they didn't become Linus or Rich for it

amano 2025-10-14T17:29:06.871849Z

But, they are still far ahead of people like you who dabble with everything and don't specialize in nothing.

gtrak 2025-10-14T17:29:38.346439Z

bold statement, lol

amano 2025-10-14T17:30:46.604539Z

Dabblers aren't good at any one thing. You are only paid as much as your best specialty. If you learned how to build a house with your hands and how to build a computer and how to build web app, you won't be good at any one of them.

amano 2025-10-14T17:31:10.892459Z

Without divions of labor and specialization, you become poor.

gtrak 2025-10-14T17:32:55.670109Z

I was a tech lead for a ruby team before this, and dabbling was enough

gtrak 2025-10-14T17:33:24.794799Z

I've worked effectively in lots of languages, even the ones I don't like

gtrak 2025-10-14T17:33:46.620849Z

I don't expect everyone else to do that, but it could work, right?

amano 2025-10-14T17:33:53.787209Z

Then, your specialty probably isn't a specific language. It's probably CRUD web dev? I still would avoid learning a new language unless I have to.

amano 2025-10-14T17:35:15.824819Z

You could be so much more if you focused on one niche.

gtrak 2025-10-14T17:35:51.685389Z

The domain was new to me, but it's just systems at the end of the day. DBs, message queues, observability. It didn't matter that it was ruby, except that ruby made it horribly slow.

gtrak 2025-10-14T17:36:32.857309Z

There aren't a lot of generalist jobs out there, but I always find one.

amano 2025-10-14T17:37:17.190539Z

Because most programming jobs don't require high expertise. But, that's not going to suffice for earning a lot of money or achieving greatness.

gtrak 2025-10-14T17:37:52.729099Z

Ah, yeah, I don't believe in making high-risk big swings kind of bets with my time.

amano 2025-10-14T17:38:07.310749Z

It's not high risk.

gtrak 2025-10-14T17:38:09.159479Z

That's why I'm not a founder.

amano 2025-10-14T17:38:34.345189Z

Being an expert C++ game engine developer isn't exactly a high risk endeavour.

amano 2025-10-14T17:40:27.066299Z

In any case, learning a new programming language just for fun isn't going to help. It will just waste more of your time.

gtrak 2025-10-14T17:40:34.521559Z

gamedev is maybe not the best example https://cjc.utppublishing.com/doi/10.22230/cjc.2006v31n3a1771

amano 2025-10-14T17:41:27.351809Z

Earning a lot of money isn't about working 4 hours a day.... If you just want to be happy, you can be a starbucks employee. No stress, but little pay.

amano 2025-10-14T17:44:26.099449Z

Life is too short to waste time on learning programming languages just because you might think they maybe help in the future. If you are going to learn something, you better need it now.

gtrak 2025-10-14T17:45:00.540339Z

I thought like you for about 10 years, but it was refreshing to enjoy it again.

amano 2025-10-14T17:45:45.731739Z

I'm not passionate about programming. I'm only passionate about wealth for now. Clojure is just a stepping stone toward wealth for me. If my business grows, I won't code outside my tiny system scripts.

amano 2025-10-14T17:47:45.045219Z

I used to be passioante about programming, but I discovered I was rotting in poverty because I was only thinking about comfort and fun. I don't want to spoil myself with comfort and fun anymore. If java is going to pay me a billion dollars, I will write it instead of clojure. If diggin the ground pays me billions of dollars, I will dig the ground. Concrete business moguls don't make love with concrete dolls. I don't make love with clojure dolls. I just want to have some wealth...

amano 2025-10-14T17:55:40.721409Z

A new programming language won't help you deliver business value. Learning typed racket definitely won't. Learning guile scheme and guix system won't help you deliver business value if you can spend your time on just delivering business value instead of learning these things. I would just use a good simple programming language to deliver the value. Time to market is important. With speed, you can fix backend problems later.

gtrak 2025-10-14T17:56:41.270729Z

agreed, that's why I never learned haskell. I learned ocaml for one job b/c it was impossible to hire ocaml devs, so they were willing to wait for people to learn it during onboarding. It took a couple of weeks, same with rust.

gtrak 2025-10-14T17:57:56.078479Z

Clojure broke my brain and made learning new languages easier, I think

amano 2025-10-14T17:58:27.639829Z

I definitely regret learning haskell... I already know how to write clojure. I'm sure Rust will be just as cumbersome as haskell.......

gtrak 2025-10-14T17:59:38.610829Z

I'm not saying there's no cost, just that you might be overstating the cost. You like clojure and don't want to consider other languages, I have no problem with that. I just want those things to be represented accurately.

gtrak 2025-10-14T18:00:56.010859Z

Not every clojure dev we hired to do ocaml had an easy time onboarding, and they were let go.

amano 2025-10-14T18:01:07.341699Z

I also regret learning Raku because of its complexity in comparison to relative lack of expressive power.

amano 2025-10-14T18:02:09.375679Z

Rust isn't going to be any less complex than Raku. So, I stay away from complex languages.

2025-10-14T18:03:20.185719Z

I'll move the conversation to off-topic: https://clojurians.slack.com/archives/C03RZGPG3/p1760464964839769

amano 2025-10-14T18:03:22.366339Z

The most complex part of clojure is transducers, so clojure isn't nearly as complex as other big languages.

gtrak 2025-10-14T18:10:06.365579Z

🙊

p-himik 2025-10-11T09:43:20.428569Z

There's nothing special about Clojure in this regard, so it by itself does not require anything. You might be alluding to the fact that it's dynamically typed, to that I can only add my own observations that the vast majority of bugs are not type-related.

☝️ 1
amano 2025-10-11T10:16:29.611269Z

I wasn't precise with my language. Is it sufficient to add tests for critical parts in production? Or, should I aim for nearly full test coverage in production?

amano 2025-10-11T10:17:11.796349Z

I guess static type checking reduces the need for a lot of tests.

practicalli-johnny 2025-10-11T10:17:38.748169Z

Unit tests with specifications and generative test data is very common in Clojure. I suggest that is critical for the public interface/api of the clojure system (incoming and outgoing). The amount of unit test code coverage is an engineering decision for the team and organisation, depending on many factors. REPL driven development can prevent errors creeping in when done well, although often use the repl experiments to help design valuable unit tests too I have found generative testing with clojure.spec or malli very effective in both commercial and personal projects. Using test selectors during development can be very effective at minimising the feedback time from testing

p-himik 2025-10-11T10:35:31.570719Z

> I guess static type checking reduces the need for a lot of tests. That's what I tried addressing with my second statement above - I don't find it to be the case. With everything else being equal, including the amount and the scope of tests, a project being written in a statically typed language does not mean that that project is more reliable than the version written in a dynamically typed language. There are factors beyond just the "compiler checks that X can be done" one, and they aren't amenable to even a hypothetical perfect and practical type system that doesn't exist and probably won't exist for decades to come. But it's my own anecdata and a somewhat philosophical preaching. All the studies in the relevant domain have always been indicative at best, and their indications are stochastic as well.

💯 1
Ludger Solbach 2025-10-11T11:11:23.369729Z

IMHO, testing should always be prioritized by risk. Test the high risk areas first and the lower risk areas after that. It's your decision when to stop, because of diminishing returns. In an ideal world, everything would be tested. But if you don't live in an ideal world, prioritize the testing according to risk and consequences. The higher the coverage, the better, of course.

Gent Krasniqi 2025-10-11T11:41:03.490639Z

I can only speak of one-person projects so far when it comes to Clojure, and for those I don't find I need more unit tests compared to popular statically typed languages like C#, Java. Compared to something like Elm and Ocaml, however, I do feel a higher need to test the nil case explicitly in unit tests (and depending on how complex/nested the data structure is, that can be quite a few tests). I know Clojure and other lisps aren't the worst when it comes to their approach to nulls, but I have had quite a few cases where I was caught by surprise in practice. So now I end up being possibly too defensive on that front.

teodorlu 2025-10-11T11:48:44.048469Z

> Is it sufficient to add tests for critical parts in production? Or, should I aim for nearly full test coverage in production? We structure our app so that we can write mostly functions that take data, return data, and doesn't do anything else. Those functions are easy to test (example input, example output or example input with assertions on output). Those minimal "machinery" parts (like http server stuff) are things we don't spend too much effort writing tests for. It's hard to test, and it's often stuff you notice immediately if it's wrong. If the http server is called with invalid arguments, you won't see anything when running locally. So trying to test everything is probably be more painful than beneficial. To answer "shold I test X?", you'll have to feel your way forwards. If you spend all your time writing tests, write fewer tests. If you spend all your time debugging errors that could have been caught by better tests, write more tests.

Ludger Solbach 2025-10-11T12:09:48.022569Z

If you have a functional core with a stateful shell, so you push all state handling to the boundaries, most of the application can be tested by unit tests without the need for mocking or complicated state preparation. So testing a functional core is easier than testing a default OO application.

hrtmt brng 2025-10-11T13:15:54.018219Z

In my opinion static typing prevents you only from the most stupid bugs. Often a single test case provides the same confidence as all the typing ceremony. Don’t understand me wrong. I like static typing, and it has some value and it is a good exercise and provides more reasonability while programming. But most code is so simple, that the effort does not pay off. So I recommend to write tests until you feel you have enough. I can tell you at least, that for me 100% systematic test coverage prevented me a few times from bugs in Clojure. But the effort was high. So I don’t know if it was finally worth the effort. And I also think that tests have a downside. If you change the code, you have to change tons of tests. All the time you spend for testing, you don’t have for programming and for systematic thinking. I think nobody can give you a finite answer, what is good for you.

amano 2025-10-11T14:02:04.138649Z

I will try writing tests for critical pure functions. I prefer minimalist approach. That way, I can know how much test I actually need.

2025-10-11T14:58:58.178539Z

You need to test your code, but generally that's done at the REPL. After that, the amount of regression test you want to have depends. I don't feel you need that many in reality. They exist so that you don't accidentally regress on some behavior or property. I'd say that's most valuable when testing business logic and the more end to end features.

2025-10-11T22:24:52.017309Z

for me, tests are something I can do before asking someone else to look at my code. I don't want to waste a collaborator's time by making them fix my mistakes before they can get other work done. REPL is excellent for drafting out my own internals, but it isn't how I would ensure I am not breaking the rest of an application. it's very easy to have "don't push code that won't pass the type checker" and/or "don't push code that doesn't pass unit tests" as rules.

2025-10-11T22:28:29.443219Z

also, especially when working remotely, it's easy in functional style code (in any language) to have things that are so abstract that you can't really tell what they are for without unit tests.

gtrak 2025-10-12T01:03:28.219329Z

The codebase I work in with experienced clojure devs has more lines of test code than impl, but a large portion of that is test data. I've done a lot of ocaml in the past and some rust these days, and my feeling is you need a large test suite in clojure for any nontrivial codebase, and not so much in static-typed HM-inference languages. Eg, test the happy path and rely on exhaustiveness checking for the other cases. You don't usually need to write tests for anything the compiler does for you, so you spend a little more time encoding your business logic into type invariants instead of writing tests for those properties. I've done it both ways, I prefer static types to be honest, but others will disagree with me here.

gtrak 2025-10-12T01:56:06.984479Z

Another way to look at it is in clojure you may have to write more tests than some other language choices, but they're easier to write. You may have to apply more judgment to prioritize what to test, and there's some common gotchas and the usual dynamic-typed problems, but repls and homoiconicity make it less bad.

gtrak 2025-10-12T01:58:52.556379Z

also data-orientation helps vs something like ruby

amano 2025-10-12T02:00:01.611119Z

I was burned by haskell monad transformers and its complex type system that hinders type inference.

gtrak 2025-10-12T02:01:02.540369Z

I'm not sure all that haskell stuff is necessary, but I haven't tried to use it.

amano 2025-10-12T02:03:23.371539Z

I wouldn't use rust for web programming because it is large and complex? Why did you need a lot of tests for your clojure application? Just a lot of test data? Do statically typed programming languages spare you from a lot of test data?

amano 2025-10-12T02:04:17.790519Z

I'm a minimalist, so I try to write minimal tests.

amano 2025-10-12T02:05:42.647959Z

By the way, I wrote a 7k LoC haskell application. I hated the experience. It's cumbersome.

gtrak 2025-10-12T02:07:14.186079Z

No, I think static types spare you from some paranoia of possibly missing an important case. Instead, you just feel friction when modeling things wrong and it might force some different choices upfront. I'm not sure there's any relation to our application domain and the testing, it's just what the developers ended up doing over time. I've worked on a 40k-line ocaml codebase (not sure how much of it I wrote), and wrote 7k lines of rust recently for this thing, and I didn't hate it generally. There were specific tooling problems that improved over time in ocaml, not rust.

gtrak 2025-10-12T02:08:08.388209Z

It seems weird to choose a language based on how many tests you think it'll make you write?

amano 2025-10-12T02:09:48.372049Z

No.

amano 2025-10-12T02:09:59.022999Z

I already chose clojure and clojurescript as the languages for my new web service.

amano 2025-10-12T02:10:42.976699Z

Technically, I can use haskell, rust, and ocaml for web programming, but I prefer clojure for web programming.

gtrak 2025-10-12T02:11:40.823709Z

Yeah, I don't know what's clojure-specific about testing strategy, except you tend to model everything as pure interpreters over tiny data-dsls.

amano 2025-10-12T02:13:32.487399Z

Haskell is way too complex with higher kind types, monad transformers, etc, ... OCaml may be good, but I haven't learned it. Rust is big and complex. There isn't a single statically-typed language I like, yet.

gtrak 2025-10-12T02:18:40.355069Z

The rust complexity doesn't bother me, I don't have to know all of it to be effective. Borrows/lifetimes are a key thing, but they're worth it:https://cliffle.com/blog/rust-typestate/#a-simple-example-the-living-and-the-dead Eg, if you close a file you can't compile a program that tries to do something with it after

amano 2025-10-12T02:19:57.559279Z

I have a bad habit of chasing fun instead of utility. Clojure and clojurescript are more than fine for web programming, so I use them. I'm sure Rust can be useful in the right contexts.

amano 2025-10-12T02:23:38.135079Z

https://www.roc-lang.org/ seems to involve minimal static type burden, so it can be useful in the future. Just not now.

gtrak 2025-10-12T02:27:09.133939Z

Ocaml has really nice inference if you just care about not having to explicitly write the types out, but I think I felt more 'burden' around them at the start: https://ocaml.github.io/merlin/editor/emacs/ Rust and typescript need to you write them out at function boundaries, but ocaml doesn't

gtrak 2025-10-12T02:28:05.461699Z

For rust, VSCode/rust-analyzer can infer those anyway, so it's a couple of clicks to have it write them for you

amano 2025-10-12T02:32:22.451159Z

I don't see the appeal of typescript. Static types on javascript is like lipstick on a pig.

gtrak 2025-10-12T02:33:20.532879Z

Yeah, that complex type system is what you get when you try to accommodate all the dynamic code that's already been written instead of a designing a language without baggage.

gtrak 2025-10-12T02:34:19.548589Z

It's as good as anything for web programming, I guess?

gtrak 2025-10-12T02:38:20.118199Z

It depends on your requirements. The rust I'm working on can handle 10k rps for authz and JWT validation on 20 threads and uses like 50MB of memory max to do it. Nearly everything is stack-allocated. If you just care about code expressivity, you might pick something else, but I like working in it.

amano 2025-10-12T02:39:18.852259Z

Rust is a low-level system programming language that's designed to be efficient, but it leaves a lot to be desired.

amano 2025-10-12T02:45:36.716689Z

For my web programming, Rust isn't the first choice.

amano 2025-10-12T03:06:16.383799Z

https://medium.com/tekyz-blog/discipline-the-backbone-of-an-exceptional-software-development-team-d2669d807893 In my next project, I'm going to test out freedom and discipline. There is no substitute for discipline. Rust ruined developer experience with memory safety without garbage collector. This time, I opt for freedom and discipline instead of total safety.

gtrak 2025-10-12T03:08:58.504419Z

I may be a bit cynical but is the argument that dynamic languages don't give you a false illusion of safety? 😄

gtrak 2025-10-12T03:12:59.873009Z

plenty of success stories out there https://www.allthingsdistributed.com/2025/05/just-make-it-scale-an-aurora-dsql-story.html

amano 2025-10-12T03:14:41.822399Z

Rust is a good choice if you want to squeeze out performance without worrying about memory leak, but I don't need to do that in my web service project.

amano 2025-10-12T03:15:50.321829Z

If I ever need to squeeze out performance, then I already don't need to write any code. I can hire rust developers later if I choose rust, and I don't have to write rust.

gtrak 2025-10-12T03:15:52.123199Z

Hmm, let me put out there that I think the people that complain about the borrow-checker are usually OO or C background folks, not FP folks.

gtrak 2025-10-12T03:16:21.207219Z

Maybe there's more of them to begin with, but I think clojure's immutable habits get you 80% of the way to doing that right.

amano 2025-10-12T03:17:23.431599Z

I"m not against rust for all cases, but I don't want to be the one who writes it. I'd rather hire rust developers.

gtrak 2025-10-12T03:17:28.337949Z

If you know you have a lot of self-referential data structures, then you might actually have a hard time with it, but most people don't really need that.

gtrak 2025-10-12T03:18:02.596379Z

Eg EDN doesn't have cycles unless you put in atoms or something

gtrak 2025-10-12T03:18:56.655189Z

I don't care if you write rust, I just think that it's a common misperception that the better perf comes at the cost of usability, which doesn't match my experience.

amano 2025-10-12T03:19:26.071849Z

Rust isn't usable for me... I don't want to deal with rust memory safety in my web service. I'd rather pay someone to squeeze out performance if my web service is so much in demand that I need to hire people anyway.

amano 2025-10-12T03:21:26.037489Z

Rust has haskell vibe, and I didn't like writing haskell... which forced me to write monad transformers and lenses.

amano 2025-10-12T03:22:11.985169Z

I just want to focus on web service business logic. Clojure is good for that.

amano 2025-10-12T03:26:29.298879Z

Clojure was designed for line-of-business(in situ) applications. It's suitable for people who want to focus on business logic.

gtrak 2025-10-12T03:27:05.634579Z

Has rich hickey ever written a web service?

amano 2025-10-12T03:27:13.846629Z

Yes? A lot?

gtrak 2025-10-12T03:27:31.841589Z

He was a C++ guy

amano 2025-10-12T03:27:41.299079Z

He also wrote common lisp and other languages.

amano 2025-10-12T03:28:13.577019Z

And, it doesn't matter at this point. I already know how to write clojure and clojurescript. I like these languages. I don't want to spend the next few months on learning Rust now. Rust isn't an advantage over clojure for my use case.

amano 2025-10-12T03:30:25.184319Z

Rust is very much like C++. I wouldn't write C++ personally, either. But, I will hire someone who writes C++ or Rust.

gtrak 2025-10-12T03:33:58.059129Z

I suggest to try new things, but I also hope this works out for you!

amano 2025-10-12T03:34:30.036239Z

I don't have time to learn everything that comes my way. If I learned everything that comes my way, I would grow old and die before I launch any business. I don't live 10,000 years. That's why we have division of labor. I run my business, and you write Rust. I hire UI programmers because I can't replace them with my own time.