3 ms·
Here’s my take. I haven’t used this feature yet so I haven’t dug in too deep. drink() takes a Drinkable. A Drinkables can be non-copyable. Copyable is the def
by MBCook 2y ago
Here’s my take. I haven’t used this feature yet so I haven’t dug in too deep.
drink() takes a Drinkable. A Drinkables can be non-copyable.
Copyable is the default, so it has to mark itself as accepting non-copyables.
Coffee is non-copyable. Water doesn’t say which means it’s copyable (the default).
You can use a copyable anywhere you’d use a non-copyable since there is no restriction. So since drink can take non-copyables it can also use copyables.
I’m guessing the function definition has to list non-copyable otherwise it would only allow copyable drinks since the default is all variables are copyable.
“consuming some” means the function takes over the ownership of the non-copyable value. It’s no longer usable in the scope that calls drink().
For the copyable value I’m not sure but since they can be copied I could see that going either way.
On syntax:
Yeah it’s a bit weird, but there was a big debate about it. They wanted something easy to read and fast to use. NotCopyable<Drinkable> is really clear but typing it over and over would get real old.
~ is not special syntax. My understand is “~Copyable” is the name of the type. You can’t just put ~ in front of anything, like ~Drinkable. But since that’s the syntax used for bitwise negation it’s pretty guessable.
& is existing syntax for multiple type assertions. You can see the evolution in this Stack Overflow answer:
https://stackoverflow.com/a/24089278 https://stackoverflow.com/a/24089278
Seems to read like C to me. It has to be Drinkable and not Copyable.
Like I said I haven’t gotten to use this yet, but it seems like a nice improvement. And I know it’s a step in the path towards making it easier to do safe asynchronous programming, object lifetimes, and other features.
- skrrtww 2y agoYeah after thinking about it a bit more it does make more sense to me. The primary gap I had was, as you allude here: > You can use a copyable anywhere you’d use a non-copyable since there is no restriction. Effectively copyable always conforms to non-copyable, just not the other way around. And the compiler effectively automatically notates literally everything with Copyable, so you need the explicit (& ~Copyable) in the function definition so you're still able to define functions within a ~Copyable protocol that have Copyable semantics. It's very in the weeds, and I still don't like it (I would have preferred NotCopyable since the ~, especially next to the &, directly implies something like bitwise operators), but I guess custom ownership is itself very in the weeds and you will have to think about it hard no matter what approach is taken. I would have expected custom ownership to be fundamentally incompatible with Swift, but clearly it's here; I should probably read about it more so I have a more clear understanding. (I also didn't realize & was extant syntax).
- MBCook 2y agoYeah, I’ll admit it’s hard to get your head around. I had to think about it a couple of times just writing that explanation. It took me a couple of minutes to figure out why it was in the function definition. I guess it had to be but that wasn’t obvious to me at all at first. > And the compiler effectively automatically notates literally everything Right. Just like how all classes in Java extend Object even though you don’t have to literally write it. I believe they’re still working on a more Rust-like borrowing system, but I could be wrong. I know this helped them implement parts of the standard library much better because they could make assumptions that you can’t make with copyable objects. I do get your point about just calling it NotCopyable. I don’t actually know why they settled on the name they did, I didn’t ever try to look that up. Maybe it’s because it’s a special thing that requires compiler machinery and there’s no way for you to make an equivalent?