<i>"Of course you can argue that Rust recently adopted language specification, but if you take a second to learn more about it you’ll find out that it comes essentially from outside."</i><p>It is worth noting that the Ferrocene specification is made for the certification of the Ferrocene compiler as its sole purpose. It is neither intended nor suitable to implement a compiler based on it.
> My criteria were subjective but simple to understand: the language should introduce new concepts (as Principia Discordia puts it, ’tis an ill wind that blows no minds) [...]<p>I wonder how many people share this opinion. I derive as much if not more value from the refinement of existing concepts than the introduction of new ones.<p>Wanting new concepts just for it's own sake is wild to me.
For me lack of language specification is not a problem and it is good that Rust only have one implementation so I don't have a headache to support multiple compilers like C++. The only problems I have with trait is lack of const function and trait upcasting, which just solved by 1.86 that released yesterday. For iterator type mismatched it does not cause much problem since I can create a dedicated generic function to handle that.<p>The major problem for me with Rust is deadlock. In Rust it is very easy to cause a deadlock compared to other languages. In other languages you need to think a lot before locking a mutex but in Rust you just `foo.lock().unwrap()`, which can easily cause a deadlock if you have multiple mutexes and someone in your team does not aware the lock order.
Ah, this is a codec guy. That yields an unusual list of desired features. Bit-pushing predominates. Inline assembler and access to SIMD instructions is important. Speed in tight loops is essential.
<p><pre><code> > Even more annoying is that I have to duplicate the iterator code: as I often work with frames that may be flipped bottom-up I want to write code like
>
> let mut iterator = if !flipped {
> data.chunks_mut(stride)
> } else {
> data.chunks_mut(stride).rev()
> };
> for line in iterator { ... }
>
> but I can’t since objects have different type (and probably size) and there’s no realistic way to coerce them to the same interface.
</code></pre>
For this specific case there is a relatively ergonomic solution using dynamic trait objects + temporary lifetime extensions, available since Rust 1.79:<p><pre><code> let iterator: &mut dyn Iterator<Item = _> = if !flipped {
&mut data.into_iter()
} else {
&mut data.into_iter().rev()
};
for line in iterator { ... }
</code></pre>
Alternatively, if this is not a feasible solution (e.g. we want to return the new iterator to an outer scope, or the overhead of dyn indirection is unacceptable in this context), one can consider using itertools::Either instead:<p><pre><code> use itertools::Either;
fn conditionally_flip_iter<I: DoubleEndedIterator>(
data: I,
flipped: bool,
) -> impl Iterator<Item = I::Item> {
if !flipped {
Either::Left(data.into_iter())
} else {
Either::Right(data.into_iter().rev())
}
}
// ...
let mut iterator = conditionally_flip_iter(data, flipped);
for line in iterator { ... }</code></pre>
> no dick (or walrus) operator (for me it’s been a good sign that I’m not going to like the language, so far there were no false positives). This means that Go and Nim are out<p>Not sure where they got that Nim has a walrus operator. Maybe because the syntax resembles Python? That'd make sense.
Author and lots of commenters specifying their biggest complaint about rust and nobody has mentioned lack of async drop? That's the top of my list by far, everything else is just nits in comparison.