If this is too off-topic please let me know and I will delete it. What’s your feeling about the current economy? Even if macro numbers in some countries are good, don't you feel some of us (western countries, for instance) are already living in a recession? Some people attribute this to the end of low or zero interest rates, so companies have prioritized profits instead of growth, but at the same time, I see Big tech betting in AI like there is no tomorrow and losing fortunes. I cannot get my head around what is going on. I don't think anyone knows. Is a significant market bubble about to pop?
I think this is a good place to plug my favourite Gary Stevenson https://www.youtube.com/watch?v=rAb_p5DCC3E
> Is a significant market bubble about to pop? Put it this way, a bubble is not about to pop iff • The companies currently buying NVIDIA GPUs will continue buying more GPUs than they did the previous quarter • OpenAI successfully raises all the money it needs to (which is more than available free capital) • The first, second, and third in history 1+ GW data centers are all built in a timespan that far exceeds every other data center project that has ever been done. • AI companies, of which none are profitable, suddenly become profitable • People stop making videos of Garfield with an Uzi shooting up rooms full of lasagna
This is the kind of news that makes me concerned.
I don't think the bubble will pop because what else is there? There Is No Alternative. The ultrawealthy just don't have any other outlets to pour their evergrowing assets to. Hence, the crypto bubble has not popped. Hence, housing and gold is up. Money is not real, the only real thing is the driving the middle and working classes deeper into poverty – something that will coninue regardless of what the latest meme the billionaire class is infatuated with.
The ultrawealthy cannot prevent bubble pops. If they could, there wouldn't be bubble pops
Lets say, hypothetically, the Fed turns on the money printer. Cool, a few trillion dollars flow to the AI companies. Those companies then burn that money, as they do not have a way to make a profit...for what purpose is this being done? How many times would even that deus ex machina happen?
(potentially interesting discussion here but with my Admin hat on, I'll just caution that we generally try to keep away from politics even in #off-topic since that can get pretty contentious... remember to be polite to each other here and try to focus on the tech / economics aspects if possible, thanks!)
Having been in this industry for over forty years, the scale of investment in AI seems unlike any previous bubble we've seen over the decades... I can't see how it is sustainable and yet the folks with all the money still seem to be comfortable pouring a lot of it into AI, and tech companies in general seem very comfortable injecting AI into absolutely everything. I find it puzzling, TBH.
> Lets say, hypothetically, the Fed turns on the money printer. They will. > for what purpose is this being done? For the same purpose as banks were bailed out in 2008. @seancorfield I promise, no politics from me except calls for itty bitty socialist revolution (the real one, not the red ersatz).
when the banks were bailed out, after the cash injection the banks had a business model. I.E. but-for the speculative crash they could continue to function. AI companies do not have a business model, they stop functioning if at any point people stop shoveling mountains of money into them.
Do you think there will be a shift to on-device models for a lot of the day-to-day work? The whole Copilot+ PC thing seems to be headed that way, and we're seeing some on-device AI for smartphones these days. Will that offset the vast cost currently being run up by data centers?
If that happens, that would also cause a crash
Yeah, I think the massive costs, the need for power and water and chips and so on – it is the feature, not a bug.
the money poured into making data centers and filling them with Nvidia GPUs only pays off as an investment if you needed data centers filled with Nvidia GPUs
It very conveniently satisfies the excuse of productive economic activity, making it look like something important is being done.
I guess at least the data centers create some new jobs... 😐
What I find most baffling about the push to build the datacenters is the short lifecycle of GPUs. I can't make sense of how having to rebuild the datacenters in 5 years squares with making money.
The jerbs that the damn clankers are later going to take away anyway.
(I also think--and hope--that LLMs will become commodity tech that I can run on hardware I own, which does not square with the massive valuations we're seeing.)
I have a graph of the business relationships going on: before I share it, as context Nvidia seems to be investing in "neocloud" companies. These companies then use that investment to buy Nvidia GPUs. They then use these GPUs as collateral to raise debt to buy more GPUs.
Now my head hurts! 🙂
Yeah, these graphs are making waves in the last few days.
the factoid i've latched on to is that not only do they need to raise more money, they need to raise more money than exists to be raised. And then they need to do it again next year because they do not make a profit
I'm something far worse even than a layman, but having observed the attitudes of the "power players" and decision makers in the world of AI, the situation doesn't seem very good. It seems to be largely split between mysticism about the potential of AI and then the typical Silicon Valley investor types who only care about "disruption," which seems to implicitly include collapse/bubble burst if that suits them, and I guess I want to ask: why shouldn't it?
At great cost to my sanity I powered through (watching) an interview with Peter Thiel and he said, "if you don't have AI, theres...just nothing going on" (I didn't interview Peter Thiel)
the thing that bothers me isn't so much that the peter thiels' of the world did/do stuff like this, its that its like the 3rd time our field has been complicit in it. Its like we have a collective mental autoimmune disease. Crypto and the Metaverse were equally stupid.
(even if this kinda made it far beyond them in terms of dollerydoos thrown into the burn pile + scale of harm when pop)
well "our field" is complicit in it by its very nature
As Taleb says, we have essentially “saturated” our capacities for meaningful growth, and without growth we cannot pay debts, so there is a need to create bubbles.
Don't worry guys, we are on the right side of history.
with allowance for my ignorance of finance stuff, isn't the entire venture capital model built on debt? I don't think there is any need to "pay debts" in the sense that your average person understands that phrase
yeah thats a real worry - i've heard that microsoft and google could probably survive this going south, but oracle might be pretty up a creek
and that would affect stewardship of java/the jvm
which, in turn, would affect us here
Java is GPL, so f em. Oracle dying in a fire would likely be a positive thing for Java all in all.
it sure wouldn't be a positive thing for the company's 160k worldwide employees
unfortunately software requires capital to maintain and develop + god knows where the copyright would end up + even just considering the scenario of "they need to cut costs drastically and decide that Java language development is where they cut" it would be rough
> its like the 3rd time our field has been complicit in it I remember the hype/investment/promise cycle of 5GLs and object databases from decades ago so... way more than the 3rd time 🙂 although those were inward-facing (aimed at developers, rather than consumers).
And, although the web endures, the web-bubble-bursting in 2000 was probably another time we were all complicit in this (hello, $1M for an e-commerce website project...).
one could argue that software engineers are well-paid because their jobs are hard. one could equally well argue that software engineers are well-paid to buy their silence and cooperation in morally dubious schemes
I've been calling it a bubble for over a year Nice to see everyone else is catching up The current best predictions are for a crash around late 2026 or early 2027 Hope it crashes and doesn't get inflated away. Buy the bottom. Good luck.
My "I told you so" tour will be brief, but pointed
Was it you who shared that excellent Ed Zitron post giving a timeline for the bubble pop?
> Was it you who shared that awful, ranty Ed Zitron post FTFY 🙂
(I cannot stand Zitron's style -- and I think it really detracts from his message)
> I've been calling it a bubble for over a year This feels like a slightly overconfident assertion given that the whole economy as currently organized explodes every 20 years
Ed is the hero we both need and deserve.
yeah, Ed writes like he talks. And he talks like an annoying british person
I'm an annoying British person but I don't talk like that 😄
what i would give to live in a world with only one kind of annoying british person
I can see he's big on citing those sources too
he could use a footnote tho, all these links are incredibly distracting
We're all doomed. But hopefully not before I can cash in my pension 🤣
If you shoot messengers, do you get better or worse messenges?
I'm 35 What pension
> This feels like a slightly overconfident assertion I'm not slightly over confident, tyvm 😉 I did think the crash was going to come from another direction, the disillusionment with output quality from LLMs combined with mass extinction at the start of the senior engineer pipeline resulting in a high demand and tiny supply of experts X whole piles of slop to clean up
I do not think that, crash now or crash later, what this problem requires is more "experts"
Experts here in the sense of expertise not credentialism
Seems like one of those extremely specious "fact versus value judgment" dichotomies that works given some particular perspective that I do not have. To be more explicit: expertise in what? Venture capital? "AI ethics"? Intellectual property law? Computer programming? All of the above? It's certainly not my intention to be pedantic, but I feel a pretty visceral opposition to this guru culture where people are always talking about some ideal-typical intellectual person or group of people who will either appear, or by sudden consensus, be put forward as the leader to fix X problem, and the industry or society closes ranks behind them. On the one hand, it feels like kicking the can down the road, and on the other, it appears to buy way too much stock in the tech messiah narrative that is pervasive
@ben.sless I opened my first (of many) pension funds when I was 19. The pension funds are predominantly sustainable or environmental company focused. (I was too young for a pension when I first started working at age 16 🤣 ) I also have a very small investment in a wind farm.
@bhlieberman93 the argument being made was that there's a training pipeline in the programming workplace, where junior programmers do programming over some number of years and become expert programmers. AI potentially causes two parallel compounding problems: undermines the pipeline so we have fewer experienced programmers available, and creates mediocre code that needs the attention of experienced programmers
@jr0cket meant to imply by the time I retire the funds will probably be insolvent. I need to invest my funds based on that assumption.
Pretty early on, I wrote a web browser extension that replaced the words “AI” or “artificial intelligence” with “FA” and “fancy autocomplete” respectively. It really makes the insanity pop out when reading stuff on the internet, like that one time when Klarna tried to replace their customer service with fancy autocomplete.
Regarding predicting the burst, remember that the market can stay irrational longer than you can stay solvent.
Coincidentally I just finished the book "the great taking". It explains the bubble(s) from a different perspective, not so positive. It gives a different perspective on the bubble and it claims the bubble will burst, because the bubble is by design. Probably not a happy read if you are new to the topic, but the more goodwilling people understand it the better
@jeroenvandijk, I am interested in reading your book. Where/when can I buy it?
@asier.galdos It's available here for free https://thegreattaking.com/
Thread to discuss Rust, Clojure, mutation, and other such nonsense for fun and not for profit.
🐱
The most complex part of clojure is transducers. And, transducers are only a tiny part of clojure. Clojure is still far simpler than raku, rust, and haskell, and C++.
I just see no good reason for now to use anything other than clojure and clojurescript for web dev.
@gtrak Even mutation constrained locally can still produce atrocities as I showed in that loop example. In a pure semantics sense, immutability is just simpler. Mutation semantics only persist for hardware realities, it's just that we can't get rid of it because the hardware can't be as efficient without it at all. Even if you see &mut v at the call site, it's still some implicit mental mutation where you have to realize v is now changed and so on. Rust maybe could have hidden it even more, if it had forced v to be returned and used afterwards from the return value itself.
To me, Rust is worse than clojure for web dev. Rust is worse for anythying that's not low-level or performance-critical.
I would avoid Rust as much as possible. I'm not doing any low-level shit.
Yeah, I avoid transducers, reducers, STM, I'm confounded by spec/malli, core.async I tried to use once, and I think I should generally avoid it now We use malli, and I'm not sure if it's worth it or not. The other devs on my team are more traditional clojure devs and I don't represent their views 😄.
No reason to consider an inferior language.
Transducers are far simpler than Rust....
I can reckon Rust is better than C 🤣, maybe. Not everyone agrees with that actually. But Clojure is just joy in a bottle, pure interactive coding, connected to the runtime program in harmony. It's like being inside your program as you build it. That's just hard to beat.
I don't write transducers, but you can use transducers without really understanding them in depth.
I went from paranoia around mutation like you have right now to having fun with it. It's just a non-problem.
Atom is fine... Other STM constructs are mostly unused.
Transducers are pretty amazing. Honestly it's lazy seq that I think are too complex in comparison. The unfortunate existence of both is a bit tricky. But had transducers been the core from the start it would have been really great.
I don't really have paranoia. That's for static type people lol
if not paranoia then vibes
I have enough discipline to work around mutable data types, but I prefer persistent data structures.
It's more ergonomics. It's like a good UX vs a bad UX. A pleasant to use API vs a unpleasant API.
I don't think a lot of APIs mutate their args?
That's a C-ism.
Even if they do, it'll help you do it safely.
Well I'm sure we agree. Because Rust is basically halfway trying to get rid of it 🤣. But where are it's map/reduce, stream-like data transformation functions?
iterators
I already made my decision. Nothing you say will change my mind about clojure/script.
If you want me to write in a different language, pay me.
data structure manipulation is generally worse, like it is in every other language. Don't worry @amano.kenji, I won't hire you.
Me, neither.
Let's keep it friendly please 🫡
He's not my friend.
He's my enemy.
I was joking, but yeah, ok
You are in clojurian slack. We already chose clojure.
It's all personal choice. Ya, but now we moved to off-topic, so this is an appropriate channel.
https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.reduce
Write Rust if you want...
I was thinking you lose the ability to have the intermediate changes like 'reductions', but it's rarely used in clojure anyway
I'm not going to obsess over every little detail of clojure...
I decided to stop being a nerd.
Spec. Malli. Whatever.
(defn more-money-please [] ;; details left as an exercise to the reader )
I will learn more on the fly.
Yes, but the ability to use intermediate changes more than once is still a better UX and ergonomic. And once again, mutation is just a necessary compromise if you want more extreme efficiency.
even with clones it's still 10x faster than highly-optimized java
so I don't spend time worrying about perf
I don't care... I would use python even. Even python is fast enough for my use case.
I think clojurists might see rust devs concerned with those topics and think everyone must be worrying about that stuff all the time, but you need to keep in mind that this can target microcontrollers and the community is massive.
@gtrak Well, if you remove performance, Rust kind of loses all its appeal compared to GC languages and Clojure
tail latency is another angle
Why am I going to bother with wrapping things in Rc, Arc, what borrowing semantics I need on every function, declaring the type of everything, etc. If not for performance?
Plus the slow compiles
Convincing other people is impossible. You know. People convince themselves.
Ocaml is a GC language with much of the same ergonomics as rust, but I stopped wanting to work in it b/c it was even more niche and had no libraries. We had to maintain C bindings for postgres and mssql in a startup, which was a waste of time.
Ownership/borrows are just not that big of a deal if you're coming from FP
if you're unlearning OO at the same time, it's new
I'm coming from FP. I wrote in haskell for a few months. I was an intermediate haskell programmer.
Ya, but we're not talking about OCaml 😛. I also don't bother with OCaml.
And, I know I will hate ownerhip/borrows.
I'm not doing any low-level shit.
HM type inference is quite nice, I thought I needed a GC, and I didn't
If you don't like clojure, why are you here?
You can go somewhere else.
I'm working in it full-time
We have 80k lines of clojure and 8k of rust on our team
You clearly don't like clojure much.
Get a new job that doesn't involve clojure.
I'm on vacation this week, so I'm more chatty than usual
You're not hooked on the REPL? For me, even forgetting Clojure, just the pure REPL-driven + structural editing is too good to pass on.
No, I thought I would miss it more, but adjusted pretty fast
Telling other people who are good with clojure in clojure community to consider other languages is a waste of time.
Clojure is just the best available language that gives me that. Where it adds a well designed core of standard functions, access to ton of existing libs, the goodness of immutability and FP.
If you like Rust, find a Rust job.
Not sure why this is so irritating for you 😄
🤷♂️ To each their own. But for me it's just too nice. And the overall expressive power as well.
Irritating because you kept telling me to consider Rust although I told you I like clojure and don't like Rust multiple times. Assholes give unsolicited advices multiple times despite being told not to do so. Repeated unsolicited advices are very annoying.
Your question was if clojure is the kind of language that requires full test coverage, and my answer is you'll never know if you've missed an edge-case in a dynamic language, and this experience report is supporting detail
And, I decided to start with minimal tests....
that's cool
I thought you were trolling me with Rust because Rust is obviously god damn complex like haskell. I was traumatized by haskell. I can understand haskell, but I hate it.
I hate playing chess against compilers.
no, I see the complexity in rust, but I'm still productive with it
I see it in haskell, too, and I'm not sure why I would ever want a monad transformer
also in clojure
Ok ok, let's keep it civil. I think the other thread just got too long and we got into some fun space vs tabs, but probably should have moved to a different thread earlier. And personally I enjoy seeing the opinion of people who lean differently, so I don't fall into the emperors new clothes.
yes, that's what I was trying to offer
Clojure doesn't force me to play chess against itself.
I don't want to fight haskell's complex type system or satisfy Rust's borrow checker.
I hate haskell type math. I can do it, but I hate it.
I hate playing chess... because it is useless waste of my energy.
I just want to write application logic. Clojure lets me do that.
First you have to make a tiny data DSL before you can parse it
repeat ad infinitum
You say as if Rust is some kind of the end state of programming langauge evolution, but it is just another shitty language on the way to the ultimate static type language.
I hate people who endorse shitty languages.
that's a fair take actually, I have no idea
That might be just a case of where you work? I rarely invent my own DSLs in Clojure. I do think a lot of people struggle to keep things simple in Clojure, it's almost like they expect more complexity and have to introduce it back. And since Clojure does not limit your expressive power, you can go way overboard with it.
I just use maps and defrecord....
In haskell, I defined application monad transformer.... just to carry application state.... That made me miserable.
Since I've also worked in professional teams, especially in a Java shop, you'll see a lot of real mindbenders Clojure code, because it was like a bunch of Java devs just learning Clojure for the first time as they build a whole new team.
I've been doing clojure on and off for 15 years, what I feel today is just having to load a bunch of context up in my head before I can get my task done.
I know the language, but figuring out what I actually need to do in the application is a lot of friction.
Haskell doesn't make it easy to understand the code, either. I have trouble with understanding my own haskell code I wrote a few months ago.
I hate monad transformers...
And even in the community, you'll get exposed to a lot of experimentation, since again, Clojure is so expressive, you can experiment with all new abstraction, programming language ideas, constructs, etc. And those tend to get upvoted, because they are interesting, so you see a lot of that. It's tempting then to go back and use all that stuff or get inspired.
I liked the early days, there was a lot of that
But if you use Clojure in a KISS way. It stays really simple.
There's still quite a bit. But I think Covid got everyone jaded. I don't' see much action overall in the programming space since. Appart for AI 😛
I will do anything that pays a lot, but outside of that, I have my preferences. I like simplicity.
I think transducers are good for efficiency, but if you don't care about efficiency, you can skip transducers....
What I notice is in some sense, a lot of other language constrain you. Go gives you like 5 things and that's all, and you can't make your own. Some people like that, they need to be held back 😛.
Go is actually simple. I might consider it if Clojure wasn't a thing...
I don't like golang at all
I don't like Go, either, but it's at least simple.
If all you care is basic business value, then Go is totally fine.
that's true, I guess, not quite a turing tarpit, but how long did it take to get generics?
error-handling is so verbose or easy to get wrong
I think core.async.flow makes core.async error handling cleaner.
I'll have to try that out
I liked using channels and fibers in janet. Janet supervisors let me centralize channel errors in one place. core.async.flow is more centralized than janet supervisors.
Delivering business value today is better than learning new things that might be helpful in the future. You can easily learn new things for years without delivering any value.
those two things are not at odds unless you make it that way
I feel at some point, you also don't want things to be too dumbbed down. Like it has to meet you at your level. It's like a tricycle is simpler than a regular bicycle, but at some point you want to take sharper turns and it's like, dude I'm good, I can learn to balance and not hurt myself.
I'm often tempted to learn guile scheme and guix system, but I know they won't help with my business, and it will take months to learn them. So, I decided to give them up.
we needed to deliver authz business value, someone before I got here picked Cedar, which has a canonical rust impl and java bindings. I dove in, learned a lot and provided a lot of business value at the same time.
But a unicycle is just crazy lol, that's just too complicated, even for the best of them. So like you need to have the simplicity/complexity just right.
unicycles are simpler
but you can't go as fast
great analogy
Unicycles are not for most humans...
you can make sharper turns if you like doing that
Unicycles are for people who don't care about practicality.
Right, maybe unicycle are simplest, then bicycle, then tricycle, at least in construction. But then tricycle are easiest, then bicycle and then unicycle. Guess there's a balance in both.
In the same way, assembly is even simpler than C.
Assembly = unicycle.
it's just feet
Haskell and Rust = mad max
And then machine code 😛. It's just a wheel, no seat or pedals
Clojure = Toyota Rust, Haskell, Ada = Commercial airplane Toyota is fine for me.
Toyota camry is simple for drivers and does the job.
I don't need formula one racing cars with all the complexities exposed to the driver.
I actually would love windows and mac os as a user although I use linux. I hate using linux actually.... It exposes all the complexity to me. I use linux only because I hate being spied on.
I hate my life choices. Why did I learn linux?
As I grow older, I become less patient with complexity because I realized that complexity is just a fun distraction. The mind loves fun complex puzzles. gtrak loves fun puzzles. I don't anymore. I'm not a nerd anymore. Now, I just want out.
Bjarne Stroustrup regretted creating C++ due to its enormous complexity.
@gtrak You should meditate more. An overly stimulated mind seeks complexity and can't stop working when it should rest.
The overly active mind is trying to walk while it's sitting down on a chair.
I don't like all puzzles, but I'll solve them once to enforce an invariant I do care about forever
But you're right that maybe this is due to some predisposition. Yet, it's been good for me to embrace it sometimes and repress it other times.
Liking clojure is weird enough to start
And I think the number of people who are good at clojure but don't want to be doing it is orders of magnitude smaller
You have to be an enthusiast generally to be here at all
Screw invariants. GC is perfectly fine. I don't need to play chess against borrow checker's invariants.
Screw tokio. You can pry virtual threads off my cold dead hands.
Screw sigils.
The mind seeks unnecessary puzzles when it's bored. It suddenly doesn't mind Raku's complex sigils and Rust's borrow checkers and Haskell's complex type math.
Rust's GC-less memory safety may be beneficial in some areas which need safety and minimal memory consumption and maximum performance, such as pacemaker and spaceship controller. Outside that, Rust becomes unnecessary puzzle.
For the same reason, I avoid C, C++, and other low-level languages.
After all that complex haskell type math with GADT, higher-kinded types, monad transformers, and so on, you are still unsafe. A bad tradeoff.... After fighting Rust's borrow checker, you realize you can just use GC and never needed to fight it in the first place to get 64 bytes of memory. If you sacrifice freedom for safety(invariants), you lose both.
When does the pursuit of safety end? Are you going to write idris just to get more safety? Do you need to be buried alive in monad transformers? Do you really need the type system to enforce all the little invariants?
Just fire the gun in the general direction. Shoot.
Idris? Ada? Haskell? Rust?
These are all shitty static type languages which will be replaced by better static type langauges in the future.
The pursuit of safety leads to convoluted alien babies. Safety, my ass. Give me usability and simplicity. Developer experience(DX) matters.
DX and UX matter. Safety with great DX is okay.
Roc language aims to avoid shitty puzzles that usually come with other convoluted static type languages.
These complex static type languages were made by people with left-brain imbalance who can't stop craving fun puzzles. Shitty languages. The creator of C++ regretted C++. Haskell is a monstrosity. Ada is used by no one. Brainfuck joins the rank. If they meditated hard enough, they would never create monstrosities like C++, Ada, Brainfuck, Rust, Haskell, etc, ...
If you want a static type language. Roc language is a step in the right direction for static typing.
https://dev.to/pragma/haskell-is-a-bad-programming-language-2hc8
I propose all these complex statically typed languages are merely shitty research prototypes aiming for the simple final forms. We are their research subjects.
After all the safety measures, Rust libraries just panic!, and Haskell libraries throw poorly documented errors.
If I can get productive in a new language in a few weeks, it's not a big risk that it might get replaced with a better one. But, I think Rust (and java) will probably be around after I retire.
It's hard to learn new libraries in clojure, but it's not hard to do that in a static language
there are panic-free versions of most things if you care about that, but I don't for web code. I'm a pragmatist.
Zig would have you pass an allocator around to every call. Rust could force an error return of every allocating function, but that would be quite a mess
It looks a lot like exceptions but never mind the fact that they're exceedingly rare in comparison, and you can generally avoid them
For example, https://doc.rust-lang.org/std/boxed/struct.Box.html#method.try_new
It's simply a bad idea to throw safety out the window for the 80% case because it's possible to construct an overly-complicated program if you intend to break it.
Think of it this way, can your brain do a better job than a static analysis under the same constraints?
You're slower and you might miss something that it would never miss, or you might attend to the wrong thing.
Immutability good, static types bad, seems like a contradiction. Developers can be reliably disciplined about one and not the other for some completely subjective reason
I'll take all the help I can get, I'm dumber than the computer at scale
I don't index into vectors, I operate on the ends of them usually. I can use a result-returning function instead of the panicking one if I don't need the tiny bit of speed. The slow version is still 10x faster than java.
I wouldn't say static type bad. I'd say static type hinders expressivity and constraints code design and structure. And since it won't actually help with program correctness, does it do what it should, but just with type mismatches (well Rust it does a bit more which is nice, as it asserts ownership). But it means you still need to do as much testing as anything else. In that case, optimizing for testing is nice. REPL, fast compile and run cycles, etc.
Let's say there's an infinite amount of bugs you could write, but a tool exists that will prevent infinite slices of kinds of bugs within that infinity (eg, the even-numbered bugs will no-longer happen), but you don't know ahead of time if those are the kinds of errors you'll make. What ends up happening is your mind is free to think about other things.
There's still an infinite amount of bugs you could write, is it unsafe? It's more safe, for sure. Also you can't generate code fast enough.
I really like that when I'm learning a new library, I won't miss handling an edge-case. I guess it could panic if the memory suddenly grows 1000x more than I expect it to, but that would break every other language under consideration the same way.
panics are more like asserts
I think there's some risk to implicit ones, but if you want the program to crash because you don't expect that to happen, you have the ability to do that.
> you still need to do as much testing You might put the same effort into testing, but I think you'll end up testing more interesting stuff
You can't write senseless tests to begin with, they won't compile.
I do like clojure's homoiconicity for test data, specifically, but there's a json! macro that's good enough
For example, borrowing, ownership and move semantics enable you to write an API that will stop someone from accessing a file after it's closed. You don't need to remember to use with-open, ever. https://cliffle.com/blog/rust-typestate/#a-simple-example-the-living-and-the-dead
Is that not useful?
Resource management in our clojure is a nightmare, you have no idea. We have a really complicated variation of with-open that actually uses virtual threads to park cleanup methods.
We've spent person-months rewriting this and the code around it over and over for some reason https://github.com/jarohen/with-open?tab=readme-ov-file#usage
All the nested callbacks made debugging quite horrible. Plus most of the functions around the entry-point of the app are not regular functions, they're function-returning functions, returning a function that takes a callback. Then you use with-open+ to wrap code into function and pass it in as a resource context.
Here's what a similar pattern looks like in rust for otel spans, no callback or macro wrapping a callback needed:
let my_var: u64 = 5;
let my_span = span!(Level::TRACE, "my_span", my_var);
// `my_span` exists but has not been entered.
// Enter `my_span`...
let _enter = my_span.enter();
// Perform some work inside of the context of `my_span`...
// Dropping the `_enter` guard will exit the span.no-GC is actually a lot less cumbersome for some nontrivial expressivity
you can't do anything useful in a java finalizer
Maybe we didn't need to do that? Can't be sure.
if I want to stitch the span across threads, I just pass my_span into the new thread before entering it. It's quite obvious, no var-thread-local-binding conveyance.
Refcounts and RAII are a lot simpler than GC
To get otel into the clojure, I didn't have much fun replacing timbre with telemere for 2 weeks, I didn't even go as far as adding spans yet. Mostly that was due to walking back extra stuff we built on timbre. In rust it was about a day and a half, but it's a smaller codebase and I wrote most of it. Super fun, though.
My opinions were formed much earlier than this codebase I'm on today, but it isn't helping
In the vast majority of cases, I don't even need to know what the GC is doing.
Rust will probably be obsoleted by carbon or zig in 10~15 years.
Carbon has optional GC and doesn't have rust's cubersome borrow checker.
Rust doesn't do resource management for you, either. It only does memory management. No language that I know manages resources for you. Carbon won't do resource management for you. No language manages open files for you. Lack of resource management is not a reason to avoid clojure. It's a reason to avoid all programming languages.
You also aren't likely to need nested callbacks if you translated them into core.async.
If you want to disseminate Rust propaganda, don't do it here. I hate Rust.
Tired of resource managment? Rust. Tired of nested callbacks? Rust. Every road leads to Rust according to you.
I've worked in a lot of languages ¯\(ツ)/¯
Rust is just a failed research prototype.
Carbon is on the way. I still won't touch carbon, though.
doesn't seem like its design goals have anything to do with what I want out of a language
This is clojure community. If you don't particularly like clojure, you should find other communities and other jobs. Start finding a new job if clojure is not particularly good for you.
keep that focus and I hope the money comes
The way to handle asynchrony in clojure is not callbacks but core.async which you don't use widely.
In janet, I use only channels to handle concurrency and asynchrony. In clojure, it will be core.async channels.
If I didn't like Rust, should I go to Rust communities and complain about the flaws of Rust? Or, should I go to the community for a language that I like using? If you don't like something, don't come to its community and say you don't like it. Find another language you like, and go to its community. Complaining about something in its community is annoying. Don't try to directly convince others to stop using Rust, Clojure, or anything else because you don't like it. If you don't like clojure, maybe write an article about it. But, don't come to me and tell me I should stop using it. And, don't recommend Rust.
You are asking about basic testing strategy. I have been doing clojure for 15 years. I'm trying to have a civil discussion, but it's a waste of time.
It was a waste of time from the beginning.
If you are sick and tired of clojure, by all means, publish articles about your frustration, and find your better language. Just don't bother me with Rust, Haskell, or anything else I'm not likely to use in my lifetime.
Good luck avoiding it
I have my own reasons. You have your own reasons. No language is going to satisfy everyone.
I don't use clojure for everything. You don't use Rust for everything. Recommending Rust without knowing what I will write next is just useless.
Should I write Rust for my next command line script? No?
Don't use it either
Try to avoid using software written in it :)
It seems you just lack focus. Don't mention random things you are reminded of.
You have all the answers
Anyways 👋 I'm out
As I told you already, if you don't like clojure, find other communities instead of telling clojure community people to consider Rust or any other language. I wouldn't do that in Rust community or any other language community, either. Don't try to convince people to use other languages regardless of their choices. If they want to write cobol, let them. Shall I go to haskell community and tell people that haskell is a terrible language and they should consider Go?
Leave people alone. Let them use what they like.
I found Rust development to have a slower feedback cycle compared to the Clojure REPL The rust compiler does seem very smart though and Rust tools give accurate feedback through LSP. As the compiler is very strict by design and therefore needs more cpu cycles, it can feel slower for changes to run. The tooling around Rust does seem very robust. Although some of the community libraries haven't appreciated the value of avoiding breaking changes. In comparison to Java, Kotlin and C/C++/C# then Rust seems a valuable option to consider.
i would not describe “rust needs mutation for performance” as accurate, if people are micro-optimizing that much they’re using MaybeUninit and ptr::read. i think boats says it well: https://without.boats/blog/notes-on-a-smaller-rust/ > pure functional programming is an ingenious trick to show you can code without mutation, but Rust is an even cleverer trick to show you can just have mutation.
A lot of people just find it easier to program with mutation. I don’t think there’s anything wrong with giving them that tool, what Rust does is localize the mutation and make it harder for it to cause bugs
The borrow checker also does a very specific thing that’s hard to describe to people who haven’t programmed Rust … by rejecting so many valid programs, it forces your design away from object graphs and towards data driven design and very small structs. A lot of the Arc<Mutex> stuff people complain about comes up because people who are new to the language are still thinking in object graphs. I don’t think this is intrinsically good or bad, but it did reshape how I think about programs.
Actually just saw a trending hackernews article about adding GC to Rust 😛
hm, they forked rustc for this
reading
> It is unclear to us why this happens: we observe significant lock contention within BDWGC during GC collections i wonder if BDWGC is built on the assumption that finalizers are fast to run, that’s not always true for Drop
oh hm they changed all memory to be allocated in a generational arena > while we informally say that Box<T> allocates on the 'heap' and Gc<T> allocates on the 'GC heap', all allocations in Alloy are made through BDWGC and stored in the same heap. > > When used as a finalizer, Box<T>'s drop method is thus unneeded, as the underlying memory will be freed by BDWGC anyway
i think you could write this with #[global_allocator] but i’m starting to see why they forked the language
> The new compiler intrinsic needs_finalizer returns true if a finalizer is required for a type yup there it is
> we only insert fences for a Gc<T> if it has a finalizer. Intuitively, it seems that we should not generate drop methods in such cases, but this is difficult to do directly inside rustc this surprises me, i wonder if they were working with HIR instead of post-mono
i do know rustc assumes that DefIds exist from very early in compilation, but it’s possible to create shims that don’t have a DefId. maybe they didn’t know that.
yeah ok this works by adding a new MIR pass, that can add new metadata but it can’t add or remove items from the program
oh wow their GC type is Copy
uh
that’s a choice
even Arc isn’t Copy
i don’t understand their design goals
in any case, this changes the compiler extensively enough i don’t expect it to be upstreamed, not as-is anyway
there’s an existing library that does this in userspace less invasively, but no one uses it
Agree, I don't think this would make it into Rust. But it was the comments in hacker news I thought interesting, a lot of people seemed to enjoy Rust language design but not borrow checking. They like Trait based, functions in modules, hygienic macros, etc. And so were very interested of a Rust with GC and no borrow checking.
Your take is interesting though. That there is an appeal for Rust not because of performance, but because people prefer to program imperatively in terms of look and feel and abstraction, and Rust can make that safe.
I don't think I disagree. Even I've been experimenting with things like https://github.com/xadecimal/procedural
There are certain things that I think can provide good ergonomics if made safe.
Some that I've been wondering about are, early return/break, implicit function-level variable scope, traditional for-loops.
The ones that I'm not sold on, is anything that goes beyond a single function scope. I feel:
let a = (foo a)
is just nicer then:
(foo &mut a)
I feel most people who "like" the latter would get used to the former without issue.
well, consider the times when you might pass &mut a to a function. i implemented a C preprocessor that looked like this:
let mut stream = input.tokenize();
while let Some(token) = stream.next() {
match expand(token, &mut stream) {
Literal(t) => yield t,
Replacements(ts) => stream.push_front(ts),
}
}
you can't simply replace this with let stream = expand(token, stream) because the scopes aren't right. i guess you could replace it with stream = expand(token, stream) (i.e. passing stream by value, so you can't reuse it unless it's reassigned), but that just seems like &mut with more steps.in any case, with GC and no borrow-checker, Rust is really quite close to ocaml with better tooling and libraries. at that point it's lost most of its identity.
i've seen that! i think it's an interesting direction
i'm always amazed by the extent to which OCaml is really driven by jane street
I didn't work there, but I worked at a startup that used ocaml and their libraries for 5 years. I like rust more, but ocaml is nearly there.
Esteban Kuber (prolific rustc contributor, works mostly on diagnostics) has floated the idea for years of having an "easy rust" where type errors and borrow-checking are delayed to runtime so you can see an instance of what causes your assumptions to break
rustc's diagnostics are quite good but they have to be phrased as existential and universal types, whereas runtime errors can literally show you a stack trace of how your program breaks if a certain piece of code were allowed
this is kinda what people already do with Rc IMO, "easy rust" would basically just be wrapping everything in Rc<RefCell> for you so it's not so noisy
i actually implemented the start of it at one point but uh .... phrased it as slightly too much of a shitpost for people to take it seriously lol
I thought I wanted something like that in ocaml, and a repl, too, but it was just a skill issue
I stopped thinking I needed that after a while
idk. i don't think "it is possible to do things without nice tools" is an argument for not needing the tools
i like systems that scale both up and down, in the sense that they're nice to use for both beginners and experts
turning off the type system or something like laziness in clojure isn't doing anyone any favors
those things just need to work better
i am not sure what you mean by "work better" here
like this https://clojurians.slack.com/archives/C03RZGPG3/p1760638643426989?thread_ts=1760464964.839769&cid=C03RZGPG3 seems like a very hard constraint to me
even haskell has things like this btw https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/defer_type_errors.html
better ergonomics, yeah, not changing the behavior at the cost of making it unclear what it's doing
yeah, i see "easy rust" as a learning tool, not something you put in prod
but i don't think it's inherently worse than #[allow(warnings)] or something like that
@gtrak maybe another way to phrase this: rust is kinda like if you couldn't run your tests until you had added malli specs for all your functions
i think "running your tests" is more important than your program type checking
I write tests after, lol
lol
My workflow is to just make a huge mess, figure out what I'm missing to clean it up and actually ship it, and pretend it made sense with git hacks
lmao
i do something similar if i'm really prototyping — but that's exactly the point at which i find it more useful to run the tests than for it to type check!
> i guess you could replace it with stream = expand(token, stream) (i.e. passing stream by value, so you can't reuse it unless it's reassigned), but that just seems like &mut with more steps
That's where we can disagree, to me that's much more ergonomic and clear. Stream ownership moves to expand than back to me. Even for performance, I would have preferred:
expand(token, &mut stream) <-- compile error
stream = expand(token, &mut stream) <-- allowed
And I wonder if you'd need to delcare &mut at the callsite if that was the case. Rust could know to borrow or move based on the function definition. And it would still be visually explicit that stream is changed after the function call.
you can construct this API today in the existing language
fn expand(token: Token, stream: Stream) -> (Vec<TokenOrReplacement>, Stream);
it's just a mouthful
Only argument against I could see, is for "multiple return values" Not sure what the pattern is in Rust for that? Do people do:
let mut result1 = ...
let mut result2 = ...
foo(&mut result1, &mut result2)
?sometimes!
rust does allow you to return tuples, it's just annoying to work with functions like that
especially if one of the arguments is a Result
You could imagine a language with multiple return values, pattern matching to extract them, and no &mut, or only a &mut for performance on the definition, but call syntax is same for move or mutable borrow.
how would you distinguish call-by-value vs call-by-reference? without that distinction you can't have RAII, drop order is part of the semantics of the language
It's the same no?
i don't understand
one of the things that makes rust rust, and which i like most about it, is that it's very clear which functions mutate their arguments and which don't
Like Rust knows, because the function you call says if it's by value or reference.
well yes but it's no longer apparent from the call site
i like that it's apparent at the call site
It's still apparent, because the call site is forced to use the returned variable and no longer the passed in variable.
yeah ok i see, &mut is always replace with passing an owned value and reassigning. how does this deal with shared references (&) ?
& is probably still needed. But I don't mind it as much, because it's not like"mutation at a distance".
Though, I don't know, maybe something can be done with it too. But not sure
But you're right, resources might be the one thing that mutable move semantics are nice, and I'm not sure immutable functional semantics have a good solution for it. It's tricky, because a resource can't really be made immutable, so it's a bit of a curveball to functional immutable abstractions.
i'm trying to remember how clojure deals with this
generally you just have to remember to call close i think? and the API warns you to use with-open, yeah
that doesn't support complicated access patterns
Ya, basically. Manual close, or lexical close using with-open.
You can do thing like, auto-close on "consumed". But it doesn't work for all resources, they don't have a "consumed" state. A DB connection is never "consumed" for example.
Another example I gave elsewhere is core.async channels require you to call close, in rust if the receiver half of a channel goes out of scope or is dropped, it's closed and a send will get an error result