Top
Best
New

Posted by lukastyrychtr 5 days ago

Weird Expressions in Rust(www.wakunguma.com)
192 points | 150 commentspage 2
pluto_modadic 5 days ago|
I've absolutely seen some /cursed/ rust one liners.

if you extend it to the most cursed ~6 lines of code, you really can obfuscate what you're doing in a way that's fiendishly hard to debug.

sureglymop 5 days ago||
With yesterdays release let chains got released. Really needed feature but can sometimes look pretty cursed: https://blog.rust-lang.org/2025/06/26/Rust-1.88.0/#let-chain...
behnamoh 5 days ago||
Great, now this stuff gets fed into LLM trainings and we'll see them in the next-gen model outputs.

Seriously though, I love "abusing" programming languages in unexpected ways. My favorite so far is: https://evuez.net/posts/cursed-elixir.html. Reading this made me realize Elixir is literally macros all the way down, and it's a Lisp!

nfrmatk 5 days ago||
There's a fun RustConf talk on this topic from a few years ago. https://youtu.be/tNVDjMxCz-c
Sniffnoy 5 days ago||
I don't understand the one with dont(). Why does i.get() end up false at the end? Shouldn't it be true after having been set by dont()?
LegionMammal978 5 days ago|
The final line "assert!(i.get());" asserts that i.get() is true in the end. The ! character here belongs to the assert! macro, not a boolean negation. (This unfortunately gets a bit weird-looking when you want to write sensible stuff like "if !matches!(x, Some(5..=10)) { ... }".)
Sniffnoy 5 days ago||
Oops, I see, thanks!
IshKebab 5 days ago||
Honestly I'm surprised how not weird these are. Way less WTFy than Javascript, PHP, C or C++.
dathinab 5 days ago|
yes but to be fair the blog is focused on unusual aspects of everything being an expression

you still can create some more confusing things by idk. overloading some operators (but luckily not `=` and similar crazy C++ things) adding recursive macros and maybe combining it with lifetime variance and coercion edge cases, maybe sprinkle in some arcane `#[]` annotations and people with be very confused, more so then in the article

IshKebab 5 days ago||
Yeah... I'm just saying I haven't seen anything close to these things:

https://github.com/denysdovhan/wtfjs

https://github.com/satwikkansal/wtfpython

keybored 5 days ago||
Once I tried how many `{{{...}}}` I needed to make javac crash. It wasn’t that many.
bensons1 5 days ago||
I am sort of amused, a memory safe language deploys this sort of juggling
npalli 5 days ago||
yeah this is good, but now add lifetime annotations to have fun.
steveklabnik 5 days ago|
Lifetimes are not expressions and therefore can't really be put into odd places.
Thaxll 5 days ago|
Why assigning a variable to a function that returns nothing is not a compilation error?
tialaramex 5 days ago||
Do you mean a function which returns "nothing" in the sense that it does return but it has no particular value to return, like Vec::clear which gets rid of the values but preserves the capacity of the container ?

In Rust the return type of this function is the unit type, the empty tuple (). So, the variable has this type, there's no problem with this in Rust, even though some lesser languages can't handle the idea of a type this small.

Or did you mean a function which never returns, like std::process::exit ? In Rust this function's return type is ! the Never type, an empty type that you ordinarily can't name in stable Rust.

Because this type is empty, a variable of this type will evaporate, the compiler knows that we can't bring values into existence if there are no values of that type, the code paths in which this variable exists will never be executed, so no need to emit machine code.

In a language with generic programming like Rust this isn't an error, it's actually a convenience. We can write generic error handling code, and then for cases where there will never be an error our error handling code doesn't even compile, it evaporates entirely, yet for cases which can have actual errors, the error handling code is emitted.

dathinab 5 days ago|||
assuming you mean returning () (the empty tuple/void type)

because it doesn't compose well with generics, macros, proc-macros etc.

e.g. if you have this dump way to wrap clone: `fn foo<T: Clone>(v: T) -> (T, T) { let new = v.clone(); (v, new) }` it would implicitly not work with T = (), because then `v.clone()` would be a "function which returns nothing".

In isolation this might seem fine but if you compose abstractions you sooner or later run into an edge case where it isn't fine.

And this becomes even more a problem when macros/proc-macros are involved.

It also makes changing code easier, lets say you have something like `let x = foo(); dbg!(x);` and you change the return type it will keep compiling as long as the type implements `Debug`, even if you change the type to `()` (i.e. return nothing). And again for normal code that is a minor nit pick, but for macros, proc macros, generic code of sufficient complexity sooner or later you run into edge cases where it really matters that it's allowed. Not often but often enough.

Lastly and most importantly assigning `()` to a variable hurts no one, you won't see any such code in normal PRs.

So it it doesn't hurt anyone but can be quite use full in edge cases.

Lastly linters (mainly clippy) do warn or error for some of this nonsensical things, depending on the lint-set you enabled.

assbuttbuttass 5 days ago|||
There's no such thing as a "function that returns nothing" in Rust. Unit, written as (), is a first class value and can be assigned to a variable, although there's not much point
steveklabnik 5 days ago||
Which example are you referencing?
More comments...