Hacker News new | ask | show | jobs
by pdimitar 756 days ago
I've been doing programming for ~31 years in total and ~22 years professionally and at this point I have lost all hope that programmers at large will ever gain these mythic qualities called "self-reflection" and "introspection".

Truth is, these people are simply afraid for their cozy jobs, that's all there is to it. Derivative states of mind like Stockholm Syndrome and Sunk Cost Fallacy are quite normal to appear in these conditions.

On OP: I could not agree more. People always downplay their fuck-ups, that's sadly part of being a Homo Sapiens, but the lack of awareness is still both despairing and hilarious to watch.

And finally, C/C++'s niches have decreased but these people will not adapt, of course. Almost anything I've done with those languages 15-20 years can today be done with Rust. Or if you are on a tight time budget -- Golang, and you still won't lose too much speed.

But sure, "nothing can be done, these things sometimes happen". Sigh.

6 comments

I would love to be able to use Rust in my professional project. Unfortunately, I am doing high performance scientific computing. Rust doesn't even come close to offer any good alternative to cross-plateform, cross-device (CPU/GPU) libraries such as OpenMP Target, Kokkos, SYCL, ... I believe we need Nvidia/AMD to take Rust seriously (I'm not sure it is even possible without unsafe everywhere) to be able to offer good libraries.

In my world, using C++ is the modern language, because most project are stuck with Fortran.

That's completely valid and that's why I said "almost anything" -- other things include kernel development and embedded.

My broader point was that C/C++ are still kings in some areas but people insist on using them where a bunch of languages do better today.

Also cross-platform libraries, if you want to be everywhere, from computers and phones to set top boxes to weird Japanese rtoses you haven't even heard of, Rust just won't cut it.
Fortunately there are other languages that are more available cross-platform than Rust with its tiny Tier 1 list.

Unless ofc you're contractually obligated to use vendors half-arsed kludget together patchy version of GCC of unknown provenance that they compiled with barely half C support, let alone other GCC languages.

At least C++ provides the tools to avoid this kind of problems, if one choses to do so, instead of insisting into C idioms.
Yeah, part of the problem here is that the source code and the bug were in C, and people commenting here think C and C++ are the same thing.

There's a huge difference between C and C++. There's a big difference between 2001 version of C++ and 2021 version of C++.

The languages are so different that, in general, something that happens to one of them doesn't apply to the other.

I program MCUs as a hobby. I wish I could use something better than C. Even C++ with RAII would be better. But somehow, even C++ support is spotty, with unsupported features, broken debugging, etc. for seemingly no reason. And all device-specific libraries are written in C, so I'd have to write C++ wrappers for every little thing. Send help...
That's why I said "almost anything". I am aware that f.ex. kernel development and embedded work is still firmly in the C domain.

I am not evangelizing for Rust, Golang or anything in particular. I am evangelizing for periodically asking yourself "Am I still using the best tool for the job?" which most people never do.

Actually, maybe Rust would get more people interested if it didn't sound like a religion...
It’s a cult, but you don’t have to join the cult. I use Rust both privately and more and more frequently professionally and I don’t really notice the cult community outside of smiling at it once in a while when it blows up on HN.

We’re mostly adopting rust to replace our C, to protect us from ourselves. It’s just so much easier to hand off these sort of projects to developers who mainly work with things like Java or C#. Partly because of the memory “safety” but also because things like enums work the way they expect them to being sum types, and so on. It’s also very clear when something is intended not to be mutable. The borrow checker is probably the biggest struggle, where with C, everything is a struggle.

Rust still has a long way to come though, and maybe it’ll never get there. I do think we’ll see an uptake as performance increasingly matters due to cloud costs and ESG. Right now though, I’d argue that unless you know why you “want” to use Rust then maybe you shouldn’t.

I saw your comment on an older C# thread in which you said (paraphrased) that C# is not bad, has nothing really stellar, and is just kind of bland.

If you could theoretically swap out the entire back-end of a programming language, and hypothetically you did that to C# by allowing developers to write C# styling and syntax that could be compiled to Rust, it would probably not be a big loss. The type primitives would be an apples-apples comparison at best, or "Rust is just better" if you really scrutinized the types closely. Where does that leave the rest of the language? A better regex implementation? Rust would probably win. A better GUI experience? Rust is speedily approaching usable APIs there at the same time Microsoft is trying to sunset the best they had.

I wonder if F# could be rebased on top of Rust...

Mostly agreed with your comment though I still have to remark that every community has zealots and it's mystifying to me why are people so annoyed by Rust's. So it's hard to agree that "Rust is a cult".

As you said, it's a pragmatic but also kinda niche language. I don't reach for it unless I can't do the job with others, easier and quicker to work with languages.

> ... every community has zealots and it's mystifying to me why are people so annoyed by Rust's.

Because they're the ones that we keep hearing from right now. When it was the Haskell zealots showing up every few days, they were annoying. When it was the Lisp zealots, they were annoying.

The C sphere is actually refreshingly free of zealotry (mainly I guess because there isn't such a thing as a "C community" and even despite C being the main attack target of language zealots - funny enough nobody complains about those pesky assembly coders and their hippie attitude towards memory safety lol).

The "religious zeal" was also an important reason why I switched back to C from C++ and why I don't have much interest in Rust. I can't quite stand the "holier than thou" attitude in.parts of those communities.

Maybe it's you and some other curmudgeons projecting -- worth to consider if that's the case.

Maybe it's normal for people to praise something that legitimately solved their problems. I know that happened with me.

There is a difference between praising and preaching, the latter happens more often with rust
If you say so. ¯\_(ツ)_/¯

But even if it was true (I'd contest it's not) can't you ignore it and judge the language on its merits? We are not teenagers for a long, long time now, we should be making up our own mind about things.

Before the current "AI" hysteria, HN was full of "I've rewritten this thing that was working just fine in Rust". No mention of how it's better, has more features - or even has all the original's features - or anything about why you should use the rewrite instead of the original.

Am I supposed to use a tool just because of what it's made of, or because it solves a problem for me?

Mikroe is still in business selling Pascal and Basic compilers for all kinds of tiny CPU and MCUs since 1997, so some people do value their products.
Rust only works for a few popular targets, but if it is just a hobby then Zig might be an option. C interop is pretty seamless, so you don't face the problem of having to reinvent the universe.
In my experience interop is rarely a language problem, lion share of time is consumed by reading the docs, testing if you understood the docs correctly, testing what's implied but not written in the docs and figuring out how to cope with idiosyncratic interface.
No, more people should be using memory managed languages like Java and Golang. Then educate and expose people to sum types and pattern matching. It is actually insane how people is still unconvinced about sum types. Imagine how insane it is to program without product types? That's exactly what it felt like.
> It is actually insane how people is still unconvinced about sum types.

Oh don't even get me started on this but I agree sooooo much.

> No, more people should be using memory managed languages like Java and Golang.

Well, I use both Golang and Rust depending on the need. We can have both, it's not an either-or.

I'm feeling my lack of academic training here, but I needed to make sure. When you say sum types, are you referring to enums, or is it a broader concept than that? The Wikipedia article was quite archaic but seemed to support my initial understanding that you're talking about enums.

Are you talking about enums?

Rust's enum is a sum type. The enum in C is just integers (again) wearing a hat for some reason. This may not be obvious, but if my enum in C seemingly has three possible values it... doesn't, it actually has at least hundreds of possible values, but only three have names - it's just an integer in a hat.

A sum type is an idea from type arithmetic. Suppose we have two types A and B, and we want to produce a new type from those, the most common provision in languages is to let you make a product type, it has all the values of A multiplied by all the values of B, this may be available to you as a named tuple, perhaps named a "struct" or "class" in your preferred language.

But what if instead we added these types instead of multiplying them? The new type has the values of A plus the values of B ? That's a sum type.

Suppose I have three types which resemble booleans: mood (it's either happy or sad), size (huge or tiny) and activity (either sleeping or eating)

A sum type of these three would allow me to make a "brief" of a cat as one of the six values, either as its mood, its size or its activity. The cat brief can be sad, or sleeping, or tiny, but it cannot be sleeping and sad [in this model] any more than a cat's size could be both huge and tiny. There are 2 + 2 + 2 = six values of the brief type.

In contrast a product type, maybe lets call that "state" of the cat consists of separate values of each of the three constituents, so the state of a cat might be (sad, tiny, sleeping) or (happy, huge, eating) or any other combination. There are 2 * 2 * 2 = eight values of this state type.

Just as an arithmetic is kinda crap if it only has multiply but not add, a type system is kinda crap if it can't make sum types. Where complicated hard-to-get-right hacks are used (e.g. C++ std::variant) these are often unsatisfying both ergonomically and in terms of delivered functionality, so hence the desire to have actual sum types in the language.

In Rust they are called "enum", elsewhere "tagged union", "discriminated union" or "variant" (under the hood, all of those are just a C-style union bundled with a tag field which identifies the active content of the union). The rest is language specific syntax sugar which makes their usage more or less convenient and typesafe (and sometimes more memory efficient, for instance a pointer|null type doesn't need the tag since the set of valid pointers doesn't overlap with null)
> (under the hood, all of those are just a C-style union bundled with a tag field which identifies the active content of the union)

Crucially that's not necessarily what's going on in Rust and (assuming it lands) won't be the actual implementation of C++ std::optional<T&> specialisation.

Instead the language can decide from the value which type it has. This is where Rust's Guaranteed Niche Optimisation kicks in. If we've promised the compiler that type T's values don't occupy the space needed fully, the GNO promises that sum types consisting of T plus one other value are the same size as T was. There is no "tag field".

In practice, the compiler can provide optimisations beyond the Guarantee. For example the compiler can see that OwnedFd (a file descriptor) has a niche so Option<OwnedFd> is the same size as OwnedFd (ie the same size as a C integer, typically 4 bytes), but it can also see that char has a huge niche. Many of the 32 bits aren't needed to store a 21-bit Unicode scalar value, so (although the guarantee doesn't apply) a sum type of a char and six hundred other named possibilities is the same size as just the char was.

Ah, I see you mention this at the end, I think it's worth highlighting much earlier, that the "tag" isn't actually a mechanically necessary part of such a type.

Yes, I am talking Rust enums and OCaml's enumerated data types.
Or what F# calls a Discriminated Union.
Just call them "tagged union" or "variant" and suddenly "sum types" are not so rare anymore ;)

...same with "struct", "record" or "tuple" vs "product type". Nobody calls them that except functional programmers and mathematicians, both quite rare specimen in the wider programming world, but nevertheless they are ancient and widely known concepts even among us "peasant coders" ;)

> Just call them "tagged union" or "variant" and suddenly "sum types" are not so rare anymore ;)

Nah, this is a false dichotomy. If a language doesn't have product types but instead resort to declaring variables separately, you don't call that "structs". Similarly, calling tagged unions a sum type is kind of misleading. They are both programming languages, I am sure I can do whatever I can do in A using B.

Why is a "struct" such a powerful concept? Because it is correct by construction. When I declare struct A, I have everything that A should contain. It is impossible to say, oops, I forgot about A::b. Similarly, a sum type as a concept is only useful when the abstraction is very, very solid.

Tagged unions or variants (in C and C++ respectively) is nothing like that. I have a variant A, I checked that that it is B, but oops, I casted it as C. Its your typical TOCTOU (or LOCLOU for line of check, line of use, I guess). std::optional is also like, same with pointers. Proper sum types, like Rust, it is literally impossible for me to get C by mistake.

Obviously, all of this minus some underlying implementation details, unsafe code yadda yadda.

Sorry if I sound aggressive, but I am just tired of "we have A at home, A at home (the most cursed shit)".

Does go have enums? Yea... just declare some global constants like so bro.

SomeEnum_A = 0

SomeEnum_B = 1

SomeEnum_C = 2

Yea..."enums"..

Edit: Oh how can I forget, we had this kind of issue just TODAY in production. No wonder I am so pissed off.

It's possible to write systematically safe code in C, no need to change language. People really just don't want to do it.
It's possible to write systematically safe code in assembly, no need to use any language. People really just don't want to do it.
When the language has builtin safety, it has better ergonomics, so there's merit in switching language.
If that language you speak of is Rust or many GC more dynamic languages I'll agree. If you mean C/C++, frak no. They don't have "builtin safety" at all. Nothing that's opt-in is safe or secure.
You're entitled to your opinion, the universe has an opinion too.
In theory, in 50 years of practice, not really.
If you mean those two godlike C programmers, that's not what I mean.
Maybe it is but the last several years of periodic (and quite embarrassing) CVEs suggest otherwise.
What they suggest? What I and the discussed article claim is that safe code isn't written because programmers don't want it. CVEs aren't caused by desires, they are caused by unsafe code.
Many people suggest to start gradually migrating to either Rust or start investing much more seriously in formally proving C/C++ code (which is IMO a huge endeavor).

As I said in multiple other comments, I know there are valid cases for C/C++ where various factors prevent migration. I am not playing a little rebel revolutionary here, I am addressing the people who can migrate away but refuse to do so based on hand-wavy philosophy clashes (or my favorite petty rebellious take: "people praise Rust, I must resist using it!"). Petty stuff and I am pretty disappointed that people who bill themselves as "engineers" refuse to see objective evidence and hold on to only what they know.

Those are the people I address with my comment. Not the people who will be never allowed to migrate away a 2 million lines worth of C codebase. They have my deepest sympathies.

I didn't propose to migrate to rust.
You asked me a question, I replied.
> Petty stuff and I am pretty disappointed that people who bill themselves as "engineers" refuse to see objective evidence and hold on to only what they know.

I think it is widely accepted that Rust is more safe. (There comes the NPM factor too so it's not entirely clear). The thing is just, you are excited about this technology, and you are equating "engineering" with "security". You are willing to pretend that other merits and factors don't exist, including ergonomics of iteration, or inertia. I tried writing my usual explorative Win32 code in Rust for an evening. Well, it was painful and I went back to do it the way that works for me, that is supported by all the official tooling, and that the official documentation is written in. I also can't see myself reading reasonable Rust code quicker than I can read and write reasonable C code in a year down the line. It's just too intricate, too clever, too condensed / abstracted and at the same time too verbose. Another time I went to download a couple simple projects (e.g. text editor) to dabble a bit with. But the stuff was too opaque and had _hundreds_ of third-party dependencies, and I couldn't understand it well. So I lost interest.

Choice of language and ecosystem is an economic matter. They get chosen based on what one knows and what one wants and how one evaluates the possibilities. "Security" quite frankly is not the most important of concerns in most situations, and for a good reason. I frankly am not getting paid in finding the nicest or "most secure" way to write a piece of code, but to get it done. I am not interested in following the development of the hundreds of dependencies of my Rust project, and to change my data structures when they learned a better way to design the API to those "safe" data structures.

But you are seeing only "security". Well, it's most secure to just shut your computer off. So much for "objectivity". Maybe you _are_ the zealot!

> The thing is just, you are excited about this technology, and you are equating "engineering" with "security"

I do no such thing. I am not at all excited about Rust in fact anymore, I just learned where it excels at and I know when to reach for it.

> You are willing to pretend that other merits and factors don't exist, including ergonomics of iteration, or inertia

I have literally just responded to you before this comment where I made it clear that I stopped actively using Rust due to slower speed of iteration -- and that is said in another comment as well (including the inertia or lack-of-choice factor).

Can you please not misrepresent what I said? It's clearly written in at least two places.

> Choice of language and ecosystem is an economic matter. They get chosen based on what one knows and what one wants and how one evaluates the possibilities.

Which agrees with my "right tool for the job" take elsewhere in the thread. We're aligned.

> I frankly am not getting paid in finding the nicest or "most secure" way to write a piece of code, but to get it done.

Yes, and that explains why the programming at large is always teetering on the verge of ruin and stuff is barely working and is kept together by goodwill and spit. Though obviously worker bees like you and me can't change that reality for now. I have partially made my peace with that fact but not entirely; hence I reach for Rust every now and then.

> But you are seeing only "security". Well, it's most secure to just shut your computer off. Maybe you _are_ the zealot!

You seem to have gotten quite worked up and I'll ask you to stop. When I told you that I am open to discussion in a previous comment I was genuine.

Both Microsoft and Google said that from 60% to 75% of all C bugs are memory safety problems -- not my words, not my research, but that of two of the largest IT corporations out there.

That is proof. That is objective info. We can bikeshed and throw feces at each other until the end of time but there are people who got out there and gathered the info.

I refuse to be viewed as a zealot simply because I want to attack the lowest hanging fruit in terms of bugs and security vulnerabilities. No, that makes me both a pragmatic and a guy who is no longer willing to live with the broken status quo.

And I'll not agree with your polarizing take that "the only security is shutting your computer down". That's nonsense. You are simply not motivated to advance anything but your career. That's your right, surely, but at the same time it makes you dismiss any well-intended discussion about the current state of our profession and how can it be advanced further. You dismiss stuff off-hand and then you blame me for being a zealot. Not acceptable to me and I'll not take it.

So try and calm down and read better. We in fact agree on much more than you think but you are not seeing it because you seem to have formed an opinion of me before you even started writing.

THIS, sadly. Though it'd be more accurate to re-phrase: 's/just don't want to do it/have other priorities, or are stuck in organizations with other priorities/'
I get that we can't always do what we want in our jobs (and in some places quite rarely even). I get it fully and I sympathize.

But that still doesn't do C/C++ any favors. None of my Rust contracting work ever resulted in a buffer overflow.

And it doesn't need to be Rust, as the anti-seat belt folks always are quick to complain about, plenty of systems languages since PL/I and NEWP days have bounds checks by default.

Back in the days we were arguing for Ada, Modula-2, Object Pascal on Usenet, we were straitjacket programming advocates apparently.

Haha, nice analogy, thank you. :)

And yeah I am gradually giving up on arguing with people who are extremely biased but point at me and blame me for being biased. Seems there's no win.

I actually regret engaging so thoroughly in this thread but once started I figured I'll not budge and will hold my ground. I am anti-group-think that way.

I haven't engaged in such threads in a while and I think the next time around is going to be months in the future. We'll see.

Eh, Rust would be fine if not for the fact that it's too opinionated.

Unfortunately you can't just have Rust's safety checks, without opting into restrictions that Rust designers force onto You that aren't inherent to safety checks, but more because 'that's a better practice (according to us)'.

And also, easy and fast iteration just isn't there, both because of borrow checker restrictions and compile times

C/C++ being non-opinionated is the main source of the security vulnerabilities.

Let's face it, it felt good to be a lone cowboy carrying a lot of responsibility and knowing what you are doing. I was there myself and I'll admit the ego trip was awesome.

These times are long past and naturally, people refuse to adapt.

> Unfortunately you can't just have Rust's safety checks, without opting into restrictions that Rust designers force onto You that aren't inherent to safety checks, but more because 'that's a better practice (according to us)'.

Show me something that does better and I'll switch tomorrow. But don't tell me C/C++ are better -- they are not. Too much freedom leads to CVEs literally every month somewhere and that's only because we don't have better vetting and checking tools, otherwise I'm sure we'd be getting one every day for a while.

> And also, easy and fast iteration just isn't there, both because of borrow checker restrictions and compile times

I agree on that, that's why I mentioned Golang. Most of the C/C++ systems I worked on around 15-20 years ago didn't need the close-to-the-metal speed because at least 90% of their time was spent on I/O... frak, even Python would have done well there. And Golang is times faster. It's a very nice compromise if you want to be productive and don't care super much about CPU speed efficiency.

> C/C++ being non-opinionated is the main source of the security vulnerabilities

This. "Undefined behavior" is such a terrible way of thinking. As is the "we can assume in the optimizer that UB does not happen and then eliminate code on that basis", which allows the compiler to introduce bugs that only appear at certain -O levels.

It took decades to get them to define arithmetic as twos-complement.

> It took decades to get them to define arithmetic as twos-complement.

I'm not sure this is right? IIRC C++20/C23 require two's complement representation for signed integers but generally leave other behaviors (including signed overflow) the same.

[0]: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p09...

I’d say the biggest problem of interpreted, JIT compiled, and GCed languages is not the speed; it’s the RAM use. I agree that quite often we don’t need the speed of close-to-the-metal. But there is something wrong with most programs eating tens or hundreds of megabytes, without doing much.
And I agree on that. My favorite Elixir's runtime (Erlang's BEAM VM) still has some subtle problems with holding on to big(ger) binaries (strings) that requires very specific code be written at the green thread boundaries and it can get pretty maddening if you don't get it right -- which is not easy.

Golang I hear is doing much better btw. But you still have to be wary of its footguns i.e. leaking goroutines.

Go is doing much better on memory use because 1) it is AOT compiled, 2) it tries to allocate as much as possible on the stack (escape analysis), 3) it supports value types (the items of an array and the fields of a struct are contiguous in memory). But it's still a GCed language, which generally means a slightly higher memory use, controlled by $GOGC, to not spend too much time CPU time on garbage collection. Overall, Go is an excellent tradeoff for most applications.
There are restrictions out on You by the borrow checker to ensure safety, and then there are restrictions put on You by rust design team 'just because'.

Again, the former are fine, it's the latter I have a problem with.

In order for me to agree on the "just because" part you'll have to give some examples. What made you think they are arbitrary? And how did they prevent you from doing your job?
Comment above, mentioned borrowing while structs instead of borrowing memory. I believe this was once discussed under term 'partial borrows', but the "idiomatic" aproach is to 'just split your structs'.

Which isn't really a good aproach to structuring codebase, it's just to appeal to borrow checker inflexibility.

Lack of global scope. Lack of function overloading.

> Comment above, mentioned borrowing while structs instead of borrowing memory. I believe this was once discussed under term 'partial borrows', but the "idiomatic" aproach is to 'just split your structs'.

You're mistaking "idomatic because it's the only way" with "idomatic because we say say so". There is currently no way in Rust to specify the granularity of a borrow, so we're stuck with splitting your structs to get around it.

Part of the problem is that it's a hard problem to design around. It can not be done automatically by the compiler, because it would result in changes in the implementation being changes in the type signature. For example, say we have this function:

    pub fn foo(&self) -> i32 {
        self.a + 5
    }
The granularity is borrowing `a`. If we then change it to this:

    pub fn foo(&self) -> i32 {
        self.a + self.b
    }
The granularity of the borrow has changed in a backwards incompatible way (it now includes `b`), but that change is not reflected in the signature. It's the same reason why the compiler refuses to infer signature lifetimes from function bodies now.

You could, of course, say that we can allow the programmer to specify it manually:

    pub fn foo<'borrow>(&'borrow self) -> i32
        where 'borrow: 'self.a + 'self.b
    {
        self.a + self.b
    }
But this is now leaking implementation details if `a` or `b` are private fields.
> Lack of function overloading.

Isn't there at least some technical basis for this (less-than-ideal interactions with type inference IIRC)?

I would say until C++98, C++ used to be more opinated, one of the reasons many of us went with C++ when given the choice, wasn't OOP features, rather the security improvements over bare bones C, with compiler provider frameworks.

Then eventually C++ got invaded by C expatriates, and writing C with C++ compiler idioms increased instead of going away.

It is like giving Typescript to groups of folks that insist on using any all over the place.

Actually I have good-ish memories of the early `boost` (we're talking 2003 - 2006) and some of the `std::` libraries in C++. They got the job done fine and were not in the way. So yeah, agreed.
>Show me something that does better and I'll switch tomorrow.

There's no limit to perfection, but if you merely don't write C of opportunistic kind, logical errors quickly start to outweigh other types of errors.

Are you willing to die on this hill? I remember an HN post a while ago where both Microsoft and Google said something like 65% of the bugs in C code were related to memory (un)safety.
I don't deny that.
> Show me something that does better and I'll switch tomorrow

Frankly this is a very bad decision. Because now you have C code, Rust code, and yet another language's code, and you're left with a mess that you have to integrate too.

Obviously I was demonstrating that I don't shill for Rust in particular -- I simply believe C/C++ are not cutting it anymore. Rust is not perfect but it solves a sizeable chunk of their problems, that's all.
Most programmers don't have any opinions, so if they use an unopinionated language, they end up using patterns that opinionated people use. So it's better to have one source of truth for opinions, so that we don't end up using the "wrong" opinions of people who talk more than they think.
Compiler/language people are also just "opinionated people" though. Some have good opinions, some have bad opinions. In the worst case you have opinions which are the result of a 'design by committee/community' process.
Single source of truth of opinions can be challenged and changed if one's arguments are good enough. The benefit is that it's easier to see the advantages and disadvantages for those opinions, because they're all in the same place.

This is in contrast to C++, where one organization creates a set of guidelines, another organization creates another set of guidelines. Valid arguments of critique in one organization are not seen in the other.

Single source of truth is also beneficial to compiler authors as well, because they get more feedback how the language is used and why.

Unfortunately you have to pick 2 out of:

- Lack of restrictions

- Safety

- Performance

If you choose safety and no restriction, you pay the price in performance (for GC etc.)

There's a massive Terra Incognita to explore between Rust on one side and Python on the other side (just to pick two extremes).

It's not "2 out of 3", it's a triangle where a language can pick a sweet spot anywhere within the triangle (and ideally, it's not a "sweet spot" either, but more like a "sweet area" where the programmer can pick an actual spot within that area defined by the language).

That sort of extreme flexibility simply does not exist. I mean it does but then you are firmly in the dynamic languages territory and you are forgoing any hope for close-to-the-metal performance.
IMHO it does and its not restricted to dynamic languages (like JS or Python), look at this Zig function signature for instance (just an example from my current dabbling):

   fn setData(comptime pins: anytype, bus: anytype, data: u8) @TypeOf(bus)
In practice this looks and feels like dynamic typing, yet when looking at the compiler output it still resolves to optimal code (since it's "compile-time dynamic typing" not "run-time dynamic typing", but the difference in practice is surprisingly small).
Well you can make OCaml and Rust look like dynamic typing as well by omitting type signatures and squeezing the type inference engine as much as you can but I was under the impression that you have more asked about something that is very relaxed in terms of upfront requirements and be able to tighten it up later?

That's why I claimed that no such language exists.

I'm not super familiar with Zig, but that appears to be the same as the rust function signature fn setData<P, B>(pins: P, bus: B, data: u8) -> B;

in rust, the P and B are resolved at compile time, not at runtime. If you wanted dynamic dispatch the types would be Box<dyn B>

Again, restrictions that are forced you for a price of safety are one thing. But what I'm complaining about are restrictions that don't have to be there to get borrowchecker working, but rather are there because designers arbitrary decided "it's better this way".
As someone just starting to finally learn Rust, I'm curious what some examples of this might be.
All AFAIK, since I only dabble occasionally in Rust:

The borrow checker works on "struct granularity", but it would be much more flexible and convenient if borrowing would work on memory location granularity (for instance passing a struct reference into a function "taints" the entire struct as borrowed, even if that function only accesses a single item in the borrowed struct - this 'coarse borrowing' restriction then may lead to all sorts of workarounds to appease the compiler, from 'restructuring' your structs into smaller pieces (which then however may fit one borrowing situation, but not another), or using 'semantic crutches' like Rc, Cell or Box.

There are also related restrictions about function call barriers. AFAIK the Rust compiler cannot "peek into" called function bodies to figure out what's actually going on inside those functions (and that information would be very valuable for fine-grained borrow checking), it can only work with the information in the function signature.

Again, disclaimer: take this with a grain of salt since I'm not a daily Rust user, but this is how I understood why Rust feels so restrictive.

> The borrow checker works on "struct granularity", but it would be much more flexible and convenient if borrowing would work on memory location granularity (for instance passing a struct reference into a function "taints" the entire struct as borrowed, even if that function only accesses a single item in the borrowed struct - this 'coarse borrowing' restriction then may lead to all sorts of workarounds to appease the compiler, from 'restructuring' your structs into smaller pieces (which then however may fit one borrowing situation, but not another), or using 'semantic crutches' like Rc, Cell or Box.

That's valid, thanks for pointing it out. I seem to recall the team lately mentioning they are starting to consider fixing that. And yes that's a real productivity killer, happened to me as well in the past.

They made a lot of progress with borrow checker granularity between 1.0 and now. It's much more granular now than before.
> There are also related restrictions about function call barriers. AFAIK the Rust compiler cannot "peek into" called function bodies to figure out what's actually going on inside those functions (and that information would be very valuable for fine-grained borrow checking), it can only work with the information in the function signature.

I don't think it's so much "can not" as it is "will not". Allowing the function signature to be determined by the body can lead to accidentally breaking callers by changing the body.

That, at least, is consistent with other parts of the signature: the input/output types and how the lifetimes of input/output references are related.

So a few things .. Rust is a very good safe language. It also has an unsafe keyword to make the compiler ignore borrows etc.

If you want fast iteration, use python and then hand transpile your code into rust.

Not every tool has to be used at once ... but Python for the idea and rust for the implementation can be the best of both worlds ... :)

Except Rust's unsafe is even worse then any other 'unsafe' languages.

And while you can technically prototype in a other language, speed of iteration is always a bottleneck.

The only way to escape it is if You are an about master of language, the project you are working on and even the feature you are adding.

But that's a verry rare case scenario

I don't disagree btw. As a contractor I have found myself very often in a situation where Rust's slower iteration simply didn't work for me so I got back to Elixir and also relearned and started getting proficient in Golang.

Rust's slower iteration only disappears when you become a pro as you said and that's my main problem with it. I simply can't invest as much time and effort for free.

Rust is just a different language. It's not C-like or Java-like plus checks or anything like that.

It's a value oriented language. Variables mean something completely different than in any other common language. Everything is about the values and where they are kept at the moment.

This is one possibility. Have you considered the other, that you're the old-man-yells-at-cloud variety of narcissist?

Hence why you choose to interpret things as everyone (except you) is defective. Everyone (except you) is laughable, completely lacking in self-awareness, refusing to adapt and be and do as they should (according to you of course).

Because they're all lesser than you! That's why. You write Rust. So obviously, you're so far above them. Like a God looking down at monkeys.

Couldn't be reasons like inertia, or lacking the time, or not having the budget to change, or being too tired to learn, or any other such thing that'd let them be equal to you but just with differing priorities.

No, because then you wouldn't get your narcissistic supply, allowing your delusion you're better than others, rather than a man distracting himself from his own failings?

Just an alternative theory. What do you think?

Don't worry, HN went through this many times before. It was Go a few years ago, Node.JS before that. Rust too shall pass.
> Couldn't be reasons like inertia, or lacking the time, or not having the budget to change, or being too tired to learn, or any other such thing that'd let them be equal to you but just with differing priorities.

This is already included in the "almost anything" expression and you are the 4th person deliberately (or accidentally?) not noticing it.

There are valid cases for C/C++ both on technical merits and business specifics. I have not denied that.

---

The rest of your comment is just projection borne out of your faulty assumptions about my comment and it's thus not interesting at all.

> This is already included in the "almost anything" expression and you are the 4th person deliberately (or accidentally?) not noticing it.

I genuinely think that :

1/ this field is dominated by a disproportionate amount of people with autistic traits

2/ their ability to reason only functions in the narrowest sense and their grasp of language (takes everything in the most literal sense, thinks in extremes, prone to putting things in boxes, have a very, very strong attachment to their routine and are unable to ever leave the comfort zone they constructed) makes any attempt at communication beyond painful.

I have come to not even bother replying to people who are unable to understand human words such as when they interpret "most" as meaning "all" or "rarely" as "never" as it's one of the telltale signs that it is going to be extremely unproductive.

This phenomenon is the cause of most pains and drama. Once you start to see how this pattern develops you understand the true cause of the endless bikeshedding, of why even the idea of having a code of conduct can raise endless anger and storms and so on. You're touching a comfort zone so the temper tantrums are thrown. The routine has been built and it must continue until the end of times.

If there's any field in this world that is in need of more neurotypical, emotionally stable adults, this is it.

Or maybe, just maybe they correctly interpreted "most" as "more than half" and "rarely" as "decidedly less than half", and actually disagree with the statement as is. And what can I say, "reasons like inertia, or lacking the time, or not having the budget to change, or being too tired to learn, or any other such thing" sounds exactly what almost anybody is confronted with -- so it doesn't exactly seem like just an _exception_ to the set of "almost anything".

But it's nice to add words like "autistic", "thinking in extremes", "painful", etc. to terminally bash on those people who are wrong and just can't learn...

Or maybe, just maybe, I explicitly agreed with the real-world limitations up-thread but now you are just looking to pick a fight because me agreeing with stuff does not fit your preconceived notion. :)

But, by all means, go on, I can only presume you are bored.