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.
The FLS was written with that specific intend in mind, but that mostly limits the scope of the spec that Ferrous Systems is/was interested in maintaining. We were also not interested in adopting large scale contributions on parts that Ferrous Systems doesn't need - we're a small outfit after all, 20ish people, and we don't have the capacity to maintain a full specification.
However, that's no fundamental barrier that limits the specification per se - now that the Rust project is adopting it, others can contribute and pick up maintenance slack. We'll certainly continue to contribute to the things that we are interested in seeing, but if someone wants to build a compiler based on the spec, they can contribute the parts needed.
On the upside: The spec in its current shape is good enough to certify the compiler and I know people have started building other things on the FLS. Structurally, the tooling and the content is fine - so I believe it can serve as a good nucleus for the Rust languages spec.
As for the "strange" aftertaste in the process of adopting the FLS that's mentioned in the article:
I don't believe that the Foundation/Project adopting the Ferrocene Language Specification is bad. While Ferrous Systems as a company holds no official position in the project, we consider ourselves very much part of the project. We have people that head working groups, one of our employees was in the governing council, my brother and co-founder is founding member of the Foundation. Rust-Analyzer is maintained by my esteemed colleague Lukas. We draw on the project - after all we certified the projects rustc as we found it. We contribute to the project as part of the work we do. We started writing a spec because no one had written one, and specifically *we* had a need. And that's essentially how things work in open source: We scratch our itch - and in the process lift the tide for everyone. The project taking some time to figure out what the project wants is not surprising: They have their needs, we have ours, and they often overlap but they're not identical. We're not the rust project. The project is not Ferrous Systems.
Say, what about something like a formal machine-parsable spec and/or a testsuite that describes the way the language should behave, rather than a prose description that then each compiler writer interprets to the best of their ability?
I guess you could make the same argument for C++...
(In case you're wondering, just as an example, you might start implementing garbage collection).
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.
Wanting new concepts just for it's own sake is wild to me.
I suppose there's a difference between wanting to encounter new concepts, and wanting to find them as a part of a programming language you've decided to learn and use, though.
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.
C++ is from an era open source was not yet well established.
I'd argue that's not just a fairly common list of desired features but that if there's more than 1 of those desires not in your own list then there's probably better languages than Rust to consider.
> 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.
For this specific case there is a relatively ergonomic solution using dynamic trait objects + temporary lifetime extensions, available since Rust 1.79: let iterator: &mut dyn Iterator<Item = _> = if !flipped {
&mut data.into_iter()
} else {
&mut data.into_iter().rev()
};
for line in iterator { ... }
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: 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 { ... } let mut iterator = data.chunks_mut(stride);
while let Some(line) = if !flipped { iterator.next() } else { iterator.next_back() } {
…
}
I sometimes wonder idly if the language would have been better off without a `for` loop (if `while let` had happened much earlier). `while let` is more verbose, mainly because iterator construction has to be an explicit separate line, but it’s also more amenable to alteration to make it more fit for purpose. (You can go down to `loop` and `break`, but I think this sacrifices too much in ergonomics and comprehensibility in the usual case. As `while let` also compromises, but I wonder if it’s closer to the sweet spot than commonly imagined, and `for` doesn’t actually get you so much.)Not sure where they got that Nim has a walrus operator. Maybe because the syntax resembles Python? That'd make sense.
a := b
the `:=` looks vaguely like a walrus. The most common reference language seems to be Python [1]. The usage is for making assignment remain an expression, so you can do stuff like area = (width := get_width()) * (height := get_height())
or something, and have the top-level expression remain valid since the sub-expressions are assignments that remain expressions, i.e. the assigned value is also the result of the expression.Since it was introduced, I have been looking but there has been only a handful of times where I could use it to write clearer code.
I'm curious if anyone actually likes it.
edit: A quick search shows that I do use it regularly in while loops, e.g.:
while result := my_fun():
...https://en.wikipedia.org/wiki/Assignment_(computer_science)#...
That always made more sense to me than = for assignment and more =s for different kinds of equality, but in the end this syntax discussions are always just bike-shedding.