Is there a possibility you could change the title of the post to something relevant to its content? HN unfortunately has a policy against providing useful titles to links when page authors haven't done so themselves, and the intersection of people who will want to read your post and people who are interested in late medieval personal protective equipment is probably pretty low.
sadly, i clicked on it specifically because I was curious what PPE was available in the time of alchemy. what i found was boring code instead. 100% click-bait-n-switch
Me too! I mean I might be interested in object transmutation in Rust some of the time but not right now. Likely there are even more people in the converse situation, but they aren't the ones commenting on this thread.
HN policy also suggests using a representative phrase when the main title is misleading[1]; in this case the subtitle (The Path Towards Safer Transmute) seems suitable. (This can be changed either by the OP or by someone who bothers to email the moderators.)
I'd love an explanation of how bool bit validity causes undefined behavior. Does the compiler emit "jump if equal to 1" instructions instead of "jump if equal or above 1" when comparing operands?
The reserved values can be used as tags in outer enum types. For example `Option<bool>` might encode `None` as 2. If you did `Some(transmute::<bool>(2))` it'd turn into `None`.
UB has nothing to do with what the compiler emits. It's undefined behavior because the language says it's undefined behavior.
That said, "what may happen in practice" can be an interesting question, but any answer cannot be relied on to be the case, because it may change at any time. Looks like my sibling already gave you a possible thing that may happen.
That's complicated. Types as automata seems overkill.
"A type, Src, is transmutable into a type, Dst, if every possible value of Src is a valid value of Dst."
Do you really need that much generality? How about "A type is fully mapped if all bit patterns which can be stored in the type are valid values. Fully mapped types of equal length can be transmuted into each other. References are never valid values for this operation."
u8 through u128 are fully mapped, as are i8 through i128. Floats can be considered fully mapped.
Structs of those types with no padding and valid alignment are fully mapped.
This is enough to handle network packets, the main use case.
There are tons of network protocols where only certain bit patterns are admissible. The algorithm linked here is substantially more useful than just "your entire type has to be made of u8s"
You don't know on input if the bit pattern will be valid. If you're going to coerce raw bytes into it, the usual case for network protocols, you have to be prepared for any bit pattern.
TIL about bit_cast. You may be correct, checking out its docs.
The StackOverflow answer I just read comparing the two suggests bit_cast is a library function, transmute is an intrinsic. But transmute is const, and reinterpret_cast isn’t. So on some level it’s a mix of the two. Most important thing is that it’s closer to this kind of cast than a normal one.
Reminds me of how Haskell solved this problem [1] [2]
Haskell's solution is elegant, powerful, and straightforward. Roles make it all work without programmer trade-off. And nowadays, Coercible has been built upon to be a metaprogramming tool (-XDerivingVia).
21 comments
[ 7.8 ms ] story [ 57.4 ms ] thread[1] https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
That said, "what may happen in practice" can be an interesting question, but any answer cannot be relied on to be the case, because it may change at any time. Looks like my sibling already gave you a possible thing that may happen.
"A type, Src, is transmutable into a type, Dst, if every possible value of Src is a valid value of Dst."
Do you really need that much generality? How about "A type is fully mapped if all bit patterns which can be stored in the type are valid values. Fully mapped types of equal length can be transmuted into each other. References are never valid values for this operation."
u8 through u128 are fully mapped, as are i8 through i128. Floats can be considered fully mapped. Structs of those types with no padding and valid alignment are fully mapped. This is enough to handle network packets, the main use case.
Additionally, you often want to coerce from the constrained in-memory representation to the wire representation.
The StackOverflow answer I just read comparing the two suggests bit_cast is a library function, transmute is an intrinsic. But transmute is const, and reinterpret_cast isn’t. So on some level it’s a mix of the two. Most important thing is that it’s closer to this kind of cast than a normal one.
Looking forward to using this.
Haskell's solution is elegant, powerful, and straightforward. Roles make it all work without programmer trade-off. And nowadays, Coercible has been built upon to be a metaprogramming tool (-XDerivingVia).
[1] https://hackage.haskell.org/package/base-4.20.0.1/docs/Data-...
[2] https://www.seas.upenn.edu/~sweirich/papers/coercible-JFP.pd...
> Safe Zero-cost Coercions for Haskell