Hacker News
A Gopher Meets a Crab
joshka
|next
[-]
Result<Option<Result<Message, WsError>>, Elapsed>
That’s three independent “not the happy path” channels: timeout, stream closed,
and websocket error.The nicer version is not a cleverer match. It’s choosing a domain error shape and converting into it one layer at a time:
let timed = tokio::time::timeout(duration, receiver.next()).await;
let next = timed.map_err(|_| ReceiveError::Timeout)?;
let item = next.ok_or(ReceiveError::Closed)?;
let msg = item.map_err(ReceiveError::WebSocket)?;
The ugly line is what happens when you have not decided where to normalize the
shape yet.
loeg
|root
|parent
|next
[-]
Result<(), ()>
Is pretty weird, though, no? Why would you want a unit value / error type?
MrJohz
|root
|parent
|next
[-]
That said, a couple of the examples here feel a bit strange - they're clever things you can do, but they're not necessarily things you often have to do, particularly for a relatively simple task like this. I think the problem with the author's approach is that they can't distinguish between "weird because Rust is weird" and "weird because the LLM generated bad code", because they (understandably) don't have enough experience in what good Rust code looks like.
nasso_dev
|root
|parent
|next
|previous
[-]
this lets you implement `std::error::Error`, which you really should to make it less painful when you want to erase the type (`std::error::Error` is `dyn`-compatible)
2ndorderthought
|root
|parent
|next
|previous
[-]
Sure this is something someone can do but it's suggesting the caller doesn't care about why it failed and doesn't need anything from it's success. It's a choice but it's not a typical one. Maybe the fact that it looks weird and there is no comment is a clue that this isn't high quality code.
People really should be more skeptical of LLM coding. Claude is not as amazing as marketing makes it sound. It is amazing in that it can write code and follow specs sometimes, but a lot of quality gets lost along the way without close supervision by someone who knows better
simianwords
|root
|parent
|next
|previous
[-]
joshka
|root
|parent
|next
[-]
saagarjha
|next
|previous
[-]
hnlmorg
|root
|parent
|next
[-]
So getting an LLM to write an example project then dissecting the code and interrogating those choices, seems like a very good way to learn the idioms of another language.
2ndorderthought
|root
|parent
|next
[-]
hnlmorg
|root
|parent
[-]
Syntax is the easy stuff to learn. It’s any shifts in paradigms (eg pure functional vs imperative vs logic… etc) that takes time to learn.
And I say this as someone who’s written professional software in well over a dozen different languages. So I understand well the challenges learning something new.
2ndorderthought
|root
|parent
[-]
I have also trained people who were good to decent software engineers in other languages to write rust. The syntax is nontrivial for a lot of people. There are a lot of people who gave up trying to learn rust, especially before the rust book became what it is today.
People typically fight the borrowchecker until it clicks. Learning from an LLM and reading only means you have to be as good as the rust compiler without any experience writing the language. It's got to be way harder that way.
saagarjha
|root
|parent
|previous
[-]
hnlmorg
|root
|parent
[-]
Go and Rust have different idioms and syntax. But they occupy broadly similar paradigms.
For example, you don’t need to relearn how to do iteration like you would with a logic or pure functional language. You wouldn’t need to concepts like methods, like you would if you were coming from a stack based language. Etc
commandersaki
|root
|parent
|next
|previous
[-]
atorodius
|root
|parent
|next
|previous
[-]
It is more like you wanting to build a bed out of wood so you hire a carpenter and watch them and ask questions about every step and maybe help a bit at the end.
I find it amazing to learn new programming things
victorbjorklund
|root
|parent
|next
|previous
[-]
2ndorderthought
|root
|parent
[-]
hnlmorg
|root
|parent
[-]
This isn’t like learning JavaScript and then expecting to be an expert in Prolog.
2ndorderthought
|root
|parent
[-]
Some people adapt to it more easily, especially coming from languages like scala but it has a lot of unique characteristics that aren't in C or are even related. Like lifetimes, dynamic dispatch through enums, the borrowchecker, pattern matching, the ? Operator, etc.
Maybe you all are way smarter than me, super possible, but I wouldn't expect much to translate between go and rust. I think some evidence for that is the blog post here...
huqedato
|next
|previous
[-]
2ndorderthought
|root
|parent
[-]
So which is it?
The answer is rust has very little in common with go. Rust is very explicit and go is not. Some people find the explicit nature of rust and it's guarantees refreshing. Other people find go refreshing because the syntax is more limited and it looks simple on paper.
RobotToaster
|next
|previous
[-]
coqadoodle
|root
|parent
|next
[-]
SyneRyder
|root
|parent
|previous
[-]
wiseowise
|next
|previous
[-]
cenamus
|root
|parent
[-]
tialaramex
|root
|parent
|next
[-]
The blog post uses, among other things, the Try operator ? and pattern matching, neither of which are available in C++ and both of which make the Result type much nicer to use than std::expected. There have been similar "I saw it in a shop window" proposals for both these in C++, and I expect that pattern matching in particular will be attempted again targeting C++ 29.
nothinkjustai
|previous
[-]
a) Vibe coding produces bad code
b) Rust is weird
Somehow we’re supposed to accept b as the answer? Give me a break….