I've been using higher RAII with Vale for quite a while, and it doesn't have the problems Rust seems to have.
It's actually not difficult to design APIs to properly use handles and other RAII'd objects. Either don't drop generic types (for example, the HashMap doesn't drop any user types), or require a drop generic bound or concept function [0].
If one wants to make it even easier, just take in a "consume" lambda which will take arguments. Then, the caller can specify what to do with these objects. That's how Vale's drop_into function for arrays work, for example.
In my opinion, Rust made the same mistake with `drop` that Java made with `toString` and `hashCode`. We shouldn't needlessly couple functionality with objects, it just causes problems, as is seen with Rust's lack of linear typing. But that's just my opinion ;)
The trouble with Vale's "concept function" and the C++ Concepts it is mimicking is that they're duck typed. We know syntactically that we can do this, but there's no reason to believe it's semantically justified.
This is why you'll notice Rust's traits don't have names like "Iterable" or "MaybeComparable" but "Iterator" and "PartialOrd". They have semantics. Rust's Iterator is not merely any thing which happens to have a next() method but specifically a iterator in which that next() method gets to the next item.
Over in Concepts land they have two "fixes" for this, but they're both pretty unsatisfactory. One fix is, you document what the concept means, and then you just tell the programmer it's their fault when the syntax matches (so it compiles) but the semantics don't (so it's broken). The other is, just tell people not to use Concepts for simple things, if it's complicated enough then likely the syntax will only match when semantically aligned. Unfortunately of course lots of powerful er, concepts, have exactly one match point.
This is funniest when in juxtaposition e.g. Stroustrup first showing off concepts with a simple example like your Fireable concept back in 2018 or so, mixed with Stroustrup in 2020 explaining that it's crucial never to do anything like that because it's too fragile...
> If it helps, think of it this way: a concept function is a 1-method trait on an implicit parameter.
No, that just underscores the problem, it's just duck typing. This "1-method trait on an implicit parameter" doesn't deliver semantics.
Let's look at an actual Rust trait, Eq. https://doc.rust-lang.org/std/cmp/trait.Eq.html and notice that the implementation of this trait is empty. For a duck typing system there is nothing to check, syntactically Eq doesn't do anything.
But of course semantically Eq is rich with meaning. You can't go around using a HashMap with keys that don't exhibit Equivalence, what's that going to do? Nothing good.
I see now what you mean, youre talking about structural interfaces, like Go and Typescript have. Yes, concept functions are those applied to generics.
You may not like structural interfaces, but they're much better at decoupling data from how it's used. People who have used both Typescript and Rust often wish more languages worked with structural interfaces like Typescript does.
It's easy to see why, looking at the examples in the article.
I believe in decoupling, and think a good language will have as little coupling as possible. To each their own though!
It's actually not difficult to design APIs to properly use handles and other RAII'd objects. Either don't drop generic types (for example, the HashMap doesn't drop any user types), or require a drop generic bound or concept function [0].
If one wants to make it even easier, just take in a "consume" lambda which will take arguments. Then, the caller can specify what to do with these objects. That's how Vale's drop_into function for arrays work, for example.
In my opinion, Rust made the same mistake with `drop` that Java made with `toString` and `hashCode`. We shouldn't needlessly couple functionality with objects, it just causes problems, as is seen with Rust's lack of linear typing. But that's just my opinion ;)
[0] https://verdagon.dev/blog/concept-functions