Readit News logoReadit News
robviren · 24 days ago
I find the dependency creep for both rust and node unfortunate. Almost anything I add explodes the deps and makes me sweat for maintenance, vulnerabilities, etc. I also feel perpetually behind, which I think is basically frontend default mode. Go does the one thing I wish Rust had more of which is a pretty darn great standard library with total backwards compatibility promises. There are awkward things with Go, but man, not needing to feel paranoid and how much can be built with so little feels good. But I totally understand just getting crap done and taking off the tin foil. Depends on what you prioritize. Solo devs don't have the luxury.
slopinthebag · 24 days ago
Those deps have to come from somewhere, right? Unless you're actually rolling your own everything, and with languages that don't have package managers what you end up doing is just adding submodules of various libraries and running their cmake configs, which is at least as insecure as NPM or Crates.io.

Go is a bit unique a it has a really substantial stdlib, so you eliminate some of the necessary deps, but it's also trivial to rely on established packages like Tokio etc, vendor them into your codebase, and not have to worry about it in the future.

ajross · 24 days ago
> Those deps have to come from somewhere, right? Unless you're actually rolling your own everything

The point is someone needs to curate those "deps". It's not about rolling your own, it's about pulling standard stuff from standard places where you have some hope that smart people have given thought to how to audit, test, package, integrate and maintain the "deps".

NPM and Cargo and PyPI all have this disease (to be fair NPM has it much worse) where it's expected that this is all just the job of some magical Original Author and it's not anyone's business to try to decide for middleware what they want to rely on. And that way lies surprising bugs, version hell, and eventually supply chain attacks.

The curation step is a critical piece of infrastructure: thing things like the Linux maintainer hierarchy, C++ Boost, Linux distro package systems, or in its original conception the Apache Foundation (though they've sort of lost the plot in recent years). You can pull from those sources, get lots of great software with attested (!) authorship, and be really quite certain (not 100%, but close) that something in the middle hasn't been sold to Chinese Intelligence.

But the Darwinian soup of Dueling Language Platforms all think they can short circuit that process (because they're in a mad evangelical rush to get more users) and still ship good stuff. They can't.

Mond_ · 24 days ago
The tradeoff Go made is that certain code just cannot be written in it.

Its STD exists because Go is a language built around a "good enough" philosophy, and it gets painful once you leave that path.

GuB-42 · 24 days ago
It is more of a cultural thing. Package managers encourage lots of dependencies while programmers using language with no package managers will often pride themselves in having as few dependencies as possible. when you consider the complete graph, it has an exponential effect.

It is also common in languages without package managers to rely on the distro to provide the package, which adds a level of scrutiny.

kcexn · 24 days ago
Technically it's the same. But behaviorally it's not. When pulling in more dependencies is so easy, it's very hard to slow down and ask the question do we need all of this?

Mucking around with cmake adds enough friction that everyone can take a beat for thoughtful decision-making.

pjerem · 24 days ago
> Go is a bit unique a it has a really substantial stdlib

It’s not that unique though. I can say that Python and hell, even PHP have pretty complete but also well documented stdlib.

Java is meh tier but C# is also pretty good in this aspect.

It’s totally a choice for Rust not to have a real stdlib and actually I feel like that would maybe make Rust maybe the best language overall.

bryanlarsen · 24 days ago
Python used to have a great standard library, too. But now it's stuck with a bunch of obsolete packages and the packaging story for Python is awful.

In a decade or so Go the awkward things about Go will have multiplied significantly and it'll have many of the same problems Python currently has.

xnyan · 24 days ago
> the packaging story for Python is awful.

Big caveat that this is just for me personally, but uv has fixed this for me personally. Game changing improvement for Python. Appropriately, uv is written in rust.

mixmastamyk · 24 days ago
Lots of removals have already happened and uv took over packaging in Python-land.
__mharrison__ · 24 days ago
I just ported (this week) a 20-year-old Python app to uv/polars. (With AI it took two days). App is now 20x faster.
SPBS · 23 days ago
> In a decade or so Go the awkward things about Go will have multiplied significantly and it'll have many of the same problems Python currently has.

The stdlib packages are far better designed in Go than in Python. “The standard library is where packages go to die” is literally not a thing in Go, in fact quite the opposite.

tasn · 24 days ago
These are two sides of the same coin. Go has its quirks because they put things in the standard library so they can't iterate (in breaking manners), while Rust can iterate and improve ideas much faster as it's driven by the ecosystem.

Edit: changed "perfect" to "improve", as I meant "perfect" as "betterment" not in terms of absolute perfection.

aatd86 · 24 days ago
There is a moral hazard here. By accepting that APIs are forever, you tend to be more cautious and move toward getting it right the first time. Slower is better... And also faster in the long run, as things compose. Personally, I do believe that there is one best way to do things quite often, but time constraints make people settle.

At least it is my experience building some systems.

Not sure it is always a good calculus to defer the hard thinking to later.

JetSetIlly · 24 days ago
The golang.org/x/ namespace is the other half of the standard library in all but name. That gets iterated often.

For stuff in the standard library proper, the versioning system is working well for it. For example, the json library is now at v2. Code relying on the original json API can still be compiled.

strawhatguy · 24 days ago
Iterating often is not helpful for stable systems over time.

I like go's library it's got pretty much everything needed out of the box for web server development. Backwards compatibility is important too.

incrudible · 24 days ago
The cost of "perfecting" an idea here is ruining the broader ecosystem. It is much much better for an API to be kinda crappy (but stable) for historical reasons than dealing with the constant churn and fragmentation caused by, for example, the fifth revision of that URL routing library that everyone uses because everyone uses it. It only gets worse by the orthogonal but comorbid attitude of radically minimizing the scope of dependencies.
onyx228 · 24 days ago
The dependency creep keeps on happening in web frameworks where ever you look.

I was thinking of this quote from the article:

> Take it or leave it, but the web is dynamic by nature. Most of the work is serializing and deserializing data between different systems, be it a database, Redis, external APIs, or template engines. Rust has one of the best (de)serialization libraries in my opinion: serde. And yet, due to the nature of safety in Rust, I’d find myself writing boilerplate code just to avoid calling .unwrap(). I’d get long chain calls of .ok_or followed by .map_err. I defined a dozen of custom error enums, some taking other enums, because you want to be able to handle errors properly, and your functions can’t just return any error.

I was thinking: This is so much easier in Haskell.

Rather than chains of `ok_or()` and `map_err()` you use the functor interface

Rust:

``` call_api("get_people").map_or("John Doe", |v| get_first_name(v)).map_or(0, |v| get_name_frequency(v)) ```

Haskell:

``` get_first_name . get_name_frequency <$> callApi "get_people" ```

It's just infinitely more readable and using the single `<$>` operator spares you an infinite number of `map_or` and `ok_or` and other error handling.

However, having experience in large commercial Haskell projects, I can tell you the web apps also suffer from the dreaded dependency explosion. I know of one person who got fired from a project due to no small fact that building the system he was presented with took > 24 hours when a full build was triggered, and this happened every week. He was on an older system, and the company failed to provide him with something newer, but ultimately it is a failing of the "everything and the kitchen sink" philosophy at play in dependency usage.

I don't have a good answer for this. I think aggressive dependency reduction and tracking transitive dependency lists is one step forward, but it's only a philosophy rather than a system.

Maybe the ridiculous answer is to go back to php.

zozbot234 · 24 days ago
Rust has trouble supporting higher-kinded types like Functor (even though an equivalent feature is available, namely Generic Associated Types) due to the distinctions it makes between owned and referenced data that have no equivalent in Haskell. Whether these higher abstractions can still be used elegantly despite that complexity is something that should be explored via research, this whole area is not ready for feature development.
instig007 · 24 days ago
> I know of one person who got fired from a project due to no small fact that building the system he was presented with took > 24 hours when a full build was triggered, and this happened every week.

Incremental Nix builds can take less than 1 munute to build everything, including the final deployable docker image with a single binary on very large Haskell codebases. That fact the the person was fired for everybody around him systematically failing to admit and resolve a missing piece of supportive infrastructure for the engineering effort of one person tells a lot about the overall level of competence in that team.

> but ultimately it is a failing of the "everything and the kitchen sink" philosophy at play in dependency usage.

Not really, as the kitchen sink only has to build once per its version change, for all future linkage with your software for the entire engineering team doing the builds in parallel.

slopinthebag · 24 days ago
24 hours? is the haskel compiler written in javascript running in a python js-interpreter written in bash?
loglog · 24 days ago
php is the only popular language that regularly removes insane legacy cruft (to be fair, they have more insane cruft than almost any other language to begin with).
TheDong · 24 days ago
I've found Go's standard library to be really unfortunate compared to rust.

When I update the rust compiler, I do so with very little fear. My code will still work. The rust stdlib backwards compatible story has been very solid.

Updating the Go compiler, I also get a new stdlib, and suddenly I get a bunch of TLS version deprecation, implicit http2 upgrades, and all sorts of new runtime errors which break my application (and always at runtime, not compiletime). Bundling a large standard library with the compiler means I can't just update the tls package or just update the image package, I have to take it or leave it with the whole thing. It's annoying.

They've decided the go1 promise means "your code will still compile, but it will silently behave differently, like suddenly 'time1 == time2' will return a different result, or 'http.Server' will use a different protocol", and that's somehow backwards compatible.

I also find the go stdlib to have so many warts now that it's just painful. Don't use "log", use "log/slog", except the rest of the stdlib that takes a logger uses "log.Logger" because it predates "slog", so you have to use it. Don't use the non-context methods (like 'NewRequest' is wrong, use 'NewRequestWithContext', don't use net.Dial, etc), except for all the places context couldn't be bolted on.

Don't use 'image/draw', use 'golang.org/x/image/draw' because they couldn't fix some part of it in a backwards compatible way, so you should use the 'x/' package. Same for syscall vs x/unix. But also, don't use 'golang.org/x/net/http2' because that was folded into 'net/http', so there's not even a general rule of "use the x package if it's there", it's actually "keep up with the status of all the x packages and sometimes use them instead of the stdlib, sometimes use the stdlib instead of them".

Go's stdlib is a way more confusing mess than rust. In rust, the ecosystem has settled on one logging library interface, not like 4 (log, slog, zap, logrus). In rust, updates to the stdlib are actually backwards compatible, not "oh, yeah, sha1 certs are rejected now if you update the compiler for better compile speeds, hope you read the release notes".

throwaway894345 · 24 days ago
Man, I've been using Go as my daily driver since 2012 and I think I can count the number of breaking changes I've run into on one finger, and that was a critical security vulnerability. I have no doubt there have been others, but I've not had the misfortune of running into them.

> Don't use "log", use "log/slog", except the rest of the stdlib that takes a logger uses "log.Logger" because it predates "slog", so you have to use it.

What in the standard library takes a logger at all? I don't think I've ever passed a logger into the standard library.

> the ecosystem has settled on one logging library interface, not like 4 (log, slog, zap, logrus)

I've only seen slog since slog was added to the standard library. Pretty sure I've seen logrus or similar in the Kubernetes code, but that predated slog by a wide margin and anyway I don't recall seeing _any_ loggers in library code.

> In rust, the ecosystem has settled on one logging library interface

I mean, in Rust everyone has different advice on which crates to use for error handling and when to use each of them. You definitely don't have _more standards_ in the Rust ecosystem.

ceteia · 24 days ago
> When I update the rust compiler, I do so with very little fear. My code will still work. The rust stdlib backwards compatible story has been very solid.

This is not always true, as seen with rustc 1.80 and the time crate. While it only changed type inference, that still caused some projects like Nix a lot of trouble.

spartanatreyu · 24 days ago
FYI: Deno includes:

1. The web standard APIs themselves 2. It's own standard library inspired by Go's standard library (plus some niceties like TOML minus some things not wanted in a JS/TS standard library since they're already in the web standard APIs) 3. Node's standard library (AKA: built-in modules) to maintain backwards compatibility with node.

Bun has 1 and 3, and sort of has it's own version of 2 (haphazard, not inspired by go, and full of bun-isms which you may like but may not, but standard database drivers is nice).

rubyn00bie · 24 days ago
Honestly this is one of the biggest reasons I stick with Elixir. Between Elixir’s standard library, the BEAM/OTP, and Phoenix (with Ecto)—- I honestly have very few dependencies for web projects. I rarely, at this point, find the need to add anything to new projects except for maybe Mox (mocking library) and Faker (for generating bits of test data). And now that the Jason (JSON) library has been more or less integrated into OTP I don’t even have to pull it in. Elixir dev experience is truly unmatched (IMHO) these days.
ngrilly · 24 days ago
Same. That’s why Go is such a great tool.
Grimburger · 24 days ago
A Tauri hello world app has about 500(?) deps out of the box, always makes me laugh.

I get that cross platform desktop app is a complicated beast but it gives off those creepy npm vibes.

pstuart · 24 days ago
With Go it's good to keep in mind the Proverbs, which includes this gem:

  A little copying is better than a little dependency.

Ygg2 · 24 days ago
Good luck, if little copying is ICU based localization.
totally-a-human · 24 days ago
I work on a large mixed Rust/C systems codebase — been converting it piece by piece for a couple years now. The author's frustrations are legit, but I think the real question is simpler: how expensive are your bugs?

If a bug in your system means silent data corruption that nobody notices for a week — and I've lived this — Rust is worth every second of compile time. If a bug means a 500 and you redeploy, you're paying for insurance you don't need. Different worlds, different tools.

The thing I actually love about Rust — and this sounds weird — is how it handles failure. In C, every function call is an implicit "and also maybe something went horribly wrong, but let's just hope it didn't." You get used to it. You stop seeing it. Then one day you're staring at a corruption bug and you trace it back to an error return that got silently swallowed six call sites ago, and you feel physically ill. Result types are annoying when you're validating form input. They're a gift from god when you're the one who has to explain why someone's data is gone.

But yeah, for web stuff? Just use TypeScript. Life's too short to fight the borrow checker over a blog.

anon-3988 · 24 days ago
> But yeah, for web stuff? Just use TypeScript. Life's too short to fight the borrow checker over a blog.4

I am not sure about TypeScript. I think having static typing is just too good of an insurance against stupid bug and for your own sanity. I think for web purposes, especially with LLM around, you probably should just use Go. You don't have to like it, but there's enough training dataset for your CRUD application. So all you really need to do is to be able to read it.

Rohansi · 24 days ago
> I am not sure about TypeScript. I think having static typing is just too good of an insurance against stupid bug and for your own sanity.

TypeScript has static typing though?

danny_codes · 24 days ago
Typescript has static typing. It’s called typescript..
chrash · 24 days ago
the idea of one language to rule them all is very compelling. it’s been promised a lot, and now everyone hates Java.

but the truth is that Rust is not meant for everything. UI is an abstraction layer that is very human and dynamic. and i can come and say, “well, we can hide that dynamism with clever graph composition tricks” à la Elm, React, Compose, etc, but the machinery that you have to build for even the simplest button widget in almost every Rust UI toolkit is a mess of punctuation, with things like lifetimes and weird state management systems. you end up building a runtime when what you want is just the UI. that’s what higher level languages were made for. of course data science could be done in Rust as well, but is the lifetime of the file handle you’re trying to open really what you’re worried about when doing data analysis?

i think Rust has a future in the UI/graphics engine space, but you have to be pretty stubborn to use it for your front end.

bryanlarsen · 24 days ago
Rust is "Jack of all trades, master of some".

There are real advantages to choosing a jack of all trades language for everything; for example it makes it easier for an engineer on one part of your project to help out on a different part of your project.

But it sounds like the OP didn't get any of the benefits of "jack of all trades", nor did he choose a field where Rust is "master of some".

bitwize · 24 days ago
Lisp is the master of all. Or it would be except "Parens? Eugh! Brotha, eugh!"
tormeh · 24 days ago
How much of that is just because Rust UI libraries are not ready, though? It's never going to become Python, but it could become decent.
riku_iki · 23 days ago
> and now everyone hates Java

speak for yourself :-)

But sadly Java can't rule them all because there is no browser story and no IOS story.

mrbluecoat · 24 days ago
Better title: "Farewell, Rust for Web"
porcoda · 24 days ago
Yes. This is one of the things that drives me nuts about a lot of titles on here: the context like “for the web” changes how it’s is interpreted a great deal. I see the same thing when I see posts about other languages and AI and such. Context matters versus making it sound like a broad, general statement. Alas, the broad, general statements likely get more engagement..
pseudalopex · 24 days ago
Farewell, Rust for Web was a worse title. I thought it meant Rust ended WebAssembly support.
bigstrat2003 · 24 days ago
Agreed! The context matters a lot. Rust is a great language, but using it for the web is a poor choice just like using JS outside the web is a poor choice. Programming languages all have domains where they do well or poorly, and trying to make a single language work for all cases is a fool's errand.
testdelacc1 · 24 days ago
Yeah Astro is a great choice for a static or mostly static website. Moving to Astro is not a slight on any other language or framework.
NewJazz · 24 days ago
Aiui they are also migrating their backend api(s) from rust to node. They were already using astro with rust on the backend (after dropping ssr with tera).
dang · 24 days ago
Ok, we'll use that above. Thanks!
NewJazz · 24 days ago
due to the nature of safety in Rust, I’d find myself writing boilerplate code just to avoid calling .unwrap(). I’d get long chain calls of .ok_or followed by .map_err. I defined a dozen of custom error enums, some taking other enums, because you want to be able to handle errors properly, and your functions can’t just return any error.

This can be a double edged sword. Yes, languages like python and typescript/JavaScript will let you not catch an exception, which can be convenient. But that also often leads to unexpected errors popping up in production.

grim_io · 24 days ago
Often is not the word I'd use, from my experience.

The times something like that happened to me AND wasn't a trivial fix can be counted on half a hand. A tradeoff I'd take any day to not have to deal with rust all of the time.

imtringued · 24 days ago
Java exceptions usually have way more context to the point where I loathe every single developer who decided to catch an exception and only log the top level message.

Having a long ass chain of 10 nested exceptions might be overwhelming to a beginner, but an experienced developer knows which types of exceptions are caused by what and instinctively tunes out the irrelevant ones and goes straight to the source of the problem since the stack trace directly tells you which chain of calls caused the issue.

wofo · 24 days ago
I'm a heavy Rust user and fan, but I'd never pick Rust for web. There are way more mature ecosystems out there to choose from. Why would you waste "innovation tokens" in a Rust-based web application?
u16 · 24 days ago
I enjoyed using Rust/WASM for a web application I made. Once I got the build step figured out, which took a week, the application worked like I wanted right away.

I was trying to build an HTML generator in Rust and got pretty far, but I don't think I'll ever be happy with the API unless I learn some pretty crazy macro stuff, which I don't want. For the latter project, the "innovation tokens" really rings true for me, I spent months on the HTML gen for not much benefit.

jmalicki · 24 days ago
For a web backend? Rust is pretty mature there, it doesn't even feel like an innovation token - it's by my favorite thing to use Rust for.

You have very mature webservers, asyncio, ORMs, auth, etc., it's very easy to write, and the type safety helps a ton.

In 2020 it might have taken some innovation tokens, but the only things that require a ton less (for web backend) are probably Java, python, and node.js, and they all have their unique pain points that it doesn't seem at all crazy?

wofo · 24 days ago
It's been a while since I last had a detailed look at web applications in Rust (i.e., stuff with databases, auth, etc). You could use axum for the web server, which is very mature, but I'd say it's too low-level (IIRC you cannot even generate an OpenAPI spec of your endpoints, which IMO is table-stakes). Have you found something more batteries-included, with a similar level of maturity, and actively maintained by a community you can trust? It's a very high bar.

Your reply made me curious about ORMs, btw. Which one would you recommend? Maybe things have improved since I last checked. Last time I didn't like any of them and ended up settling on `sqlx` + hand-written SQL (the code is open source, hosted at https://github.com/rustls/rustls-bench-app/tree/main/ci-benc...).

rtpg · 24 days ago
I think there's a couple stories of people shipping some performant "webapp"-y stuff in Rust... but of course you can just compile those kinds of components and write the rest of your app in any other system
daxfohl · 24 days ago
Good to know! You probably saved me a lot of pain.
tracker1 · 24 days ago
I would assume today that maybe Dioxus or Leptos would be considered. Though that would be the "all in" approach on Rust front to back... it wouldn't really reduce some of the handling conditions levied in the article though.

I find C# can be a really good middle ground on the backend (not a blazor fan)... the syntax and expressiveness improves with every release. You can burrow as lot of patterns from the likes of Go as well as FP approaches. What I don't care for are excessively complex (ie: "Enterprise") environments where complexity is treated like a badge of honor instead of the burden of spaghetti that it is in practice.

andrewaylett · 24 days ago
It's a throwaway comment in the article, but I feel it's important to push back on: HTML is very definitely a programming language, by any reasonable definition of "programming language".

Edit to add: It might not be an imperative language, but having written some HTML and asked the computer to interpret it, the computer now has a programmed capability, determined by what was written, that's repeatable and that was not available apart from the HTML given. QED.

tracker1 · 24 days ago
How would one do an if condition or enumerate a list in HTML alone? For that functionality you need another language to generate/manipulate the HTML.. not to mention interpreting HTML for display.

HTML is a markup language, it's even in the name... but it's not a complete programming language by any stretch.

andrewaylett · 24 days ago
It's not Turing-complete, and as you say, it's a markup language and it's not general purpose. But neither is a necessary component of "programming language".
pie_flavor · 24 days ago
HTML requires you to understand symbolic representations, where <> means something special. It is more verbose, but no more structurally complex, than Markdown. It does not require you to understand imperative dynamic logic. Getting the hang of symbolic representations is easy, and getting the hang of imperative programming is very hard and most people can't do it. That's why the dividing line is where it is. Making a static bulleted list isn't a 'capability' in HTML if you weren't thinking it was one in Markdown, and inventing your own precisely crafted definition with no purpose other than to include HTML then calling all others unreasonable doesn't convince anyone.
Dylan16807 · 24 days ago
Please explain how your edit doesn't apply to a .txt file
zem · 24 days ago
agreed, it's a hill i am very willing to die on too.
mr_00ff00 · 24 days ago
So is Markdown a programming language? Any logic for html, is therefore Markdown as well.