26 or so data points, but still interesting. I myself have become enamored with Zig's relative simplcity and straightforwardness, although some of my friends keep telling me to do Rust instead.
Yeah, not a lot of data points, and a niche subject, game dev, but I am playing with the Mach game and graphics engine, and so far so good. I started programming in 1978 in CPM Basic, C, 6502 assembler, etc. I play with Rust, but if I am really looking for high-integrity software, I am currently using SPARK2014 (the subset of Ada), that has some legs beneath it. Rust and AdaCore are starting to work together to bring some of this into Rust, but it's not there yet. So for me, Zig is my C replacement, and SPARK2014 is my C++/Rust replacement. You can go low-level with SPARK2014 too, and IMHO, it is far easier to understand than Rust, yet it already has all the high concepts of software integrity, safety, and verifiability. Excited about cross-platform graphics and performance with Zig and Mach.
I usually put "SPARK2014 programming" or "SPARK2014 Ada" in my searches. I used to get annoyed by all of the Apache Spark stuff that came up, but that seems to have waned a bit this past year or two.
Vermont Technical College (VTC) used SPARK2014 to program their CubeSat and the book, "Building High Integrity Applications with SPARK"[1] is a great intro to it in a nice context of practical use.
There was also an article on the AdaCore site about someone who rewrote some drone firmware in SPARK2014, which is another nice real-world application. [2]
I didn't say it was strange. I found it amusing that this is what came up during the other person's search for SPARK2014, and yes, thinking it sounded like a suitable electric vehicle name. Chevy called their electric offering Volt, and Volts are in the battery in a gas car too, but I think you get the picture.
Perhaps "understand" was the wrong word given I meant for me to understand. I have a C background and Pascal as well as assembler back in the day (late 70s/early 80s). I dove into Ada/SPARK2014 and picked it up much quicker than Rust. Ada has been around a lot longer than Rust, so I think it's syntax allows for a clearer readability even if they have similar borrowing rules. If I had my druthers I'd be programming in APL or J all the time, so take what I find clearer with a grain of salt. There wasn't as much tribalism around PLs as there is nowadays. I guess people stake a lot of emotion on what they have chosen as their main language or programming paradigm they may have committed so much of their time learning. I still recommend Ada/SPARK2014 to anyone who asks me about verifiable or high-inegrity software with a follow on comment to keep an eye on Rust especially with Adacore and Ferrous Systems teaming up to help Rust get there. Zig does not have a major sponsor like Rust, but it appeals to the low-level hacker, former C programmer. I love playing with Hexops' Mach game engine and graphics toolkit in Zig! I tried Bevy and Rust, but it just doesn't flow as quickly for me. Maybe it does for others.
For me Rust is a language that I would absolutely love to work with in a professional context. The type system and borrow checker have your back and help you make changes to the code without fear of accidentally introducing any regressions.
For private lone-hacking projects though it feels way too complex and opinionated. Here Zig definitely gets closer to what I need, though sadly it made unused variables an compiler error (curse you golang for making that popular) which is super annoying for prototyping.
>it's not like commenting out variables is difficult.
But if you comment var A that uses var B now B is unused and you need to commnet B, but now B was using a function parameter C and this param is unused now so you need to update the function signature (I do not use Go,Zig so maybe they did not forced you to also use all the function params my experience is with linters where ehwn you comment something then more unused warnings appear)
What are you talking about? I don't understand how you've never encountered variables depending on each other.
In any moderately complex function you'll have more than one expression, and those can depend on each other. And you want them to be named and assigned; it makes it easier to read and decode intent and debug things (unless you're one of those wizards who get it right on the first try every time, kudos to you then). I'd not approve a PR that inlines/embeds complex concepts within larger expressions just to avoid creating variables...
Of course I have encountered dependent variables, but if I have a long chain of unused variables that means that either that code is ready to go, or the code organization needs refactoring.
Ah yes, prototyping. The stage of coding where one has lots of snippets of code meant for trying things out quickly. Definitely a context full of long chains of dependent variables.
Dude, it is about debugging, or work in progress...
Did you ever tried to debug some issue and start commenting stuff to try and find the problematic area? Hell when I comment stuff soemtimes private function will get unused , so with a shit compiler you would need to also comment the private functions, remove unused classes etc.
In my code I assure the linter will say 0 warnings.
As other said, it is not a good practice so inline all the code, I prefer well named variables, and I assume you can find examples in your code where you have a local variable that depends of a function parameter.
Funny enough I was correcting my son c++ homework yesterday, he had a complex if statement like
if (somefunction(m,n, y[j]) == m[j])
and I made him make a local variable to make it clear what is happening. then the code was easier to understand and debug because we culd print that local variable and see if is fine.
Btw, try not too respond that smug, you proved that you are an inexperienced coder and a shit person.
I'm not so sure about that one, despite clearly being in the company of people who feel attacked, I'm not the one attacking people here. I'm commenting on code practices, and baffled at other people's rage about the compiler demanding that you don't have unused variables, but I haven't attacked anyone.
You commented about my code quality, but I will assume you were in a rush and missunderstood that I was talking about work in progress stuff and debugging, so if that was teh case I apologize (if is not the case then you might understand in a few years)
I am seriously mind-blown that you've never encountered this problem in Go. You're trying something, and you see an error, you comment out a function and replace it with a print statement. And now suddenly you have to comment out a bunch of things up to the import statement just to fucking test out a simple hypothesis.
Possibly because the IDE helps with that. Including adding and removing import statements. I feel like this complaint is more theoretical than something felt by people using Go day to day.
People on the internet contradicts you, You remind me of the Apple fanboys and the keyboard issue , people complain that they keyboard has problems and the fanboys respond with "is working with me, you are using it wrong, you are stupid and probably eat at your keyboard, you broke it yourself"
All those people reporting the issue are not Go developers? Or maybe are not true Go developers, just the other kind, the ones that want generic and nice things.
But yeah, I am not a Go dev, I used linters and I would hate having to be forced to clear all the unused warnings before I can test the code.
Yes. If Zig takes 100ms to compile, and Rust takes 2s, but you just spent 20 seconds commenting unused vars in your Zig code, then the slow compiler comes out ahead. It's a great example of how good UX can be more important than raw performance numbers.
Yes, but you comment out unused variable once per variable (you can leave those underscores in and clear them out before release). The 2s happens every time you compile. The badness of slow compiles is non-linear, too. As you start to get to 30s, the likelihood that you check Facebook, Twitter, or hn goes up. At least when you're underscoring unused vars you're doing something active.
If it gets to 2-5 minutes the likelihood that you stop writing tests and rely on the compiler for bugfreeness goes up - or the likelihood that you create debt by increasing the complexity of your code organization.
It's really not a problem for me. I've worked on probably about 20k LOC of zig. Probably the one time it was an issue was when I wrote some code that wrote zig -- and then it pushed me into realizing that this was a code smell, and a refactoring fixed it.
Compile times of 2-5 minutes can happen in langs that are not rust. You mentioned rust, not me. And anyways the 30s to hn thing is real.
It isn't difficult, but it is friction. You hit compile and a few seconds later you get an error that is unrelated to the change you wanted to test. I agree with all those errors once those changes are for production, but sometimes I wish the compiler would just shut up and let me test the actual change I just made to ensure it works.
Commenting out a few variables isn't always easy either. Every try to add const to a legacy C++ project - it can take days to fix all the errors resulting from adding const to something that clearly is const in usage. I don't know zig, but I wouldn't be surprised if sometimes you get into this type of situation in a large code base (does anyone have a very large code base in zig yet?)
Good habit, maybe, but it shouldn't cause a compilation failure.
Add to that the snowball effect: you comment out a variable, compile, and you get another error because commenting out variable a made variable b unused. Rinse and repeat.
It's a huge and totally unnecessary time sink.
It should be opt-in, so that it's a warning by default, and then, when I'm ready to push my code, I could run some --strict mode that would force me to clean up my code.
One of the features in go that makes it workable is you can assign it away via:
_ = somevar
That eliminates the unused chain problem. Not sure if zig included that part of the feature as well.
Generally I agree though. The main problem with forcing unused variables, imo, is that it forces you to think a certain way. When I'm exploring the solution space on something, those constraints feel inhibiting.
If one suggested this in any other language to suppress "unused variable" warnings it would be considered a lazy way to avoid fixing the issue.
Meanwhile the developer of Zig himself recommended doing this[0] which only shows what a bad idea it is to make this a compiler error imho. It encourages workarounds and enforces something we automated long ago in the form of dead code elimination.
It is when you have chains of them: see Vulkan setup.
In Zig, I find that I put a whole litany of "_ = varname;" at the bottom of my functions (starting with the function arguments) and they stay there permanently. This is NOT an improvement.
However, it's not really enough to stop me from using the language as that's an easy thing to evantually fix.
It is a truly bizarre decision for a language which aims to have a fast change->compile->run cycle, since it can basically double the time the compile cycle takes.
Yeah, I would like a flag that makes the compiler as loose as possible, maybe something like "-fprototype". Then when I'm ready to get serious about correctness, I can remove the flag and be all pedantic.
That's the one thing keeping me from considering Zig for new projects right now.
If some enterprising young developer is reading this and wants to make a name for themselves, you should fork the Zig compiler and change those errors to warnings. It would be an extremely popular project.
EDIT: I'll even give you a catchy project name. Wig: Zig with Warnings
The patch works, but it's not efficient to have every user patch their own compiler on every release (and forgo the system package manager for upgrades). I was also envisioning adding a warning system, changing the checks to warnings instead of removing them completely, and adding a `-Werror` flag (or maybe `-Wno-error`). It would be a bit more than 5 lines, but still relatively low effort compared to how impactful the project would be.
Unused variables don't make a program incorrect. When you comment out unused variables to prevent Zig's compiler error you don't remove the dead code, you in fact make it more likely to stay in the codebase because now it's only visible to humans. While almost every other language will print out a clearly visible warning without disrupting the workflow.
I can only see downsides and no upside in this design. Why would you slow down the development workflow for something any decent compiler will discard as basic optimization step? It's an error about something that has absolutely no impact on the resulting program and its execution, you can probably find a dozen better reasons for Zig to throw errors where it doesn't.
You're right, the provocation here is engaging in intentionally
choosing a language, and choosing Zig, is optimizing for incorrectness. I didn't mean the flag.
Fridays are my live streaming day and I've chosen today's topic to be the user experience of unused variable errors. I have an idea to solve this that can satisfy both parties - those who don't want to be bothered by such errors, and those who want the premise upheld that if Zig code compiles, it does not have any unused variables.
Nice to see you here. I'm not much of a twitch guy, but I'm glad this is on your radar and I'll read about it afterwards!
If you're talking about the `zig fmt` idea, I'd like to draw your attention to a possible pitfall -- Silencing the errors with _ increases the risk that unused vars will be committed to the repo. https://news.ycombinator.com/item?id=32753079
I normally add the equivalent of `-Werror` to pre-commit and CI. But if those warnings are silenced directly in the source code, I can no longer rely on the compiler's guidance to clean up the code, and I would have to hope I could remember all the places I need to clean up before committing. In that way, solving this in the formatter could have the opposite effect on code quality than you intended. I _do_ want the compiler to yell at me... just not yet. Only when it comes time to commit.
Overall I've been impressed reading about Zig's design. You clearly have good engineering taste and I respect you challenging the status quo and trying unconventional ideas, even if I may disagree from time to time. I'm itching to start using the language once this is solved!
That's just going to result in people committing unused vars to their repos. People are already doing that now after adding '_'s by hand. https://news.ycombinator.com/item?id=32753079 It's going to get even more common when underscores are automatically added all over your project without user input and you have no chance of remembering where they all were.
If the goal of not having warnings is to increase code quality, it's actually doing the opposite.
I don't understand this insistence on working around the problem by layering on tooling, instead of just fixing the problem to begin with.
Looking at the top 5 they used zig,zig,rust,odin,asmscript
Rust is the highest level represented. I'm guessing the level of control needed to hit the tight constraints of wasm-4 preclude anything that you wouldn't use for a microcontroller. C and c++ would work too, but what fun is that?
Yeah, I did. The previous WASM-4 Jam had Zig and C tie at the top followed by Rust. Other languages also had more representation than in this last one, maybe also because of a greater overall number of entries (44 total).
I also think that there is a correlation between the majority of participants being from Europe and Zig. At the moment almost all our meetups are in Europe.
I can only speak for myself here but of all languages I've tried for WASM-4 (WAT, C, Rust & Zig) it is the most productive one for me.
I really enjoy the balance of safety and control in Zig. I can build using Debug mode during development, turning nearly all my bugs into crashes which are easily fixable using in-browser source-level debugging. But in Release-Small mode the result is fast and more importantly really small since there's a 64kb cartridge limit.
Another factor is the Zig Standard Library which designed to be portable and usable on freestanding targets. I can not emphasize enough how pleasant this is. For example I can just use a `std.heap.FixedBufferAllocator` to back a `std.ArrayList` with no problem.
The comptime feature of Zig also comes in handy when you have to minimize code size.
The seamless C interop furthermore improves my productivity since I can just use any C code I like. I've used a C perlin noise library in a previous game for example, saving me a lot of time.
Plus I've used Zig for the previous WASM-4 jam and just liked it so I didn't bother trying any other language.
Zig is not mentioned until the section "Programming languages" (including not being mentioned in the original title): please fix the title so as not to put too much focus on that.
I've noticed people that like writing code in Zig are fans the language and the people that like writing code in Rust center their identity around the language. The former leads to people saying they enjoy writing code in Zig, the later leads to religious zealotry and moral condemnation for using anything other than Rust.
It's perfectly reasonable to take the position that it's deeply problematic for a language aiming for wide use in 2022 to not be memory safe. There's no requirement that you "focus on tradeoffs", especially since real people get hurt by memory safety problems.
Not sure which lens you are using for coming to this conclusion. In my experience, most people writing Rust code have no "moral superiority" and treat Rust as a "better tool", not as a religion per se.
However, what I've seen in the discourse of several programmers that claim to prefer Zig is the assumption that Rust is "not really that big of a deal". There's a constant minimization of the advancements both the ownership system and the safety approach provide, and a lack of recognition for the fact that the language is a "game changer" in the industry.
Overall, this looks a lot like rationalization of an emotional choice, which for me is much more close to religious zealotry.
> However, what I've seen in the discourse of several programmers that claim to prefer Zig is the assumption that Rust is "not really that big of a deal". There's a constant minimization of the advancements both the ownership system and the safety approach provide, and a lack of recognition for the fact that the language is a "game changer" in the industry.
I think you have inadvertently worded this in a way that silently confirms what the parent poster was saying. But more generally, while I can't speak for the entirety of the Zig community, the people involved with Zig directly tend to be aware of Rust's strengths. The problem is that one of the reasons why Zig exists (and is having some level of success) is because some people just don't want to deal with abstraction-heavy code. Some people value simplicity over a complex language with a memory-safe subset.
And the value of simplicity is not just a matter of aesthetics. Simplicity is a defense against bugs, because memory safety is not the end goal, correctness is.
I think the issue is memory safety is reachable. Correctness is either extremely hard (proof program satisfied specifications) to nigh impossible (make sure all icon pointy things are aligned).
I totally get it's nicer than C, I love it too, but it's completely irresponsible to push a language without a memory safety story, in 2022, this hard.
From that relatively obvious conclusion it devolves into tedious nerdsnipes. Yes there are edge cases.
That's extremely hyperbolic. Zig is a systems programming language with an explicit goal of operating at a low level of abstraction. Virtually all languages in its class are less memory safe than Zig.
Except Rust? We can't ignore the fact that Rust has shown that memory safety is not incompatible with low-level semantics. (Of course, Ada, Cyclone, CCured, etc. showed this much earlier than Rust.)
Zig has very different goals than Rust. The explicit theory of the language is that Rust's approach to memory safety creates costly tradeoffs which are not needed for all use-cases.
It is very much not the consensus that memory safety is a requirement for any modern language. Asserting that it should be a requirement is an extreme position.
"Virtually" is where your argument falls apart, and I want to be clear I'm not just dunking and moving on, I do understand the position that _not_ using a memory safe language is irresponsible is fairly new.
That position is not only new, it's also not the consensus. Zig explicitly chooses to make memory safety a non-goal of the language, with the argument that Rust-style memory safety is a costly tradeoff which is not always justified.
Assuming that my argument has "fallen apart", or that you have "dunked" seems quite absurd given that you've taken an extreme position which many serious practitioners and academics would disagree with.
The point is that Zig's choice around memory safety makes its language design principles significantly outside the consensus around what PL design should be.
According to who? It's absolutely not the consensus that every programming language needs to prioritize safety.
Rust is still very much an experiment in terms of systems programming. It has a tiny overall "market share" in terms of use in large production projects compared to C/C++ and it remains to be seen whether the particular set of tradeoffs chosen by the language will lead to long term sustainable success.
Zig takes another approach and is also a worthy experiment.
You make my brain hurt. You have these extremely long circuitous set of comments that hopstoch between insisting we're talking about Rust and that it's literally impossible to do the things you do in Zig in a memory safe language.
It's especially frustrating because you've received a ton of charity and time from strangers, we understand 110% what you're thinking (I wish it was true! I've had an inordinate amount of work for 18 months now because it isn't) but you can't seem to wrap your mind around the idea that there isn't some niche where Zig is perfect and unassailable or the only alternative is rust. I don't think you have much experience in multiple languages, it's actually fairly easy to get something as fast in JS _as in C_.
With all due respect, your comments seem to imply a certain level of immaturity and it does not seem like you really know what you are talking about.
It's possible in some cases that you can implement something in JavaScript which is competitive with a systems programming language, thanks to all the incredible optimization work which has gone into JavaScript engines, but the performance ceiling of a language like JS is much much lower than that of system programming languages. For instance, if you are optimizing for memory cache performance C or Rust or Zig are going to have tools which just don't exist in JS. There's a reason that HPC - one of the computing fields where profitability literally depends on speed - is all implemented in C and C++.
And not that it matters but I've got plenty of experience with languages. I've been doing software engineering professionally for over a decade, and I've shipped professional projects in probably a half dozen languages or more including C, Rust, and Javascript. I've also done my fair share of programming in the systems domain, including computer graphics and games. I've also implemented programming languages of my own.
> you can't seem to wrap your mind around the idea that there isn't some niche where Zig is perfect and unassailable or the only alternative is rust.
I never said Zig fits a perfect niche. I said the theory of the language is valid, and it's a worthwhile contribution to the field. Zig, like all other languages, is an experiment. It's actually quite an interesting one with different goals than a lot of the other popular languages out there, and which is very appealing for the systems programming domain. I'm arguing against the idea that Zig is "irresponsible", which is an extreme position.
I keep bringing up rust because of you guys insistence that Rust is a counter-example to the idea that a new systems programming language not necessarily be memory safe. For instance this comment:
> We can't ignore the fact that Rust has shown that memory safety is not incompatible with low-level semantics.
Seems to imply that Rust's existence unto itself is proof that every new systems programming language must be memory safe.
C is the current standards bearer for systems programming. Everyone is trying to invent a "better C". Go and Nim are trying to do it with garbage collection. Rust is trying to do it with the borrow checker. Zim is trying to do it with ruthless simplicity and explicitness.
All of these are experiments, and all of them are valid. 20 years from now we'll know a lot more about what works and what doesn't from each of these experiments, but it's too early to conclude that now.
Zig has a pretty good memory safety story -- and more generally, a correctness story -- it's just a different story from Rust's. I find it funny that fans of a language of a not-so-young-age that is struggling to find relevance and capture even 1% of the market are treating it as such an inevitability that it's irresponsible to talk about anything else. It's also detached from reality, as much of the software we all depend on is being written, in 2022, in languages without sound memory safety guarantees. There are various approaches being tried for how we should write low-level programs in the future, but there is no consensus yet on the best one.
No, Zig is simply not memory safe. That's a property of a programming language that has a definition. Zig does not meet that definition.
> I find it funny that fans of a language of a not-so-young-age that is struggling to find relevance and capture even 1% of the market are treating it as such an inevitability that it's irresponsible to talk about anything else.
Leaving aside your weird description of a language powering software that serves billions of users as "struggling to find relevance", most software in 2022 is written in languages that are memory safe. Zig is quite the outlier here. It would in fact be very reasonable to survey the landscape of popular languages today and come to the conclusion that memory safety is an inevitability.
> It's also detached from reality, as much of the software we all depend on is being written, in 2022, in languages without sound memory safety guarantees.
Virtually all of that software is being developed in C or C++. The most compelling reason to use those languages is that they have a huge install base and a huge amount of code already written in them. This says nothing about whether a brand-new language should be memory safe.
> There are various approaches being tried for how we should write low-level programs in the future, but there is no consensus yet on the best one.
No, there actually is PL consensus that all new languages should be memory-safe, maybe aside from very low-level specialized languages, which Zig is not trying to be--Zig is trying to be a general purpose language.
I didn't claim that it is. I said it has a good memory safety story, i.e. mechanisms that soundly guarantee some kinds of memory safety, plus a design that helps write correct programs. Correctness in general, and memory safety in particular, are very central concerns in Zig's design, it's just that its story isn't one of sound guarantees across the board but, rather, some balanced mix of approaches -- some based on soundness, others based on facilitating comprehension and easier testing.
> Most software in 2022 is written in languages that are memory safe. Zig is quite the outlier here.
No, Zig is a low-level language, and the vast majority of low-level programs in 2022 are written in languages whose memory-safety story is worse than Zig's.
> This says nothing about whether a brand-new language should be memory safe.
That's right. We don't yet have an answer to that question, because we don't yet have sufficient experience with low-level languages that do have sound memory safety guarantees. I mean, it sure is better to have more guarantees if they come for free, but there's no such option in front of us just yet.
> No, there actually is PL consensus that all new languages should be memory-safe
No, there really isn't one when it comes to low-level languages (and the interest in Zig is proof that there is no consensus that it shouldn't exist). Rust is a low level language with sound memory safety guarantees, which comes at a price that makes it unappealing for some, and so various other approaches are being tried as well.
You can't insist there's consensus when clearly there are people who disagree with you. That's the definition of a lack of consensus. I also think it is premature, to say the least, to declare an approach that is currently still far from proving a success as the only way.
> I didn't claim that it is. I said it has a good memory safety story, i.e. mechanisms that soundly guarantee some kinds of memory safety, as well as a design that makes it relatively easy to help write correct programs.
Zig doesn't have mechanisms that soundly guarantee some kinds of memory safety. It's not spacially memory safe: extern unions, sentinel-terminated pointers, and multi-element pointers break it. At best, we think there's probably some subset of Zig that you could define that is spacially memory safe. (This isn't a particularly interesting property because it's trivially true for any language, by the way: C without pointers and without arrays is a subset of C that's memory safe, for instance, and also uninteresting.)
> No, Zig is a low-level language, and the vast majority of low-level programs in 2022 are written in languages whose memory-safety story is worse than Zig's.
Zig claims to be a general-purpose language, not just a low-level one. From [1]: "Zig is a general-purpose programming language and toolchain for maintaining robust, optimal, and reusable software."
> I mean, it sure is better to have more guarantees if they come for free, but there's no such option in front of us just yet.
It's better to have more guarantees if the benefit of the guarantees outweighs the cost, not if there is no cost. For example, for many apps, the benefit of memory safety outweighs the cost of a garbage collector.
> You can't insist there's consensus when clearly there are people who disagree with you. That's the definition of a lack of consensus.
Consensus doesn't mean that nobody disagrees. It means that the opposite position is a fringe view.
> Zig doesn't have mechanisms that soundly guarantee some kinds of memory safety.
It does.
> It's not spacially memory safe: extern unions, sentinel-terminated pointers, and multi-element pointers break it.
We've been through that. Those are syntactically delineated unsafe features for C/hardware interop. Rust has them, too.
> This isn't a particularly interesting property because it's trivially true for any language
That's right, but Zig is much closer to Rust than to C in that regard. It has clearly marked unsafe features for C or hardware interop, which aren't used in other situations and could be mechanically excluded -- just as in Rust.
> Zig claims to be a general-purpose language, not just a low-level one.
Surely you agree it's also a low-level language?
> It's better to have more guarantees if the benefit of the guarantees outweighs the cost, not if there is no cost.
Yep, and we don't know if we're there in low level languages. So far it seems that some people find the cost of Rust acceptable and others do not. In other words, there's no consensus on what the acceptable cost is.
> It means that the opposite position is a fringe view.
So disagreeing that the only right design is that of a language that's struggling to get 1% of the market is a fringe view? That's like a Haskeller declaring that it is a fringe view to disagree that non-strict pure functional programming is the only right way to write programs. I think that Odin and JAI, two other low level languages in development, also don't go down the full memory-safety soundness path. Seems to me to be quite far from a fringe view.
If people aren't buying what Rust is selling -- regardless of how strongly some feel about the justice of its approach -- I think that those of us who care about correctness must explore alternatives, and Zig is certainly a fascinating alternative. It might well be the case that neither Rust nor Zig succeed in the market, but even in that case, both can certainly serve as inspiration for the languages that follow.
> We've been through that. Those are syntactically delineated unsafe features for C interop. Rust has them, too.
And again we're assuming that the ones we went over in the previous thread are all there is. I found some more: @intToPtr, @bitCast, @alignCast. Some of those @ functions are spatially-memory-safe, and some are not: the differences are not clearly called out.
(I'm going to charitably assume that taking a pointer to an element in a dynamically-allocated array, and then shortening that array and dereferencing that pointer, is a temporal memory safety violation rather than a spatial one.)
> That's right, but Zig is much closer to Rust than to C in that regard. It has clearly marked unsafe features for C interop.
How are they clearly marked, when they're neither relegated to a separate section of the documentation nor behind a switch? As far as I can tell, the person who has gone through the most effort to isolate the spatial memory safe subset of Zig is me, in these HN threads.
> So disagreeing that the design of a language that's struggling to get 1% of the market is the only right way is a fringe view now?
Again, "struggling to get 1% of the market" is a weird way to describe a language that's serving billions of users right now.
> And again we're assuming that the ones we went over in the previous thread are all there is.
No one is assuming that. Like Rust, Zig has a set of unsafe operations that are well known to Zig programmers.
> How are they clearly marked, when they're neither relegated to a separate section of the documentation nor behind a switch?
They are syntactically distinct from the safe features, and they might be hidden behind a switch when there's demand for such a feature.
> As far as I can tell, the person who has gone through the most effort to isolate the spatial memory safe subset of Zig is me, in these HN threads.
So not only is disagreeing with you a fringe opinion, you're now the most knowledgeable on Zig's safety, a subject that is of great interest to Zig programmers? Those who spend the two days required to learn Zig know which operations are unsafe.
> Again, "struggling to get 1% of the market" is a weird way to describe a language that's serving billions of users right now.
Haskell and Erlang are also "serving billions of users" in the same way. The fact is that at an age where almost all programming languages (Python might be the sole exception) were in the ballpark of their all-time peak popularity, only a tiny portion of developers choose Rust. Like Zig, Rust is a language whose future success is uncertain.
Look, not everyone would like Zig, not everyone would like Rust, and for all we know it's quite possible that the main difference between the two approaches is that they appeal to different people. But trying to make Rust's design appear inevitable or uniquely legitimate for low-level languages when that language is doing poorly, or claiming to speak on behalf of a consensus where there clearly isn't one and several other languages targeting the same domain prefer a very different approach, make you sound detached from reality.
I find it a questionable choice to design a new complex language when complex languages tend to do poorly in the market, or to attempt a language for low-level programming that tries to appear high level on the page after C++'s lacklustre success with that approach, but I recognise that not everyone has the same taste as me, and I wouldn't call my opinions a consensus.
Android is heavily adopting Rust. They rewrote the Bluetooth stack, hardware keystore HAL, etc. in Rust and new components like virtualization are heavily using it. This is also behind the effort to get official Rust support in the Linux kernel. Android defines a stable kernel ABI for Linux LTS branches for GKIs (Generic Kernel Images). For example, 6th generation Pixels use the 5.10 LTS branch via a 5.10 GKI which can be updated independent of the device-specific kernel drivers. 7th generation Pixels will use the 5.15 LTS branch / GKIs and 6th generation ones have an experimental 5.15 LTS branch. They want to work towards having the SoC drivers and device drivers written against this stable API/ABI almost entirely written in Rust even if mainline Linux is slow to adopt it.
> a language that's struggling to get 1% of the market is a fringe view
This is an extremely strange argument. How much market share do you think C has in 2022?
You seem to massively underappreciate the dominance of the web and the hegemony of languages like JavaScript and PHP. System languages are a very tiny niche and there's much less changes there than in other domains.
Rust has obviously way less than 1% market share but it's still extremely successful in the niche it's targeting. (And btw, we're talking about the only niche that still hasn't embraced memory safety, mainly because there was no acceptable tools for that meeting their requirements)
> Rust has obviously way less than 1% market share but it's still extremely successful in the niche it's targeting
Extremely successful? It's not even mediocre. A more realistic description of its current position in its niche domain might be "still hanging in there", "not yet completely written off" or "not out of the race but waiting for a miracle."
Rust is barely at 5% of the low-level market. Its performance in its target domain is so abysmal at over seven years old that some who'd want to try it don't because its future looks so uncertain. For comparison, almost every programming language reached or at least neared its all-time peak popularity around age 10. Even if things improve we're looking at a peak of 20% of its target niche before the novelty wears off and other languages join the fray. It needs to double its market share in the next couple of years not to be "extremely successful" but just to stay relevant.
> Oh yeah, I guess Objective-C peaked in 1993, Python peaked in 2001, and Java, PHP, Ruby and JavaScript peaked in 2005.
Objective-C is irrelevant (as its adoption is tied to that of another product, kind of like VBA), and with the exception of Python, pretty much yes (I said neared or reached, not reached). Other than Python, no language showed surprising growth after a decade, including C (1983) and C++ (1995).
> but it will steadily entrench itself as foundational building block of everything that surrounds you, as it has already started.
The evidence suggests otherwise, but things could change. I'm not saying Rust will never succeed, just that current performance and the historical trend don't bode well. Of course, other languages -- Zig, Odin, JAI, and those that don't exist yet -- will also enter the game, and it's not unreasonable to expect that the low-level programming world will experience a similar fragmentation to that of the applications world, where no new language is particularly dominant.
I think it is quite possible that Rust will achieve similar success in the low-level world as Go reached in the applications world. Anything beyond that is not out of the realm of possibility, but there are no current indicators to support that. Rust's adoption rate, in its target domain, is -- today -- lower than that of languages that have achieved unusual popularity in that domain or in others.
> to bash the language
I don't bash the language at all. I bash unfounded claims about it, such as those made in this discussion: that it's achieved extreme success, that all other designs are "fringe", and that it's well established as the best way to achieve correctness. None of these things are known to be true. As for the language itself, I find it too complex and reliant on implicitness for my taste, but I've said over and over that that design is certain to appeal to others. Moreover, I think Rust's "grand idea" of the borrow checker and type-checked lifetimes is nothing short of genius, although I wish it came in a simpler language.
I also don't understand people who become so attached to languages that they deny reality. Clojure is one of my favourite languages, but it's silly to deny that its adoption is low; obviously, it's not many people's cup of tea. I find TLA+ to be one the most useful tools for me, but clearly many don't. I don't understand why people who like Rust need make believe that it's doing well, inevitable, or the only reasonable choice, when the truth -- as we know it today -- is that it's none of those things, yet that shouldn't stop anyone from enjoying it, just as Clojure or TLA+'s lack of popularity has no impact on my enjoying them. Why can't people say, "I use Rust because I enjoy it, I find it convenient, useful, interesting, and beautiful?" Why the need to also make up stuff about it?
> that they spent such a significant amount of their comment activity on HN
This one gave me pause, but I think you'll find that what mostly triggers my HN comments is not so much Rust but claims related to software correctness. I've spent years on this subject, I care deeply about it, and misleading claims about it abound. It's just that recently they've been...
> I bash unfounded claims about it, such as those made in this discussion: […] that all other designs are "fringe"
You're mischaracterizing Mr Walton's argument here: it's not “non-Rust” design which are fringe, it's “non-memory safe”, and he's arguably correct on that front: no mainstream (even in the broadest sense) language that ever came after C++ was memory-unsafe. And C++ has been progressively abandoned from every domain where its performances characteristics weren't enough of an argument. It is the consensus in PL design, whether you like it or not, and Zig is going against that 30+ years old consensus. Rust is simply the first one to seriously challenge C and C++ on their remaining domains, but memory-safe languages are ubiquitous and have been for years.
> that it's achieved extreme success
For the domain Rust is aiming at, no other languages has ever reached this level since C++, that's it. Rust hasn't taken the crown, but it's doing things that have not been done before, and it's a hell of a success for a programming language designer!
> This one gave me pause, but I think you'll find that what mostly triggers my HN comments is not so much Rust but claims related to software correctness. […] (just as before we heard similar claims about Haskell, that triggered me just as much)
I think it's mainly a thinking framework issue. You can view software defects as belonging to one of two classes: (1) design errors, and (2) programming mistakes (typos, copy-paste error, forgetting to call a mandatory function, etc.). TLA+ is a wonderful tool to make sure that your design is correct, but it's helpless against programming mistake. Respectively, the ML family of languages (and Haskell) offer really powerful tools to reduce the number of programming mistakes in shipped code (if it compiles, it has likely no programming errors) but it is completely helpless against broken design.
The frequency or gravity of software defects caused by those two kinds of bugs are context dependent but they are both sources of bugs, so in a sense (even discounting memory-safety) Rust is improving
software correctness by reducing the number of programming mistakes, even if does nothing (if we set memory issues aside) to reduce design errors.
There is no Rust vs TLA+ like there is Coq vs TLA+, Rust doesn't claim it can prove the high level requirements of your problem, it just claim it can prove memory-safety and thread-safety and give you a nice mistake-prone development environment. If you want design correctness, use Rust to implement the design you've validated in TLA+!
> Objective-C is irrelevant (as its adoption is tied to that of another product, kind of like VBA), and with the exception of Python, pretty much yes (I said neared or reached, not reached). Other than Python, no language showed surprising growth after a decade, including C (1983) and C++ (1995).
That's a surprisingly high number of wrong statements per n-gram…
As an aside, in a non-emotional discussion about a programming language, you should probably refrain yourself from insulting one of its designer. Because, yes, saying to a PL designer that his language is “struggling to find relevance” is an insult, the same way calling someone else's mom “fat and ugly”, regardless of the factual accuracy of the statement.
> and he's arguably correct on that front: no mainstream (even in the broadest sense) language that ever came after C++ was memory-unsafe.
I don't understand that logic, as we're only talking about low-level languages. Of all the low-level languages developed after C++, including D, Rust, Zig, Odin, and JAI, the majority aren't memory safe.
> It is the consensus in PL design, whether you like it or not
It clearly isn't even the majority opinion in low-level PL design, let alone the consensus.
> but it's doing things that have not been done before, and it's a hell of a success for a programming language designer!
Sure, by that metric it is a great success.
> it just claim it can prove memory-safety and thread-safety
I know, but the reason it does so is as a means to an end. The reason why anyone wants memory safety is that it eliminates certain classes of bugs that can be quite harmful. The reason why we may not want memory safety is that sometimes it can come at the cost of other bugs, overall not helping correctness. Anyway, software correctness is a complex issue, and it is not currently known whether Rust's approach or Zig's -- if either -- is more effective at achieving correctness.
> Ctrl-F for Rust on this page returns no results…
Yeah, it's an image or something, but it's there.
> you should probably refrain yourself from insulting one of its designer.
> Of all the low-level languages developed after C++, including D, Rust, Zig, Odin, and JAI, the majority aren't memory safe.
It's funny because you've included a language built around garbage collection (D), and a language that doesn't really exist yet (Jai, which is actually a placeholder name). Btw, this list (which basically contains only names we can see every once in a while on HN) shows you're really not familiar with the PL design space (which is fine actually but you should probably not be arguing about academic domains you're not familiar with).
> I know, but the reason it does so is as a means to an end. The reason why anyone wants memory safety is that it eliminates certain classes of bugs that can be quite harmful. The reason why we may not want memory safety is that sometimes it can come at the cost of other bugs, overall not helping correctness. Anyway, software correctness is a complex issue, and it is not currently known whether Rust's approach or Zig's -- if either -- is more effective at achieving correctness.
The idea that Rust may cause more bugs than it avoids is backed by zero evidence. Is Rust worth it, from a engineering team perspective, given its other constraints (low number of trained practitioners, slow compilation time, or even an hypothetical productivity cost) is a fine question, especially when I see Rust being used for back-end roles where other entrenched languages are doing fine, but claiming that “maybe Rust some unknown type of bugs we cannot be sure” is a fallacy (same fallacy applied to a different context: “climate is a complex issue, maybe there's some non-anthropic cause for global warming”).
Zig doesn't particularly address “correctness”, more than any typical language: it doesn't address “design errors” more than Rust, and is arguably addressing less “programming mistakes”. There is no trade-off in correctness between those two (Rust is trading learning curve against correctness, and it might even trade productivity for correctness, but it's not trading one kind of correctness in favor of another).
One can argue that “programming mistakes” are unimportant overall, because they get ironed out easily, and that it's a matter of team experience and proficiency, and in fact in managed languages it may be true, and that would explain why functional programming never took off, but when in comes to memory management, we've had enough CVEs to show that no, programming mistakes don't get ironed out easily.
If you want to see “Zig safety story” in action, have a look at the only commercial user of the language, and go search for “segfault” in the github issues…
> shows you're really not familiar with the PL design space (which is fine actually but you should probably not be arguing about academic domains you're not familiar with).
Oh, I'm familiar enough (my job requires me to be), but I wanted to list languages people here have heard about. Also, I'm not arguing about an academic domain. Having spent just the other night at a gathering with PL researchers in the UK, some interested in Zig, I know that even if we restrict the discussion to academia alone there is absolutely no consensus over the matter. It is an empty and false assertion, plain and simple.
Also, let's not forget that Rust leans quite heavily on a garbage collector, too, albeit a rather crude one.
> The idea that Rust may cause more bugs than it avoids is backed by zero evidence.
I never claimed that it does. I said we don't know which approach leads to more correct software, and that anyone who says we do is simply unfamiliar with the field or misleading. I explain more below.
> that “maybe Rust some unknown type of bugs we cannot be sure” is a fallacy
That's not what I meant at all. Just as an example of things that Rust's design could adversely affect to the point of adversely affecting correctness, consider two techniques that have proven extremely valuable in improving software correctness: code reviews and tests. A complex language with a lot of implicitness, long compilation time, and possibly longer code-writing time, can slow down or hinder these two techniques. Those issues are related to why so many in software correctness research today focus on reducing soundness; soundness has a cost of slowing down very effective unsound techniques, and given that full-soundness is something most have given up on, whether the price is worth it is always a hard question with no easy answers.
> Zig doesn't particularly address “correctness”, more than any typical language...
I think it does, and Zig's designer thinks so too (in the sense that he's designing the language and it tools with correctness as a primary goal) -- I don't know if it's more than any "typical" language (working on a "typical" language myself and caring a lot about correctness, too), but certainly not to any lesser extent than Rust. In particular, there's a very strong emphasis on explicitness over explicitness (no hidden control flow, local reasoning) and there's a strong emphasis on fast compilation and good testing support (including a design that makes isolating units and testing them easier) to facilitate faster and more rigorous testing.
Those who arrive at correctness from academic PL are often unfamiliar with such reasoning, which is now increasingly more common in formal methods research where the power of unsoundness is now appreciated.
> There is no trade-off in correctness between those two
I gave an example above that explains why some people think there could well be. No one can claim that either Zig or Rust yield more correct software, because we really don't know.
> One can argue that “programming mistakes” ...
That's not the argument at all. Memory errors are, indeed, both tricky and dangerous, and it is important to avoid them, but not at the expense of missing other, equally tricky and equally dangerous bugs.
> If you want to see “Zig safety story” in action, have a look at the only commercial user of the language, and go search for “segfault” in the github issues…
If you choose to eliminate bugs of class Y, you'll have none of them, and if you don't -- you will. This has no bearing at all on the question of overall correctness, which is what memory safety ultimately aims to serve. That is why there's no consensus over it.
> Also, let's not forget that Rust leans quite heavily on a garbage collector, too, albeit a rather crude one.
How do you want anyone to take any your words seriously when saying things like this… Rust has reference-counting primitives in its standard libraries, but saying in “leans heavily” on it is a “very original” take (in fact, Rust leans more on “epoch-based memory reclamation” than it does on reference counting, but even if you had that in mind, it's still quite far from “leaning heavily”).
> That's not what I meant at all. Just as an example of things that Rust's design could adversely affect to the point of adversely affecting correctness, consider two techniques that have proven extremely valuable in improving software correctness: code reviews and tests
It “could”, in the same sense that “vaccine could cause autism” or “the US could never have put men on the moon and staged the moon landing in Hollywood”
> I think it does, and Zig's designer thinks so too
Interestingly enough, you spend much, much, more time talking about it than himself…
> I gave an example above that explains why some people think there could well be. No one can claim that either Zig or Rust yield more correct software, because we really don't know.
So the gist of your argument is that we don't know because for “some reason” Rust could make testing (this is ironic when you know how much of an improvement Rust testing story is compared to most languages) and code review less practical, to a point where it would more than compensate for a class of bug that have empirically proven really really hard to avoid with conventional methods like testing, code review or runtime tooling. Wonderful.
> If you choose to eliminate bugs of class Y, you'll have none of them, and if you don't -- you will. This has no bearing at all on the question of overall correctness, which is what memory safety ultimately aims to serve. That is why there's no consensus over it.
I was referring to this quote of yours above: “Zig has a pretty good memory safety story”. Which is empirically not so good.
> It “could”, in the same sense that “vaccine could cause autism”
No. The claim "design with tradeoffs X leads to more correct programs than design with tradeoffs Y" is the one that requires evidence. The null hypothesis is that it doesn't.
> Interestingly enough, you spend much, much, more time talking about it than himself…
As I said, software correctness is my thing. When I saw Zig's brilliant, revolutionary design, I thought, wow, that's a powerful and interesting approach to software correctness. I thought pretty much the same when I saw Rust's design. My aesthetic preferences lean toward simpler languages, just as others' lean toward a more refined type system, but both of these languages make correctness a major focus of their design, they go after it in very different but equally interesting and novel ways, and it will be fascinating to learn which, if any, can achieve better correctness. However, anyone who says we already know is not telling the truth, and probably has a shaky understanding of the subject.
> So the gist of your argument is that we don't know
No. The reason we don't know is that we don't have evidence one way or another. I gave you one example as an intuition for why your hypothesis might be false.
> I was referring to this quote of yours above: “Zig has a pretty good memory safety story”. Which is empirically not so good.
You're saying it's not good because it doesn't try to completely eliminate such errors? That's called begging the question.
Now, you can say many things about me, but when talking about technical subjects I try pick my words precisely. I'll gladly keep discussing the substance of the matter -- I've devoted a lot to it and I care deeply about it (look at my blog) -- but if you're trying to poke at my words you will most likely waste both our time.
Yes, Zig has a pretty good memory safety story. It's a combination of sound spatial safety, precise pointer tracking, as well as some tools, to make catching temporal safety issues easier. It's not only a pretty good story, it's also interesting and rather novel one -- like Rust's -- only its particulars are very different. Zig's memory safety story is not perfect because the cost of perfection, Zig's philosophy believes, is too high, to the point of working against the goal of correctness.
There are two relevant open questions: If correctness is all you care about, what price should you pay for memory safety? And what if you also care about other things? I don't know the answer to these questions -- nobody does -- but we need both Zig and Rust to help us learn.
> No. The claim "design with tradeoffs X leads to more correct programs than design with tradeoffs Y" is the one that requires evidence. The null hypothesis is that it doesn't.
What's the argument here? Is it OK then to question the existence of the Apollo program because “the yanks never went to the moon” is the null hypothesis?
We've plenty of evidence that Rust offers better guarantees than C (even though with your reasoning there could be a hidden second-order effect that makes Rust actually worse than C, we cannot be sure after all, the Rust compiler is slower than C's… /s).
Now since Zig doesn't address the most prominent source of critical defects in C, the null hypothesis is that it won't be an improvement compared to C. (I actually don't think that hypothesis is true either, C is very dated and there are tons of room for small UX improvements, but getting an improvement as big as what Rust offers is a big step to climb with small improvements).
> As I said, software correctness is my thing. When I saw Zig's brilliant, revolutionary design, I thought
Yet you're like two thousand words in and you've not even begun to hint at what part of Zig designs makes it especially good for correctness compared to C.
> However, anyone who says we already know is not telling the truth, and probably has a shaky understanding of the subject.
Like with climate modeling or immunology, we're far from knowing as much as we'd like, but that doesn't mean we know nothing: for instance we know that 1) distributed systems are practically impossible to get right without tools (and TLA+ is a blessing), and we know that 2) manual memory management isn't tractable by a human without assistance. For these two problems, we have decades of empirical evidence that shows that the human brain just isn't able to do it reliably. We also know that 3) so far sanitizer and other runtime tools haven't been enough to get it right in practice.
Zig basically says that even if 2) is true, 3) will not hold for long because it will have “better tools”® than what exists for C. Hard to tell how far these tools will eventually go, but for the moment it has yet to prove anything on that front.
> You're saying it's not good because it doesn't try to completely eliminate such errors?
Yes I am, because ”eliminating completely* such errors” is the standard for every language designed after 1985 that has reached even limited use. (And we're not talking about some low-level stuff that only C or C++ could do, but about a product that competes with another written mostly in JavaScript).
By letting this kind of errors happen, it's a step back of more than 35 years ! And by “happen” or “completely eliminate” I mean “happen enough that it surfaces significantly to the user” (and resp.), I'm not arguing that it should be proven that it cannot happen (in fact, even Rust does make such a claim),but at least it should be exceptional in practice, not one of your most common issue keyword on github…
If Zig empirically had like 0.1% memory issues, then arguing that improving on any other fronts is more important would be fine (like Go not being memory safe in the presence of data race, we can agree that this isn't a significant factor in software reliability using that language and move on), but it's not what's happening. What happens is that the only commercial use of Zig so far is facing a double-digit amount of memory-related crash reported by its users. We're not talking about CVEs found by an adversary here, just Joe the user who has his software randomly crashing at startup. Correctness you said?
> Zig's memory safety story is not perfect because the cost of perfection, Zig's philosophy believes, is too high, to the point of working against the goal of correctness.
As a side note, this is a strawman, Rust doesn't aim at ”perfect...
The argument is that you don't have a hypothesis and then put the burden of proofs on others to prove that it's untrue. The justification for why science must work like this is that most associations must not be true correlations.
> We've plenty of evidence that Rust offers better guarantees than C
True, but our starting point was that neither C (let's call it 0 sound safety) nor Idris (let's call it 100 sound safety) are the best approach, i.e. we know that the most effective way is something in the middle, i.e. we already know that more soundness is sometimes better and sometimes worse.
> Now since Zig doesn't address the most prominent source of critical defects in C
No, that's your claim. Zig is as different from C as Rust is. Zig does make sound guarantees of spatial memory safety (which neither C nor C++ do), and unlike C or C++, pointers cannot be created from "thin air" with pointer arithmetic or with hidden casts such as unions, i.e. Zig has precise knowledge of what a pointer is. This makes tooling for detecting temporal memory unsafely much more powerful and precise in Zig than in either C or C++.
> Yet you're like two thousand words in and you've not even begun to hint at what part of Zig designs makes it especially good for correctness compared to C.
I hope I now did. Plus, its expressiveness is that of C++ (or Rust), not C, while being very simple (two languages are as expressive if there aren't programs in one that require more lines in the other than by a constant factor; C++ has program facilities that require exponentially more lines in C).
> but that doesn't mean we know nothing
Well, whether Rust makes it easier to write correct programs is something we don't know.
> so far sanitizer and other runtime tools haven't been enough to get it right in practice.
You're talking about sanitisers for C/C++. Zig is very different. Again -- full spatial safety, and precise pointers.
> but for the moment it has yet to prove anything on that front.
Sure, and Rust too.
> Yes I am, because ”eliminating completely* such errors” is the standard for every language designed after 1985 that has reached even limited use
That is a very bad argument. You could just as well say that the standard is not to have safety based on substructural types because that's probably too costly. I think it's funny to pretend that Rust's way to memory safety isn't very different from, say, Java's, and doesn't come at a significant cost. It obviously is, and does, and the question we don't know the answer to is: is that a better tradeoff than Zig's?
Also, the number of low-level languages designed after 1985 that have reached even limited use is too small to make any generalisation, let alone a standard, and it opens you to a far worse argument: despite the popularity of memory safety in the application space, no low-level language that has achieved significant use has been memory-safe. Don't try to build statistics on a small sample. Not only is the argument bad, but it can just as easily be turned against you.
> And by “happen” or “completely eliminate” I mean “happen enough that it surfaces significantly to the user”
This is the argument Rust is making that those who aren't so involved in software correctness find compelling, but it is nonetheless false. It goes like this: we have lots of kinds of bugs, if we can eliminate some with soundness, then that must be better! Most formal methods researchers found that argument so convincing in the 70s that they almost accepted it axiomatically. Except it turned out not to be true. Less sound approaches proved more effective overall despite not "eliminating" classes of bugs. But we don't know where the sweet spot is yet.
> Correctness you said?
I don't understand your complaint. First, I hope you're not claiming t...
In the nineties I worked on a big defence project that was written half in C++ and half in Ada. Ada was the Rust of the day, plus it had the weight of the US DoD behind it, which was no small thing. But at the time it was a much more complex language than C++, so we had to have "language lawyers", and, just as bad, its build time was much worse, that in the end we just couldn't test it as well as our more ostensibly sloppy C++ code, the result being that we gradually shifted away from Ada.
I'm not saying that the vision of the seventies of "more language; more formal soundness" is always wrong, but it's certainly isn't always right. The biggest improvement in software correctness that saved us from the total software collapse prophesied by the "formalists" of the seventies, like Dijkstra and Tony Hoare, was the advent of automated unit tests. It's been so effective that it surprised those formalists (like Hoare) as well as confounded those PL people who believed that more and better types are always better (so much so that correctness differences between languages have been very hard to find in recent years except in special circumstances, such as JS vs TypeScript). We learnt that "more language" isn't always the best answer, although sometimes it could be. We just don't know where the "best" tradeoffs are, or even if they're universal. In the past couple of decades we've also learnt more about software correctness from complexity theory, "hard" results that just weren't known to Dijkstra, and that put limits on the effectiveness of soundness. We also learnt some empirical "soft" results -- such as this one [1] -- that showed that sometimes soundness just pushes the bugs elsewhere (i.e. people write code that satisfies the language, yet manage to do this without addressing the fundamental issue, so the catastrophic bug just manifests differently).
None of that is surprising in retrospect. Bugs occur due to a lack of exhaustiveness in human reasoning (or even machine reasoning, as we now have the complexity theory to understand that), so if you're writing an algorithm whose object-lifetimes considerations are too onerous for humans, it is likely that there are other aspects of it that are equally onerous. So what is the right price to pay to prevent that algorithm failing due to use-after-free specifically?
So when a language offers to eliminate certain classes of bugs, even important classes, but possibly at the cost to both static and dynamic functional reasoning -- through reviews and tests -- it is in no position to say that it's obviously the right approach, and that's why there's no consensus that it is. Zig opts to eliminate fewer classes of bugs, up to the point that doing so is free. That's certainly an equally valid hypothesis, a-priori at least, and it will be interesting to see how things develop.
You're basically saying the same thing over and over between different posts, but here's one interesting thing:
> so if you're writing an algorithm whose object-lifetimes considerations are too onerous for humans, it is likely that there are other aspects of it that are equally onerous.
The thing is that you have lifetimes considerations in Zig too. You need to know when to free memory, so you explicitly need to reason about it, just like in Rust in the worse case (when RAII alone isn't enough) but you don't have tools to helps you know when to free and when not to (and only tools to diagnose when you've missed it) so Zig actually adds cognitive burden, not removes it. In the end you'll be reclaiming the memory at the same place (which is where the object is not used anymore and safe to free).
And you keep pointing to reviews and tests, as if rust made it harder, when in fact it makes it marginally easier than for most languages, with its built-in test framework well integrated in the entire stack, and the ability to see where mutations happen. Of course it's not revolutionary nor even unique, but on those two specific subjects in is in fact in among the best languages out there.
So you keep talking about Rust's cost, but the thing is that you can't really pinpoint what types of cost this is about (except with the hand-wavy concept of “language complexity”), and the examples you give are off.
> You need to know when to free memory, so you explicitly need to reason about it, just like in Rust
Obviously! But my point was that that reasoning isn't additive. If an algorithm is complex enough that you have to carefully reason about its object lifetime, then you might have to carefully reason about it even if you're guaranteed to get the lifetime right. Or, rather, sometimes you might, sometimes maybe not, and other times the extra burden of the language is just a chore.
> so Zig actually adds cognitive burden, not removes it
In that regard -- absolutely, in others, it reduces it. Rust's soundness obviously does some good things -- at a price. The question isn't whether those things work, but if they're worth the price. I'm not saying Rust doesn't give me value for my effort; we just don't know if it's more or less than what Zig gives us.
> but on those two specific subjects in is in fact in among the best languages out there.
Except Zig takes that to another level. Rust has some brilliant innovations -- like the borrow checker -- but Zig's entire design is a quite revolutionary, and in multiple ways. That's why I find comparisons between it and C to be so misleading. We've never seen anything like it before.
> So you keep talking about Rust's cost, but the thing is that you can't really pinpoint what types of cost this is about
I don't need to justify why Rust isn't the best approach out there; the onus is on Rust. If we knew which of Rust's approach or Zig's or maybe others altogether worked best, then we wouldn't be trying all of them. We are because we don't know.
But assumptions that soundness was the best approach proved wrong in a surprising ways in the past, and a combination of soundness and unsoundness (those "hand wavy" techniques of testing and reviews) are what proved effective. Bot Zig and Rust believe in such a combination, only in different measures. Perhaps in time we'll find out which works better, but you can't say, "fine, sometimes soundness is better and sometimes it's worse, but my mix is better than yours because it has more soundness."
Now, I'm not trying to convince you, or anyone, that Zig's approach to correctness works better than Rust's; we simply don't know. What I'm trying to get across is why both approaches are novel and interesting enough that we need to try both.
BTW, there's another axis we need to consider. The goal of software correctness from the industry's perspective is not how to write more correct software, but how to write more correct software with the programmers we have. That's why, even though it's possible that the few who can make effective use of Idris might (although maybe not) be able to produce more correct programs than others, few consider Idris as the probably solution to the problem because so few programmers would be able to put it to good use. A language that improves correctness by X around for Y programmers contributes less overall to correctness than a language that improves it by X/2 for 5Y programmers.
> Obviously! But my point was that that reasoning isn't additive
That's a very very strong claim without any supporting argument. And I'd be very surprised if it was true. (the success of the Stylo project on Firefox is a significant counter-example for instance).
> -- at a price.
once again, the abstract “price” is invoked, without any characterization… thousands of words later, we still don't know what price you're talking about…
> Except Zig takes that to another level. Rust has some brilliant innovations -- like the borrow checker -- but Zig's entire design is a quite revolutionary, and in multiple ways.
pron waves hands vigorously
You've shown a real difficulty so far to substantiate your argument with anything concrete (on the “price” of Rust, as well as on the “revolutionary” aspects of zig), though you've spent litterally thousands of words on the topic (and not just this discussion, but many before). As the French quote goes ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire viennent aisément, it makes me think you've mostly a gut feeling (Rust bad, Zig good) about this things and not a rational argument.
> I don't need to justify why Rust isn't the best approach out there; the onus is on Rust.
Nope, Rust is the state of the art, and Rust has demonstrated significant benefits over the previous state of the art. Now if Zig comes and wants to challenge it[1], fine but the burden of the proof is on Zig. Want to prove that essential oils are better than antibiotics? Go ahead, but the onus is on you.
> BTW, there's another axis we need to consider. The goal of software correctness from the industry's perspective is not how to write more correct software, but how to write more correct software with the programmers we have.
> […]
> A language that improves correctness by X around for Y programmers contributes less overall to correctness than a language that improves it by X/2 for 5Y programmers.
Yup, and that's why garbage collected languages are the clear winners of the past three decades.
But Rust is especially well-placed in that regard, because most of its users (even the early adopters) are coming from a managed-language background. And anecdotally, making low level code accessible to more developers coming from a more general-computing background is the main reason why Linus Torvalds is interested to get Rust to the kernel.
[1]: in fact this has never been an explicit goal of Zig's creator, who just want to make his programming language without bothering anyone else. He has nothing to prove, and he's never shown any willingness to take part of the kind of silly arguments, this is only the reactionary “Rust bad, need a champion to rant against Rust in online forums” crowd, who does that.
> That's a very very strong claim without any supporting argument.
I'm afraid you completely misunderstand my position. I'm merely pointing out that because we know that more soundness is not always better, the claim that Rust is more effective than Zig is not obviously true. I'm not saying it necessarily isn't. We simply don't know yet.
> the success of the Stylo project on Firefox is a significant counter-example for instance
A counter-example for what? No one is saying that Rust doesn't work well or that it doesn't offer more correctness than C++.
> You've shown a real difficulty so far to substantiate your argument with anything concrete
But I don't have any hypothesis to substantiate. I'm pointing out what we don't know.
I did give concrete examples for cases where unsoundness worked better than soundness, but because we already know that the most effective approach is not on either end, we cannot extrapolate from any specific comparison to another.
If someone wants to say language X works better for correctness than Y, they must compare X and Y, not X and Z. But I'm not making any such claim about Rust and Zig.
> Now if Zig comes and wants to challenge it[1], fine but the burden of the proof is on Zig.
No one is claiming that Zig works better than Rust, no one wants to "challenge" Rust with Zig, and no one is challenging the claim that Rust works better than C++. I want both languages to challenge the status quo.
> But Rust is especially well-placed in that regard
Of course. Rust and Zig are both well-placed in that regard, and people who care about correctness want both:
First, we don't know which, if any, works better than the other.
Second, even if one of them does work better than the other, I think it's pretty uncontroversial that they both provide better correctness than C++ (they both provide stronger guarantees, and neither is significantly more complex than C++). But because it seems that there are people who don't like Rust, and there are people who don't like Zig, software will be better served by having both.
Those who say they want Zig to not exist (like pcwalton) are not serving software correctness. I want Rust; I want Zig. We don't know what works best, neither of them is for everyone, so we need both.
> in fact this has never been an explicit goal of Zig's creator, who just want to make his programming language without bothering anyone else
Indeed. More correctness than C and C++ is, of course, one of Zig's goals; more correctness than Rust isn't. But more correctness than Zig isn't a goal of Rust, either. We want both to exist, if only because different people would prefer different languages, and both are probably improvements over the status quo. It's pcwalton who said he doesn't think Zig should exist. So let's not bother anyone else by making unsubstantiated claims about which is better, and certainly not by saying that the other shouldn't exist. Okay?
> > That's a very very strong claim without any supporting argument.
> I'm afraid you completely misunderstand my position. I'm merely pointing out that because we know that more soundness is not always better, the claim that Rust is more effective than Zig is not obviously true. I'm not saying it necessarily isn't. We simply don't know yet.
This isn't in any way related to the claim that I qualified as “very strong”: you said “But my point was that that reasoning isn't additive”, which is a very strong claim and likely to be false. The Firefox team successfully shipping their multi-threaded CSS engine in Rust while they had failed to do so in two or three previous in C++ hints that implementing complex algorithms and at the same time having to be sure you don't mix things up with lifetime is harder than just implementing the same complex algorithm without having to think about mixing things up with lifetimes. The great shift towards Java in the 90s is also an indication of it. Taking the responsibility to manage memory manually is hard, very hard and adds a significant burden on the programmer. And this isn't “unknown”.
> and certainly not by saying that the other shouldn't exist. Okay?
Where in my comments can you find a single occurrence of this claim?
I'm just arguing that at this point your reasoning of saying “we don't know which is better” is as fact-based as people arguing that “we don't know if vitamin D or Hydroxychloroquine are better than vaccines”. Zig doesn't have to be on par with Rust to have its right to exists, there's no point overselling with on the “correctness” argument that has never been its main stated motivation. And you, the “Java guy who doesn't like Rust” are practically the only one having this argument on HN, you should try leaving Rust and Zig alone for once.
Anyway, you've long stopped giving arguments and have been parroting the same “we don't know” over and over and over without any attempt to add anything new to the discussion, so I'm not interested in pursuing. Too bad, I won't have a single example of how Rust incurs a cost in correctness, nor how Zig's design is so brilliant it will make thinking about memory more practical than C and avoid memory management to get in the way of correctness, so much virtual ink spent in vain.
> This isn't in any way related to the claim that I qualified as “very strong”: you said “But my point was that that reasoning isn't additive”, which is a very strong claim and likely to be false.
You've misunderstood. I am not trying to make a claim about how reasoning works, but to give possible explanations for why assumptions that more soundness is always better often turn out wrong, i.e. how it could work. The question of why it is that we get such "surprising" outcomes in software correctness is interesting, but we until we get an answer to it, we just know that we get surprising answers.
> I'm just arguing that at this point your reasoning of saying “we don't know which is better” is as fact-based
This doesn't make sense at all. Not knowing is the default. Until there's conclusive evidence, the fact is that we don't know.
> Too bad, I won't have a single example of how Rust incurs a cost in correctness
I don't know that it does. I gave you several examples of how it might: reading it is hard as it has implicitness and compiling it takes long making testing more burdensome. Maybe there are other reasons, maybe there are none.
Now, this is handwaving, but it's more than we need. It's okay to believe that Rust yields more correctness than Zig, the same amount, or less, but until we have empirical findings one way or the other, we don't know, even without any handwaving.
> nor how Zig's design is so brilliant it will make thinking about memory more practical than C and avoid memory management to get in the way of correctness
I explained that, too. Not only does Zig provide sound spatial memory safety -- which neither C nor C++ do -- but it also has precise pointers, i.e. you can soundly track where your pointers are, which is not the case in C/C++, where you can magically create bad pointers from good ones with pointer/array index arithmetic, or magically create pointers from non-pointers with silent casting (like unions). Zig, like Rust and GC languages has precisely tracked pointers. Good pointers can turn bad through user-after-free in Zig, but they can't be "born" bad as in C and C++.
> Where in my comments can you find a single occurrence of this claim?
Not in yours. In pcwalton. You've just tried inverting the rules of science by saying that if you assert something is true and someone else points out that it's an unsubstantiated hypothesis, the burden of proof is on them, thereby making your hypotheses true by default.
Again, I think there can be a wide consensus that both Zig and Rust provide more correctness than C or C++ because they both make stronger sound guarantees and neither is worse at reasoning or testing than C++, but the question of whether any of them is more effective at correctness than the other is unknown, and unknowable until we empirically compare the two. That something is unknown is not a claim that requires proof; until we have proof for something -- we don't know.
Here's what happened with Haskell: Some Haskellers kept insisting that Haskell yields more correctness than some other languages, and that that should be accepted as the null hypothesis until proven otherwise. Then there were a number of empirical tests that believed they'd be able to show it, and they couldn't find any large effect. So even after the empirical examination some Haskellers insisted their hypothesis should be taken as true by default, because the empirical tests weren't good enough. The result is that people who care to claim about correctness get sucked into these beliefs and not even empirical findings (or lack thereof) can shake them. That's not how we move correctness forward. Of course, Rust is not quite in the same position as Haskell because it hasn't been around the long, but it's important not to get too attached to religious beliefs that "this is the on...
> This doesn't make sense at all. Not knowing is the default. Until there's conclusive evidence, the fact is that we don't know.
[…]
> You've just tried inverting the rules of science by saying that if you assert something is true and someone else points out that it's an unsubstantiated hypothesis, the burden of proof is on them, thereby making your hypotheses true by default.
You should definitely take epistemology classes on coursera or elsewhere, because by our definition of “knowing”, we never get to know anything.
And unfortunately this “but we cannot know it's too complex” is way too common nowadays, from climate change to pandemic management “we don't know” is a convenient fallacy. There are key things that we actually do know :
- that Rust is memory safe while Zig isn't (not even from a spacial perspective because there are escape hatches).
- that memory safety is a deep issue and tracking object lifetime by hand isn't something humans are good at, at all. (and use of Zig in the wild shows that the issue is unsurprisingly very common in Zig, as it is in C).
So, yes we cannot be sure that there aren't second orders or third orders effects that makes Rust less than optimal and compensate for this massive difference, but there exist no convincing list of such hypothetical effects that could have a significant impact in Rust's ability to build correct software (to take your examples about legibility and testing, Rust has a strong emphasis on explicitness and incremental builds are more than fast enough for efficient testing, so there's little margin for gains on these fronts).
So have clear evidences of a strong first order effect in favor of Rust, and no compelling evidences for adverse higher orders effects, that's what our current knowledge is.
That's a big difference with your Haskell example, because Haskell cannot really pinpoint a significant edge over other languages, it's more a collection of convenient little things, so the improvement is much more vulnerable to higher order effects. The same could be said if we had to compare Rust and Java for instance: I much prefer use Rust than Java because there are many things that I like but at the same time there are little things that are decisively in favor of Rust (Send and Sync trait for compile-time thread safety is nice, but really workload dependent) so I'd be very wary of saying that Rust leads to more correct code than Java.
But Zig carries a significant burden in that regard (and I believe it should really think about introducing a borrow-checker-like in its design before it's too late and compatibility with existing code makes it impossible, while eschewing the whole ML-style functional stuff that Rust has, because that part is definitely in the “nice to have but not really significant” category).
> because by our definition of “knowing”, we never get to know anything.
I was talking about the common scientific method. You can define "know" as "the vast majority of the target community is sufficiently convinced that something is true."
> and use of Zig in the wild shows that the issue is unsurprisingly very common in Zig, as it is in C
You've seen absolutely no such thing.
> So, yes we cannot be sure that there aren't second orders or third orders effects that makes Rust less than optimal and compensate for this massive difference, but there exist no convincing list of such hypothetical effects that could have a significant impact in Rust's ability to build correct software
I am not doubting Rust's ability to build correct software, just the claim that it's obviously the best approach.
> Rust has a strong emphasis on explicitness
I think you don't understand what "explicitness" means in this context, as Rust relies on more implicitness than most popular languages.
> So have clear evidences of a strong first order effect in favor of Rust, and no compelling evidences for adverse higher orders effects, that's what our current knowledge is.
Taken as is, you're once again claiming that your belief requires no evidence. Taken more charitably, what you're saying is that you believe it because it is very obvious to you. In that case, either it will be easily verified by the evidence and rather quickly, or it will be shown wrong just like previous "obvious" beliefs regarding software correctness.
What you can't do is is demand evidence from others because what's obvious to them isn't obvious to you, and at the same time claim that what's obvious to you and isn't obvious to others should be assumed true.
> because Haskell cannot really pinpoint a significant edge over other languages
I don't know if you're aware how this kind of argumentation sounds to others, but are you really comfortable making such arguments to support what is a scientific claim? Not only did Haskell supporters say the exact same thing (their edge over, say, Clojure was, of course the type system) but even after time and again we see how complex this subject is, how elaborate the interactions, you make an argument that is not much stronger than, "well, I have more money in my wallet than you, and since I can't immediately see any indication that you have more in your bank we can safely assume I'm richer than you."
> But Zig carries a significant burden in that regard
And Rust carries a significant burden, too: it hinders, in comparison, the two most effective assurance methods we have, tests and code reviews. Just as importantly, too many people find complex languages unappealing, and so the impact a language that not many people would use cannot be large.
Now, I am not trying to convince you that you're wrong, just that different things are obvious to different people, and unless something is obvious to pretty much everyone -- which clearly isn't the case here -- you cannot expect others to just accept your belief, however strongly you believe it, while demanding evidence from them for not accepting it.
The fact is that however obvious it may seem to you, other do not not seem to think that it is obvious that Rust leads to more correct software than, say, Zig. If you're trying to convince others of that, then you have to support it by their standard, not yours (of "faith alone suffices"). I would suggest not repeating arguments that are not only logically weak but have failed just recently, and prefer empirical evidence.
But hey, do what you want, and if you believe that everyone should be convinced or that perhaps everyone is already convinced -- that's fine, too. Just don't be surprised when others find such assertions of faith somewhat cultish and not a good look for programmers.
It's funny to read you talking about “beliefs” and “cult” while at the same time being in such a denial:
> You've seen absolutely no such thing.
Just go ahead, grab a few popular projects in Zig (for instance Bun or the zig compiler) and their issue tracker and see how fine the situation is.
And as an epistemological conclusion to this discussion, I should note that while you use “beliefs” pejoratively, but “knowledge” is in fact nothing more than rationally founded “beliefs” that's open to perpetual questioning ;).
Here you just refuse to accept to even think about the rational arguments because they go against your beliefs, hence the reluctance to address the arguments when I've exposed them, falling back to parroting your common sense over and over.
FYI the Zig compiler that people are still using today is the C++ one. The self-hosted compiler hasn't been released yet. There's some Zig code running today in the C++ compiler, but hasn't been there for the full life of the project and isn't the main source of bugs by far.
To this day I think the top 3 popular Zig projects are Bun, as you mentioned, then River [1] and TigerBeetle [2].
Most of the recent segfaults that have been fixed in Zig where Zig related, not caused by C++. (Without even mentioning the segfault in the std lib).
And about tigerbeetle, this gives you an idea of how compelling the zig memory safety story is today:
> All memory must be statically allocated at startup. No memory may be dynamically allocated (or freed and reallocated) after initialization.
And then both river and bun have their shares of segfaults, with river looking substantially better than bun, but it suspect it also has much less usage in the wild.
> Just go ahead, grab a few popular projects in Zig (for instance Bun or the zig compiler) and their issue tracker and see how fine the situation is.
I don't understand. Zig's approach to correctness means giving up on some sound memory safety guarantees in exchange for benefits elsewhere, i.e. it prefers some memory bugs in exchange for fewer others. What conclusion is it, again, that you're trying to draw from the existence of such bugs, and how do you conclude that they occur with the same frequency as in C? Your claim is statistical and I don't see what statistical method you used on the bugs you saw to support it.
> Here you just refuse to accept to even think about the rational arguments because they go against your beliefs
My only relevant belief here is that we do not have evidence supporting the claim that Rust yields more correct software than Zig, and the only rational argument that could go against that belief is the presentation of such evidence. I have no belief regarding which of Rust or Zig yields more correct programs (if either). The reason I have no such beliefs is that I know how complex and unintuitive software correctness is, and both languages have chosen interesting and novel approaches that are not directly comparable based on prior evidence, and so they themselves will have to produce that evidence over time.
Because you asked me to address your arguments (which aren't such a presentation of empirical evidence), the reason why they're unconvincing is as follows. When comparing both Zig and Rust to C++, it is reasonable to accept the claim that they both lead to more correct programs. Why? Because the claim is that they both dominate C++, i.e. they catch all the bugs that you'd catch in C++ plus more. They both make more sound guarantees, and their readability is no worse.
But that is not the same argument used to compare Rust and Zig, because they're incomparable: Rust makes more sound guarantees but it's more complex and requires more non-local reasoning to understand (and might appeal to fewer people), while Zig makes fewer sound guarantees but in exchange it strives to be easier to understand (and to appeal to more people). I.e., the argument for comparison here is not one of dominance but one of a more profitable tradeoff. Your claim that we should value the "hard", formal soundness aspects more than the "softer", informal, aspects is unconvincing because the history of software correctness shows it's a mistake to do so -- "soft" correctness techniques have proven at least as powerful as hard, formal ones, if not more. So, when the tradeoff involves both the formal and informal components of software correctness -- an interaction known to be complex and surprising -- it cannot be settled by simple argumentation, but only by empirical evidence.
That is my one and only argument: because the two languages are not directly comparable as they consciously make different tradeoffs in their chosen paths for correctness, comparing their outcomes requires an empirical test.
Since I've written about software correctness quite a bit over quite a few years now, I think the claim that I am not open to reason in that area is easily disproven by the available material. On the other hand, when someone tries to convince other professionals and fails to do so, saying "you're not convinced just because you're not open", does not lend more credence to the argument. I guess we could call that, "proof by plea", which is not, as far as I know, established as a legitimate form of knowledge gathering in science. But, like I said before, if you think the problem is me and not the strength of your argument, you can put that to the test: publish a scientific paper arguing that Rust leads to more correct programs than Zig (not C or C++), and see how many are convinced by it. If I'm the only holdout, then I'd know the problem is me; i...
> Why? Because the claim is that they both dominate C++, i.e. they catch all the bugs that you'd catch in C++ plus more. They both make more sound guarantees, and their readability is no worse.
You're talking about rigor but you keep making these laughably strong claims. This one is an extraordinary one, and it's most likely also false just because I'm pretty convinced that copy/move constructors can make some (rare) patterns much simpler and as such avoid bugs in practice. It's not clear if copy/move constructors are a net win, and the overall effect is almost certainly minimal anyway, but that's enough to refute the domination claim.
> I don't understand.
That's the key. And you don't want to understand, I'm afraid.
I have no idea what you're talking about. My one and only "claim" -- a simple statement of fact, really -- is that we lack any empirical evidence that Rust yields more correct programs than Zig, and that because the two languages consciously make different tradeoffs, they are not directly comparable, and so such empirical evidence is needed. That's it.
Everything else is just a response to you asking for more context and examples, as well as explanations for why your arguments are so unconvincing, which you then misunderstand as further claims that they are not (e.g. I do not claim that either Zig or Rust yields more correct programs than C/C++). In fact, I do not claim that any language yields more correct programs than any others (not that I don't think that could be true, I'm just hesitant to make such claims). All I did was explain why such an argument would be more convincing than the argument you're making for Rust vs. Zig.
Seems like we're stuck in a circle where you can't understand what I'm saying and I can't understand what you're saying.
In any event, we've gone full meta. Like I said, if you think I am the problem, that can be easily tested. Put your argument in a paper so that it can be properly critiqued. This way you'd at least know if it's me who doesn't want to understand or that your arguments are just not very convincing. If most software correctness people find it convincing -- yay for you; if not, you'll learn how to make your argument more convincing, so also yay for you.
You've got this funny habit to quote super tiny excerpt from my sentences, and reacting to things very loosely related to what I actually wrote. Why bother with the quotes then?
> Zig does make sound guarantees of spatial memory safety
Mr Walton gave an insightful overview of the many caveats that comes with this statements.
> two languages are as expressive if there aren't programs in one that require more lines in the other than by a constant factor
This is a very concise way of describing explicitness, I like it.
> Don't try to build statistics on a small sample. Not only is the argument bad, but it can just as easily be turned against you. […] Second, you're trying to draw a trend out of tiny samples again; this never ends well.
The famous “statistics” tropes… you know, getting a massive amount of data point and making regressions on top is not the only way to produce knowledge. Once again, epistemology classes for all are sorely needed… Fortunately, the parachutes inventors didn't wait for the numbers to get big enough before handing them to paratroopers ;).
> Also, the number of low-level languages designed after 1985
Yes, but I already answered to this argument: this has nothing to do with low-level here, in that particular case Zig is trying to replace JavaScript, which means it's fair to compare it to JavaScript and other languages.
> I don't understand your complaint. First, I hope you're not claiming that programs written in Rust don't have very serious bugs, just as bad as segfaults.
No, this paragraph is part of the sub-discussion about the statement “Zig has a pretty good memory safety story”, it doesn't involve Rust in any ways.
> You're a step away from saying, 100% of commercial Zig programs crash, <100% commercial C programs crash, therefore it's better not to have spatial memory safety. It's like talking about a person who dies from some illness
I have another analogy for you: it's like talking about someone who's just eaten an unknown mushroom and is now dying. I can't be sure that it's the mushroom that's killing him (and the standard scientific procedure to be sure about that doesn't involve giving the said mushroom to 100 person just to get a big enough sample set), but we been told not to eat random mushrooms and “it's not the mushroom fault” is not the most reasonable answer at that point, even though the sample is “just 1”. But hey, I can wait until more people it that mushrooms so I can have more data point, I'll keep counting.
> Moreover, I think Rust made the same big mistake C++ did: trying to get a low-level language to look like a high-level one on the page (so-called "zero-cost abstractions"). I think that design philosophy has little pros and too many cons.
This is the main issue in fact. You don't like the language (which is fine) because it takes too much inspiration from C++, but then you're trying to give rational argument of why “it's not that good”. And that's why your argument aren't compelling, and so hand-wavy for the first few thousand words.
In fact there are quite a few people here on HN who've picked Zig as the “herald of the fight against rust dominance” because they where offended by the Rust Evangelism Strikeforce, like what happened with Nim earlier (a decade-old language that interestingly enough had a popularity boost on HN as an alternative to Rust when Rust's influence grew, before disappearing into oblivion when the next champion (Zig) rose).
As a side note it's actually interesting to see how Mr Walton has evolved over the year as a reaction to the “we need a champion against Rust” crowd: he went from “Rust is nice, you should try it” to straight “stop advocating memory-unsafe languages just because you don't like Rust for heaven's sake”.
> almost every programming language reached or at least neared its all-time peak popularity around age 10
This is an extremely vague claim with so many caveats that it doesn't end up meaning anything yet if you state it confidently you might fool idiots into thinking you said something consequential.
It'd be great if there was all the real competition you seem imagine for Rust, but we don't see that. What we see are people pretending that it doesn't matter if they produce crap software using unsafe languages, but their customers are starting to notice.
I don't think there are many caveats at all, and only a single obvious counterexample (Python).
As to "crap software", most of application software these days -- crappy or excellent -- is written in safe languages, and nearly all low-level code is written in unsafe languages, including some of the world's most dependable software, from avionics to OSes. We can say with close to certainty that we can do better than C, but we can also say that full soundness (Idris) is not the answer, so the sweet spot is obviously somewhere in the middle. But we really don't know where exactly -- except that it's not at either end -- or even how wide the sweet spot is (or maybe there are multiple ones, which could be either universally equivalent or dependent on some variables).
There's more we don't know about software correctness than what we know -- it's extremely complicated and affected by factors ranging from formal languages and complexity theory to management, economics, psychology, and social psychology -- but we believe noe that the ideas of the 1970s of full soundness being the only path have proven wrong (including an acknowledgment even by Tony Hoare [1]), and, indeed, Rust doesn't adopt soundness fully, and relies on testing, code reviews and other unsound processes as the main means for correctness, like virtually all mainstream programming languages.
Anyone who cares about correctness (like me -- https://pron.github.io) knows to be very skeptical of any claims for absolute answers, let alone simple ones, on that extremely complex subject.
@pron I was with you before: I think pcwaltons' take on zig is ... Err, unduly negative to the point of rudeness and closed minded — and kinda paints a clear picture for why we're seeing all of the defensiveness in twitter from andrewkelly and the zig folks.
But — I think you're coming into it similarly here against Rust. Unnecessarily rude, antagonistic, and on technical points: closed minded.
@pcwalton The zig team feels they've made good pragmatic choices around memory safety? Cool. Leave a few reasons why it's different from/and why rust took another approach and your take. Dope.
@pron The Rust folk are happy and proud of the inroads they've made in adoption. Dope. Sure, there's different ways to slice the numbers and you feel what? They've taken unearned pride in their work?
I'm a fan of all of your work, but man. This thread has been disheartening.
> you feel what? They've taken unearned pride in their work?
Not at all. I think Rust is a groundbreaking and influential language. Regardless of its success in market, it is a great and lasting contribution to programming language design.
I am, however, triggered by misleading claims about software correctness -- a subject I care deeply about -- which recently tend to come from the Rust community (replacing Haskell), and then annoyed further by claims of inevitability that I find hard to reconcile with the data. Sorry, but I am human :)
The Rust team is rightfully proud of their achievements, in language design, documentation, and also in offering those of us who are interested in software correctness another novel approach to consider.
I actually have never tried Rust and probably never will, you lied when you implied I was a fan of the language. I'd probably hate it, in fact.
The idea it's either "Rust or Zig" allows the poorly considered logical jump to Zig. I wouldn't use Rust because it's annoying too, but I also wouldn't choose Zig because I consider part of my professional responsibility to be using...literally any language that has memory safety.
There is no "jump" to Zig, just a rejection of the claim that all low-level languages "in 2022" must be memory safe -- not just Zig, but also Odin and JAI aren't (I think). If you need to do low level programming, the fact is that in 2022 there is no consensus over whether you should do it in a memory safe language.
If you think it's your responsibility to use only memory-safe languages, then if you had to do low-level programming, you'd have few option, and those options have their own downsides. That's just the reality of low level programming in 2022 -- it can often only be done in non-memory-safe languages. I actually do quite a bit of low-level programming, and I consider it my professional responsibility to strive to do that in a language that is explicit and simple; there are no languages, to my knowledge, that meet my requirement and are also memory-safe, so I must compromise on something because I live in the real world.
> That's just the reality of low level programming in 2022 -- it can often only be done in non-memory-safe languages.
That isn't true. You want to use a language that is more "explicit and simple". That's your prerogative, even if I disagree with it. But you do have a choice, and you are explicitly choosing to reject memory safety.
No, you don't always have a choice, because C is the only language available (not counting Assembly) on some platforms, and even where Rust is available it is not always a reasonable option for a host of other reasons.
I've continued to code on my game submitted to the last WASM-4 jam for months and thoroughly enjoyed improving my messy game-jam code. So I'd disagree with the statement that Zig is only good for prototyping.
Other notable things from the game jam other than Zig being the most popular: it's mostly developers aged 15-24 (hopefully they split that up into 15-19 and 20-24 next time around), and mostly from Europe.
WASM-4 seems to be a technically limited "console" (64kb of RAM, 160x160 console), so it's even more of a niche than just doing game dev for WASM.
You have chance to prevent it. It's not going to be perfect but use huge lesson learned from js ecosystem "mess" (I found this triggers some (many) js folks, it's quite ridiculous).
Javascript "mess" in browsers could be reduced by dividing into two parts. DOM stuff, and pure language stuff. The first part can stay as is. Probably wrapped into thin API for new lang interop. The second part is a completely new lang that compile to wasm (ideal if vice-versa) so that backend could also send wasm to browser and be able to interact with DOM too.
Next, backend js "mess" can be stopped because we have a better way for other languages to develop for the web.
I agree with your line_1 and line_2. However I think Worse is Worse because it's only better 20% of all aspects, that makes it sounds better. Anything can be best with context pruning.
It's great that young programmers are getting into these low-level things! In the early days of Wasm I was hoping we could put together a "wasm 4k demo" competition, but alas, funding these things is more complicated than it would appear. I'm glad this competition happened, and such cool results!
Arguably Zig is a better fit for game dev. At the high end game dev is all about memory layouts and cache optimization, and that goal can run counter to Rust's approach to memory safety.
It can just be limiting in terms of ergonomics. Like I've implemented a couple of ECS's and what you want to do is dispatch a bunch of threads over big swaths of structured memory. One of the main things the borrow checker doesn't want you to do is use the same memory on multiple threads. You can do that in rust, and people have, but you have to put a lot of effort into convincing the borrow checker that what you're doing is ok, or else find ways to side-step the borrow checker.
So basically rust imposes a lot of limitations on how you can structure your program relative to something like Zig or C.
> So basically rust imposes a lot of limitations on how you can structure your program relative to something like Zig or C.
I don't see it imposing that much of a limit. If there is code you know is correct and Rust can't reason about it, do it in unsafe block.
And ECS is not just possible in Rust, but due to mutability guarantees you can make your ECS schedule systems in such way to maximize multi threading. See Bevy ECS.
Using unsafe blocks would fall into the category of "sidestepping the borrow checker". Again, it's possible to do it, but if you're going to do everything in unsafe rust why not just use an unsafe language in the first place?
And how does rust allow you to "maximize multi-threading" over what's possible in other languages? Anything you can express in rust can be expressed in C or Zig as well. The only difference is the implementation you reach will come with static guarantees about memory ownership (so long as you don't use unsafe). So the set of all rust programs is a essentially a subset of all C/Zig programs.
> Using unsafe blocks would fall into the category of "sidestepping the borrow checker".
I kinda want to end this assumption. Unsafe only allows few things.
- access to raw pointers.
- implement or accessing unsafe functions (e.g. C FFI)
- implementing or accessing unsafe trait
- access to unsafe union
- mutate global variables.
You can't bypass borrow checker, and you wouldn't do everything in unsafe. If you write everything in unsafe you are definitely doing stuff very, very wrong.
Rust unsafe is a surgeon's equivalent of a scar. Some scars need to happen, and you can tuck them out of sight if you are clever. However if after an operation you look like a map of scars, it means your surgeon is lacking.
No language can prevent you from abusing it, but in Rust it's apparent when you do it.
> And how does rust allow you to "maximize multi-threading" over what's possible in other languages?
Bevy newbie here so take it with a grain of salt. Because Bevy knows when and how Resources are related it systems can freely run in parallel if two resources are unrelated and mutable, or related and immutable.
> Anything you can express in rust can be expressed in C or Zig as well.
Point of a good programming languagues isn't to enable writting programs that can do anything but to aid programmers in writing error-free programs.
Why do you think we use punctuation and spaces? I remember a talk[1] where he noted spaces/punctuation became a thing only when Christian monks started transcribing written words, as a way of error correction. This was how written word looked before:
> You can't bypass borrow checker, and you wouldn't do everything in unsafe.
Isn't unsafe still bypassing the borrow checker, in the sense that you're mostly using it because you're doing something the borrow checker does not otherwise allow?
> Because Bevy knows when and how Resources are related it systems can freely run in parallel if two resources are unrelated and mutable, or related and immutable.
But again, I don't understand how that is a unique benefit of Rust. It's completely possible to implement something in C which allows multiple threads to run over unrelated memory locations, or the same immutable memory location. As a programmer you have more options for how to achieve this when not restricted by the borrow checker. Most of the ECS systems in existence solve exactly this problem, and probably most of them are implemented in C++.
> Point of a good programming languagues isn't to enable writting programs that can do anything but to aid programmers in writing error-free programs.
I mean, I think it can't be taken for granted that preventing errors should be the top priority of every programming language. It's probably a priority of most languages, but there's no reason it has to take the number one spot.
I would argue the universal priority of programming languages is to enable the programmer to deliver user value through their program. Rust's thesis is that memory safety issues are such an obstacle to delivering user value that the language should prioritize safety at the expense of a certain amount of pain for the programmer. Languages like Zig and Jai prioritize programmer velocity and relegate safety to optional static analysis tools.
Python is another example: it's very easy to write an incorrect Python program, but the barrier to entry is so low that it enables non-programmers like scientists to do very interesting things by copying a few lines off the internet into a notebook.
There's no one best set of tradeoffs. But as I said from the beginning, if one of the main tasks you are doing is manual memory management, as domains like game dev and HPC require a lot of, you might want to choose a language which prioritizes explicit memory management.
> Isn't unsafe still bypassing the borrow checker, in the sense that you're mostly using it because you're doing something the borrow checker does not otherwise allow?
Not really. But using raw pointers and converting to/from memory addresses isn't something borrow checker can check.
It's a borrow checker not address verifier.
E.g. you can take raw pointer, and set two mutable variables to point to it and borrow checker can't know they point to same address.
> But again, I don't understand how that is a unique benefit of Rust.
It's statically enforced by the compiler using Rust's type system.
As far as I know Zig can't say well these two functions can run in parallel because they are at compile time guaranteed to never access same resources and it's impossible to bypass it (outside unsafe). And their content is thread-safe based on the type they satisfy.
> I mean, I think it can't be taken for granted that preventing errors should be the top priority of every programming language.
Douglas Crockford made a good case that every language should on some level try to prevent errors.
> Python is another example: it's very easy to write an incorrect Python program
Python is also older than Java, but even Python is memory safe (GC). Zig and new batch of better C aren't. In that way we definitely regressed.
> I would argue the universal priority of programming languages is to enable the programmer to deliver user value through their program.
If that is truly the case we'd be all programming in Excel and Access. Anything can deliver value, question is - can it be maintained, and at what cost.
In lieu of that a language that makes a set of errors nigh impossible is better than a fast one where those errors are trivial to cause.
> E.g. you can take raw pointer, and set two mutable variables to point to it and borrow checker can't know they point to same address.
That sounds an awful lot like bypassing the borrow checker.
> As far as I know Zig can't say well these two functions can run in parallel because they are at compile time guaranteed to never access same resources and it's impossible to bypass it (outside unsafe). And their content is thread-safe based on the type they satisfy.
Yeah but that's the point. Rust has one way of guaranteeing that two pieces of code don't mutate the same memory at compile time, but that's not the only way to write a correct program which guarantees that. Rust is going to force you to write your program in a certain way to achieve this. There are many other approaches you may be able to use in an unrestricted language which reach a correct and potentially more performant result which are correct, but which rustc cannot verify are correct.
> Douglas Crockford made a good case that every language should on some level try to prevent errors.
That's one opinion. There are many who disagree.
> Python is also older than Java, but even Python is memory safe (GC). Zig and new batch of better C aren't. In that way we definitely regressed.
That's not even an argument. It takes it for granted that lack of memory safety in a systems language is "a regression". That's not an established consensus.
> If that is truly the case we'd be all programming in Excel and Access.
How exactly do you come to the conclusion that Excel and Access are better at delivering value than other programming languages?
> Anything can deliver value, question is - can it be maintained, and at what cost.
Yeah exactly. The point is which language can deliver the most user value in your desired use-case at the least cost. For something like an operating system, where reliability is paramount, it may be a good tradeoff to use something like Rust which is unergonomic and slow to compile because the safety and correctness tools contribute to your use-case directly.
For something like a web front-end project, you're probably not going to choose Rust since it's going to be hard to find enough programmers who are willing or able to get over the Rust learning curve, and Rust's USP's don't do a lot for you.
For something like game-dev, where 30% of what you're doing is thinking about memory layouts, Rust's tradeoffs are actively working against you, and you might appreciate the faster code/build/run loop offered by something like Zig.
> That sounds an awful lot like bypassing the borrow checker.
I guess you could argue it's bypassing borrow checker in weakest possible sense.
Borrow checker checks borrow. You aren't borrowing you are doing pointer manipulation, and presenting it with stuff that isn't its duty to check. I argue for this because people think that unsafe region is no mans land and that rules of borrow checking don't exist there.
> Rust is going to force you to write your program in a certain way to achieve this. There are many other approaches you may be able to use in an unrestricted language which reach a correct and potentially more performant result which are correct, but which rustc cannot verify are correct.
Yes. It is a small downside, with a huge upside. Seatbelts prevent full mobility but I bet you wouldn't advocate for removing them because crashes rarely happen, and they limit your ability to move during driving.
> but that's not the only way to write a correct program which guarantees that
Rust has a provable way to eliminate a set of errors. You'd need to offer hard proof that code you wrote in alternative way, wouldn't have those issues.
And that alternative way might still be expressible in Rust using some abstraction/unsafe.
> How exactly do you come to the conclusion that Excel and Access are better at delivering value than other programming languages?
You mentioned how Python enabled more people to code. I'm willing to bet if only enabling to code then Excel and Access brought programming to more people, yet we don't see them in use, because maintaining is painful and hair tearingly frustrating. And performance is meh as well, but Python isn't winning any speed medals either.
> It takes it for granted that lack of memory safety in a systems language is "a regression". That's not an established consensus.
I value code that has less footguns than more footguns. Rust showed we can eliminate several cases of footguns, so why add them back? In that sense it's a regression. If you don't value memory safety and enjoy figuring out debugging data races, go nuts. Remove the seatbelts, you probably won't crash. However, if you do - It won't be pretty.
> That's one opinion. There are many who disagree.
3+ billion humans use spaces and punctuation as a error checking mechanism. IDOUBTYOUWANTTOGOBACKTOHOWROMANSDIDIT
> You aren't borrowing you are doing pointer manipulation, and presenting it with stuff that isn't its duty to check.
Yeah exactly - you're sectioning off parts of the code and telling the borrow checker to trust you that it's ok.
You can't simultaneously argue that unsafe languages are categorically bad and also use unsafe rust as an argument against rust's limitations. Unsafe is either bad or it isn't.
Static analysis tools outside of the language would also be the way you would check for UB and unsafe behavior in languages like C and Zig.
> Yes. It is a small downside, with a huge upside.
Depending on use-case. Again if your whole programming domain is about memory layouts and the management of allocations, you might want to choose a tool with explicit memory management.
> You'd need to offer hard proof that code you wrote in alternative way, wouldn't have those issues.
Again Rust is only one way to prove those errors don't exist. And for a lot of use cases absolute guarantees of memory safety might not be the greatest concern.
For instance, let's say I am making an HPC program for identifying pricing arbitrage in the market which generates 10 million dollars a day when it's operating. If it takes 10 days longer to implement in Rust, that cost me 100 million dollars. I am not going to care if it crashes twice a day because of an NPE I didn't catch.
> And that alternative way might still be expressible in Rust using some abstraction/unsafe.
Again, once you use unsafe Rust, why not just use an unsafe language?
> You mentioned how Python enabled more people to code. I'm willing to bet if only enabling to code then Excel and Access brought programming to more people, yet we don't see them in use, because maintaining is painful and hair tearingly frustrating.
What's your point? Python is not the easiest code to maintain in the world due to lack of static typing and a host of other issues, but it allows data scientists and others to produce billions of dollars worth of value around the world in ML, AI, and business intelligence operations. You could say they could write more correct, more maintainable programs in Rust, but that pool of practitioners just don't exist who are advanced data scientists and also Rust developers. It's a different tool for a different job.
> And performance is meh as well, but Python isn't winning any speed medals either.
And it doesn't matter because performance isn't relevant in most of the applications where it's used. Just another example of a tradeoff.
> I value code that has less footguns than more footguns.
You might value that but it doesn't mean it's an objective measure of a programming language for all people and all use cases.
> Rust showed we can eliminate several cases of footguns, so why add them back?
It's not "adding them back". Strict ownership enforcement is not a universally accepted advancement in programming languages which every new language gets measured against. It's an experiment Rust is running. It remains to be seen whether it's the right way to do programming.
> 3+ billion humans use spaces and punctuation as a error checking mechanism.
I don't even know what to say to this. Spaces and punctuation got accepted because they're more ergonomic and universally accepted by consensus as the better solution for making text readable. It's a better UX for reading.
Most system programmers do not program in rust. There's no consensus that it has chosen the right tradeoffs.
> You can't simultaneously argue that unsafe languages are categorically bad and also use unsafe rust as an argument against rust's limitations. Unsafe is either bad or it isn't.
I'm not arguing philosophically. I'm arguing from a safety viewpoint. A language that's 100% unsafe is worse than a language that's 1% unsafe.
Saying it's not perfectly safe is sophistry. Nothing is perfectly safe, but you still don't hand out your sensitive bank information to random person on the Internet/street/etc.
> Again, once you use unsafe Rust, why not just use an unsafe language?
Assume data race happen. Would you prefer to audit 30k lines or 3? Unsafe language is unsafe everywhere. In Rust, you can limit your search to unsafe regions.
> Static analysis tools outside of the language would also be the way you would check for UB and unsafe behavior in languages like C and Zig.
Define outside language? Miri is maintained by rust-lang team. And Clippy and so on. Sure valgrind and so forth aren't, but their checks are somewhat complementary.
> For instance, let's say I am making an HPC program for identifying pricing arbitrage in the market which generates 10 million dollars a day when it's operating. If it takes 10 days longer to implement in Rust, that cost me 100 million dollars. I am not going to care if it crashes twice a day because of an NPE I didn't catch.
Sure, but if your implementation has a data race error, that when triggered happens causing massive loss of funds. First you'll have to find the issue (good luck searching most of language and deps).
Then you need to patch it to prevent future errors. And it can happen again. So maybe 3 days here, 5 days there, 4 days there, and so on.
Granted it's a contrived example, but hey... If you want HPC and safety use Java/C#/Lisp, no Rust necessary.
Point being - Strength of Rust isn't in speed of development, so much as in avoiding certain sets of bugs. And borrow checker isn't the only tool to achieve this.
> Depending on use-case.
On that I agree. If your game is one and done (no maintenance), no user content, no MP, basically worse that can happen is crash sure go ahead. Jams are in that way perfect candidates for small langs where speed of development is crucial.
I'd argue most sold games aren't one and done.
> I don't even know what to say to this. Spaces and punctuation got accepted because they're more ergonomic and universally accepted by consensus as the better solution for making text readable.
Keep in mind that in Rome everything was written without spaces for hundreds of years. From their POV the spaces would be just unnecessary fluff. And there are still languages that have little to no spaces, so spaces aren't even universally accepted. See Chinese and Japanese.
> Most system programmers do not program in rust.
I don't understand, this wasn't specific about just systems language? Going from C# to Zig is a safety downgrade (but a possible performance uplift). And GC langs have been used in OS implementations.
> There's no consensus that it has chosen the right tradeoffs.
Sure, but consensus is a matter of current status and it's not set in stone.
Status quo is C, which has null - a trillion dollar mistake (adjusted for inflation and software spread :P)
> What's your point? Python is not the easiest code to maintain...
My point that we use Python won in ML because allowing people to achieve value isn't the only important aspect. There are many aspects. Sure you get to pick your own, but I've seen too many CVEs caused by memory unsafety.
But safety and reducing footguns should be ideals for any language to strive. Reintroducing footguns? What's next? Return of GOTO Spaghetti monster.
> Saying it's not perfectly safe is sophistry. Nothing is perfectly safe, but you still don't hand out your sensitive bank information to random person on the Internet/street/etc.
You want to make a nuanced argument that calculated unsafety is better than general unsafety, but you don't want to accept a nuanced argument that Rust's safety tools maybe a detriment in some use-cases.
> Assume data race happen. Would you prefer to audit 30k lines or 3? Unsafe language is unsafe everywhere. In Rust, you can limit your search to unsafe regions.
It depends on the use-case.
> Sure, but if your implementation has a data race error, that when triggered happens causing massive loss of funds. First you'll have to find the issue (good luck searching most of language and deps). Then you need to patch it to prevent future errors. And it can happen again. So maybe 3 days here, 5 days there, 4 days there, and so on.
This is a strawman argument which doesn't reflect reality. C/C++ is actually the main language used in HPC applications like high frequency trading, and they have massive incentives to choose the correct tool for the job.
> If you want HPC and safety use Java/C#/Lisp, no Rust necessary.
You can't. I chose HPC deliberately as an example: in HPC performance is the most important constraint. You couldn't use a garbage collected language because you will not be able to optimize memory performance beyond a certain point since you don't have direct control over allocations.
> On that I agree. If your game is one and done (no maintenance), no user content, no MP, basically worse that can happen is crash sure go ahead. Jams are in that way perfect candidates for small langs where speed of development is crucial.
Then what are we arguing about if you agree with me?
> Keep in mind that in Rome everything was written without spaces for hundreds of years. From their POV the spaces would be just unnecessary fluff.
You don't know that. They might have looked at spaces and understood immediately that it was an improvement.
> And there are still languages that have little to no spaces, so spaces aren't even universally accepted. See Chinese and Japanese.
What point are you trying to make? Wouldn't that support my argument that there's room for different modes of programming, both safe and unsafe?
> I don't understand, this wasn't specific about just systems language? Going from C# to Zig is a safety downgrade (but a possible performance uplift). And GC langs have been used in OS implementations.
I could have also said "most systems programmers don't program in safe languages". The point is the jury is still very much out on whether language-level memory safety is the best solution for all systems programming languages. It's relevant because Zig is the language you are cliticising.
> Status quo is C, which has null - a trillion dollar mistake (adjusted for inflation and software spread :P)
You can focus on the negatives because C is literally the most successful PL ever which the entire world is built on. People are already talking about how GC is a mistake for a lot of applications. Maybe 10 years from now we will be talking about some big mistake Rust made with async colored functions.
Maybe it will turn out Zig's approach is the right one. We don't know yet.
> My point that we use Python won in ML because allowing people to achieve value isn't the only important aspect.
It's the most important aspect. Every other aspect is just relevant to how you deliver value.
> But safety and reducing footguns should be ideals for any language to strive.
I'm sorry but you seem to be missing my entire argument. You agree there are tradeoffs. You agree there are use-cases where safety might not be the most critical thing. You have agreed with every component of my argument but you then want to draw the conclusion ...
> You want to make a nuanced argument that calculated unsafety is better than general unsafety,
No. I'm making a simple argument. More safety is better than less safety. You're trying to move argument that since perfect safety is impossible it's not worth pursuing. This is the sophistry part.
> It depends on the use-case.
No it doesn't. Debugging 30k lines is always going to take more than 3/30/300 lines especially when data races are involved.
> This is a strawman argument which doesn't reflect reality.
I said it's a contrived counter example for a contrived example.
> You can't. I chose HPC deliberately as an example: in HPC performance is the most important constraint.
There are HFT systems using Java, few were on HN even. That said, you might have thought of UHFT, but those use FPGA and ASIC, so not even C/C++ would be really correct.
> You don't know that. They might have looked at spaces and understood immediately that it was an improvement.
I know human nature. What we are used to is what we consider natural/ergonomic.
And for the record ancient Greek and Romans made it point of pride to know where and how words end.
> Wouldn't that support my argument that there's room for different modes of programming, both safe and unsafe?
Well, not really. I'm saying ergonomic isn't universal. Due do mixing with English and other such languages what's considered ergonomic is shifting towards spaces and punctuation.
> It's the most important aspect. Every other aspect is just relevant to how you deliver value.
Ok, I see where you are coming from but I fundamentally disagree. If you prioritize delivering stuff fast (move fast, break things) you'll end up with a lot of broken software, and unmaintainable messes along the way.
Maintainability and safety should be primary motivatiors.
Without safety, your performance gains can be rendered moot point anyway. And without maintability your code performance will slowly rot and die.
> No. I'm making a simple argument. More safety is better than less safety. You're trying to move argument that since perfect safety is impossible it's not worth pursuing. This is the sophistry part.
I'm not trying to move anything. I've made the consistent argument from the beginning that more language-level safety is not the most important design constraint for all use-cases.
> No it doesn't. Debugging 30k lines is always going to take more than 3/30/300 lines especially when data races are involved.
Yes it does. See HPC use-case.
> There are HFT systems using Java, few were on HN even. That said, you might have thought of UHFT, but those use FPGA and ASIC, so not even C/C++ would be really correct.
The point still stands.
> I know human nature. What we are used to is what we consider natural/ergonomic.
Ok now I suspect you're deliberately waisting both of our time. You can't claim to know what romans thought about spaces.
> If you prioritize delivering stuff fast (move fast, break things) you'll end up with a lot of broken software, and unmaintainable messes along the way.
I never said you should prioritize delivering stuff fast. I said you should focus on delivering value. So if your code is an unmaintainable mess, cleaning up your code is going to be the shortest path to delivering more value because it affects your velocity.
If you're writing OS-level networking code, safety is going to be critical to delivering value because security is paramount to your mission.
If you're writing a game, having direct, explicit, ergonomic access to memory may be more relevant to delivering value than slowing yourself down to make sure you are 100% sure every line of code is safe.
> Maintainability and safety should be primary motivatiors.
Unless they're not. If I'm prototyping a project it might me much more important to get something in front of users to see how they like it than it is to make something safe and maintainable.
Some code is used and built on for years and years. Other code is used and thrown away after it serves its purpose.
> There are HFT systems using Java, few were on HN even.
The HFT systems I know about in Java are mostly not recognizable as Java to most Java programmers. They use static allocation of all data making sure that there is no risk of a GC interrupt and have a fixed set of threads that have assigned cores.
It is sometimes a reasonable way to build a system, but very seldom.
> You can't simultaneously argue that unsafe languages are categorically bad and also use unsafe rust as an argument against rust's limitations. Unsafe is either bad or it isn't.
Why not? Rust has unsafe programming as opt-in; and the unsafe stuff is delimited with language constructs.
A nuanced argument is possible like that situation is better than unsafe computation with no opt-out, requiring very careful programming plus ad hoc tooling.
Jams can be very fad-driven. I'm not familiar with this jam, but Rust's latest game jam was dominated by Bevy, which is a very bad choice for quickly writing a game.
All WASM related stuff seems lacking of know-how of WebAssembly itself. I want the promise of "language-agnostic". For example, I have AST, I want to generate WebAssembly (either text or binary format, lets start with .wat), there's only a couple articles I found talks about how to map string to wasm's memory or table.
Current situation is it's not language-agnostic as movement, it's just c/rust mostly.
Are you trying to say web assembly is not well documented, or are you commenting on the state of tooling? It seems to me that most compiled languages can target wasm these days (eg c, c++, zig, rust, go, .net)
The specifications are open and detailed [1]. Specifications like that can be daunting to consume if you want a place to start from instead of a complete overview of the landscape, but there are tutorials in pure web assembly if you want to get started.
Not tooling. I wrote 8086 assembly before so I remember the process of learning data segment / register / byte allocation / all kind of interrupt. I would choose a word "applied webassembly" (like applied physics) for knowledge that it's lacking. c, c++, zig, rust, go, .net you said fall into "already application" category to me. It's no point of webassembly like no point of assembly when we write those languages.
Right now I am teaching a VM course on the back-half of the Wasm equation: how to build an engine for Wasm. The course is about more than Wasm, of course, so there is a lot of content about JVMs and dynamic object models, but the projects are based around Wasm.
In the future I envision university compiler courses getting divided into two halves, either as one course with two halves, or two full courses. The first course/half would be entirely frontend: parsing, semantic analysis, IR, translation, lowering--and the target would be WebAssembly. The second course/half would be all about compiling Wasm to machine code. If the second course wanted to go more in the VM/runtime direction, vs focusing on compilation, it could include the upcoming GC extension or a custom extension to have objects.
I think Wasm is the future of code formats and languages, so I'd like to move the needle here for PL implementors.
On the other hand, is the SNES "The Legend of Zelda: A Link to the Past" style everyone's favourite pixel art style, or is it just me?
Without tricks it did 256 colours of of 4096 in Mode 7. You can't do art that's as pretty with four colours. Is it a restriction that's too harsh or are we ok with games that just aren't very pretty?
192 comments
[ 3.4 ms ] story [ 324 ms ] threadOT: Searching for Spark2014 brings up a lot of results about the 2014 Chevrolet Spark. A shit box of a car of there ever was one.
I usually put "SPARK2014 programming" or "SPARK2014 Ada" in my searches. I used to get annoyed by all of the Apache Spark stuff that came up, but that seems to have waned a bit this past year or two.
Vermont Technical College (VTC) used SPARK2014 to program their CubeSat and the book, "Building High Integrity Applications with SPARK"[1] is a great intro to it in a nice context of practical use.
There was also an article on the AdaCore site about someone who rewrote some drone firmware in SPARK2014, which is another nice real-world application. [2]
[1] https://www.amazon.com/Building-High-Integrity-Applications-...
[2] https://blog.adacore.com/how-to-prevent-drone-crashes-using-...
In fact, I guess in gas cars sparks are "better" since they are engineered in, and doing useful work.
[1]: https://docs.adacore.com/spark2014-docs/html/ug/en/source/la...
For private lone-hacking projects though it feels way too complex and opinionated. Here Zig definitely gets closer to what I need, though sadly it made unused variables an compiler error (curse you golang for making that popular) which is super annoying for prototyping.
But if you comment var A that uses var B now B is unused and you need to commnet B, but now B was using a function parameter C and this param is unused now so you need to update the function signature (I do not use Go,Zig so maybe they did not forced you to also use all the function params my experience is with linters where ehwn you comment something then more unused warnings appear)
Seriously, I have never had this problem while coding in Go, and I'm a very very sloppy coder.
In any moderately complex function you'll have more than one expression, and those can depend on each other. And you want them to be named and assigned; it makes it easier to read and decode intent and debug things (unless you're one of those wizards who get it right on the first try every time, kudos to you then). I'd not approve a PR that inlines/embeds complex concepts within larger expressions just to avoid creating variables...
Edit: typos
If then you refactor away that single final value you need to delete all the previously used variables that now need to be "deallocated" by you.
Did you ever tried to debug some issue and start commenting stuff to try and find the problematic area? Hell when I comment stuff soemtimes private function will get unused , so with a shit compiler you would need to also comment the private functions, remove unused classes etc.
In my code I assure the linter will say 0 warnings.
Funny enough I was correcting my son c++ homework yesterday, he had a complex if statement like
if (somefunction(m,n, y[j]) == m[j])
and I made him make a local variable to make it clear what is happening. then the code was easier to understand and debug because we culd print that local variable and see if is fine.
Btw, try not too respond that smug, you proved that you are an inexperienced coder and a shit person.
https://www.google.com/search?q=go+lang++compiler+warnings+u...
All those people reporting the issue are not Go developers? Or maybe are not true Go developers, just the other kind, the ones that want generic and nice things.
But yeah, I am not a Go dev, I used linters and I would hate having to be forced to clear all the unused warnings before I can test the code.
If it gets to 2-5 minutes the likelihood that you stop writing tests and rely on the compiler for bugfreeness goes up - or the likelihood that you create debt by increasing the complexity of your code organization.
And juggling variables was an ongoing ordeal when I tried. I can't imagine how you would work on code without changing any of the variables.
Compile times of 2-5 minutes can happen in langs that are not rust. You mentioned rust, not me. And anyways the 30s to hn thing is real.
You can leave those "unused variable" warnings and fix them before release
The difference is that warnings are visible, the underscores however suppressed the compiler's ability to help you.
Commenting out a few variables isn't always easy either. Every try to add const to a legacy C++ project - it can take days to fix all the errors resulting from adding const to something that clearly is const in usage. I don't know zig, but I wouldn't be surprised if sometimes you get into this type of situation in a large code base (does anyone have a very large code base in zig yet?)
Only until getting rid of unused variables becomes a habit before you hit the compiler. Which is a good habit to have anyway.
Add to that the snowball effect: you comment out a variable, compile, and you get another error because commenting out variable a made variable b unused. Rinse and repeat.
It's a huge and totally unnecessary time sink.
It should be opt-in, so that it's a warning by default, and then, when I'm ready to push my code, I could run some --strict mode that would force me to clean up my code.
That eliminates the unused chain problem. Not sure if zig included that part of the feature as well.
Generally I agree though. The main problem with forcing unused variables, imo, is that it forces you to think a certain way. When I'm exploring the solution space on something, those constraints feel inhibiting.
If one suggested this in any other language to suppress "unused variable" warnings it would be considered a lazy way to avoid fixing the issue.
Meanwhile the developer of Zig himself recommended doing this[0] which only shows what a bad idea it is to make this a compiler error imho. It encourages workarounds and enforces something we automated long ago in the form of dead code elimination.
[0] https://github.com/ziglang/zig/issues/335#issuecomment-43526...
In Zig, I find that I put a whole litany of "_ = varname;" at the bottom of my functions (starting with the function arguments) and they stay there permanently. This is NOT an improvement.
However, it's not really enough to stop me from using the language as that's an easy thing to evantually fix.
If some enterprising young developer is reading this and wants to make a name for themselves, you should fork the Zig compiler and change those errors to warnings. It would be an extremely popular project.
EDIT: I'll even give you a catchy project name. Wig: Zig with Warnings
issue: https://github.com/ziglang/zig/issues/335
I can only see downsides and no upside in this design. Why would you slow down the development workflow for something any decent compiler will discard as basic optimization step? It's an error about something that has absolutely no impact on the resulting program and its execution, you can probably find a dozen better reasons for Zig to throw errors where it doesn't.
Fridays are my live streaming day and I've chosen today's topic to be the user experience of unused variable errors. I have an idea to solve this that can satisfy both parties - those who don't want to be bothered by such errors, and those who want the premise upheld that if Zig code compiles, it does not have any unused variables.
In approximately 60 minutes I'll go live on https://www.twitch.tv/andrewrok/
If you're talking about the `zig fmt` idea, I'd like to draw your attention to a possible pitfall -- Silencing the errors with _ increases the risk that unused vars will be committed to the repo. https://news.ycombinator.com/item?id=32753079
I normally add the equivalent of `-Werror` to pre-commit and CI. But if those warnings are silenced directly in the source code, I can no longer rely on the compiler's guidance to clean up the code, and I would have to hope I could remember all the places I need to clean up before committing. In that way, solving this in the formatter could have the opposite effect on code quality than you intended. I _do_ want the compiler to yell at me... just not yet. Only when it comes time to commit.
Overall I've been impressed reading about Zig's design. You clearly have good engineering taste and I respect you challenging the status quo and trying unconventional ideas, even if I may disagree from time to time. I'm itching to start using the language once this is solved!
If the goal of not having warnings is to increase code quality, it's actually doing the opposite.
I don't understand this insistence on working around the problem by layering on tooling, instead of just fixing the problem to begin with.
My guess is that it is about the language tooling, but it would be nice to hear from the authors themselves.
Rust is the highest level represented. I'm guessing the level of control needed to hit the tight constraints of wasm-4 preclude anything that you wouldn't use for a microcontroller. C and c++ would work too, but what fun is that?
https://youtu.be/7ydnjX999kk?t=894
I also think that there is a correlation between the majority of participants being from Europe and Zig. At the moment almost all our meetups are in Europe.
I really enjoy the balance of safety and control in Zig. I can build using Debug mode during development, turning nearly all my bugs into crashes which are easily fixable using in-browser source-level debugging. But in Release-Small mode the result is fast and more importantly really small since there's a 64kb cartridge limit.
Another factor is the Zig Standard Library which designed to be portable and usable on freestanding targets. I can not emphasize enough how pleasant this is. For example I can just use a `std.heap.FixedBufferAllocator` to back a `std.ArrayList` with no problem.
The comptime feature of Zig also comes in handy when you have to minimize code size.
The seamless C interop furthermore improves my productivity since I can just use any C code I like. I've used a C perlin noise library in a previous game for example, saving me a lot of time.
Plus I've used Zig for the previous WASM-4 jam and just liked it so I didn't bother trying any other language.
Asking as Rustecean.
Instead of focusing on tradeoffs they chose to call others irresponsible.
However, what I've seen in the discourse of several programmers that claim to prefer Zig is the assumption that Rust is "not really that big of a deal". There's a constant minimization of the advancements both the ownership system and the safety approach provide, and a lack of recognition for the fact that the language is a "game changer" in the industry.
Overall, this looks a lot like rationalization of an emotional choice, which for me is much more close to religious zealotry.
I think you have inadvertently worded this in a way that silently confirms what the parent poster was saying. But more generally, while I can't speak for the entirety of the Zig community, the people involved with Zig directly tend to be aware of Rust's strengths. The problem is that one of the reasons why Zig exists (and is having some level of success) is because some people just don't want to deal with abstraction-heavy code. Some people value simplicity over a complex language with a memory-safe subset.
And the value of simplicity is not just a matter of aesthetics. Simplicity is a defense against bugs, because memory safety is not the end goal, correctness is.
https://twitter.com/croloris/status/1568342336580755456
To quote Douglas Crockford: "If you say it hardly happens, it means it happens".
I totally get it's nicer than C, I love it too, but it's completely irresponsible to push a language without a memory safety story, in 2022, this hard.
From that relatively obvious conclusion it devolves into tedious nerdsnipes. Yes there are edge cases.
It is very much not the consensus that memory safety is a requirement for any modern language. Asserting that it should be a requirement is an extreme position.
Assuming that my argument has "fallen apart", or that you have "dunked" seems quite absurd given that you've taken an extreme position which many serious practitioners and academics would disagree with.
Rust is still very much an experiment in terms of systems programming. It has a tiny overall "market share" in terms of use in large production projects compared to C/C++ and it remains to be seen whether the particular set of tradeoffs chosen by the language will lead to long term sustainable success.
Zig takes another approach and is also a worthy experiment.
I'm not diminishing the success of Rust. It's been proven it can be used for serious projects.
It's a bit of a reach to argue it's proven to be the best choice for all system programming use-cases going forward.
It's especially frustrating because you've received a ton of charity and time from strangers, we understand 110% what you're thinking (I wish it was true! I've had an inordinate amount of work for 18 months now because it isn't) but you can't seem to wrap your mind around the idea that there isn't some niche where Zig is perfect and unassailable or the only alternative is rust. I don't think you have much experience in multiple languages, it's actually fairly easy to get something as fast in JS _as in C_.
It's possible in some cases that you can implement something in JavaScript which is competitive with a systems programming language, thanks to all the incredible optimization work which has gone into JavaScript engines, but the performance ceiling of a language like JS is much much lower than that of system programming languages. For instance, if you are optimizing for memory cache performance C or Rust or Zig are going to have tools which just don't exist in JS. There's a reason that HPC - one of the computing fields where profitability literally depends on speed - is all implemented in C and C++.
And not that it matters but I've got plenty of experience with languages. I've been doing software engineering professionally for over a decade, and I've shipped professional projects in probably a half dozen languages or more including C, Rust, and Javascript. I've also done my fair share of programming in the systems domain, including computer graphics and games. I've also implemented programming languages of my own.
> you can't seem to wrap your mind around the idea that there isn't some niche where Zig is perfect and unassailable or the only alternative is rust.
I never said Zig fits a perfect niche. I said the theory of the language is valid, and it's a worthwhile contribution to the field. Zig, like all other languages, is an experiment. It's actually quite an interesting one with different goals than a lot of the other popular languages out there, and which is very appealing for the systems programming domain. I'm arguing against the idea that Zig is "irresponsible", which is an extreme position.
I keep bringing up rust because of you guys insistence that Rust is a counter-example to the idea that a new systems programming language not necessarily be memory safe. For instance this comment:
> We can't ignore the fact that Rust has shown that memory safety is not incompatible with low-level semantics.
Seems to imply that Rust's existence unto itself is proof that every new systems programming language must be memory safe.
C is the current standards bearer for systems programming. Everyone is trying to invent a "better C". Go and Nim are trying to do it with garbage collection. Rust is trying to do it with the borrow checker. Zim is trying to do it with ruthless simplicity and explicitness.
All of these are experiments, and all of them are valid. 20 years from now we'll know a lot more about what works and what doesn't from each of these experiments, but it's too early to conclude that now.
No, Zig is simply not memory safe. That's a property of a programming language that has a definition. Zig does not meet that definition.
> I find it funny that fans of a language of a not-so-young-age that is struggling to find relevance and capture even 1% of the market are treating it as such an inevitability that it's irresponsible to talk about anything else.
Leaving aside your weird description of a language powering software that serves billions of users as "struggling to find relevance", most software in 2022 is written in languages that are memory safe. Zig is quite the outlier here. It would in fact be very reasonable to survey the landscape of popular languages today and come to the conclusion that memory safety is an inevitability.
> It's also detached from reality, as much of the software we all depend on is being written, in 2022, in languages without sound memory safety guarantees.
Virtually all of that software is being developed in C or C++. The most compelling reason to use those languages is that they have a huge install base and a huge amount of code already written in them. This says nothing about whether a brand-new language should be memory safe.
> There are various approaches being tried for how we should write low-level programs in the future, but there is no consensus yet on the best one.
No, there actually is PL consensus that all new languages should be memory-safe, maybe aside from very low-level specialized languages, which Zig is not trying to be--Zig is trying to be a general purpose language.
I didn't claim that it is. I said it has a good memory safety story, i.e. mechanisms that soundly guarantee some kinds of memory safety, plus a design that helps write correct programs. Correctness in general, and memory safety in particular, are very central concerns in Zig's design, it's just that its story isn't one of sound guarantees across the board but, rather, some balanced mix of approaches -- some based on soundness, others based on facilitating comprehension and easier testing.
> Most software in 2022 is written in languages that are memory safe. Zig is quite the outlier here.
No, Zig is a low-level language, and the vast majority of low-level programs in 2022 are written in languages whose memory-safety story is worse than Zig's.
> This says nothing about whether a brand-new language should be memory safe.
That's right. We don't yet have an answer to that question, because we don't yet have sufficient experience with low-level languages that do have sound memory safety guarantees. I mean, it sure is better to have more guarantees if they come for free, but there's no such option in front of us just yet.
> No, there actually is PL consensus that all new languages should be memory-safe
No, there really isn't one when it comes to low-level languages (and the interest in Zig is proof that there is no consensus that it shouldn't exist). Rust is a low level language with sound memory safety guarantees, which comes at a price that makes it unappealing for some, and so various other approaches are being tried as well.
You can't insist there's consensus when clearly there are people who disagree with you. That's the definition of a lack of consensus. I also think it is premature, to say the least, to declare an approach that is currently still far from proving a success as the only way.
Zig doesn't have mechanisms that soundly guarantee some kinds of memory safety. It's not spacially memory safe: extern unions, sentinel-terminated pointers, and multi-element pointers break it. At best, we think there's probably some subset of Zig that you could define that is spacially memory safe. (This isn't a particularly interesting property because it's trivially true for any language, by the way: C without pointers and without arrays is a subset of C that's memory safe, for instance, and also uninteresting.)
> No, Zig is a low-level language, and the vast majority of low-level programs in 2022 are written in languages whose memory-safety story is worse than Zig's.
Zig claims to be a general-purpose language, not just a low-level one. From [1]: "Zig is a general-purpose programming language and toolchain for maintaining robust, optimal, and reusable software."
> I mean, it sure is better to have more guarantees if they come for free, but there's no such option in front of us just yet.
It's better to have more guarantees if the benefit of the guarantees outweighs the cost, not if there is no cost. For example, for many apps, the benefit of memory safety outweighs the cost of a garbage collector.
> You can't insist there's consensus when clearly there are people who disagree with you. That's the definition of a lack of consensus.
Consensus doesn't mean that nobody disagrees. It means that the opposite position is a fringe view.
[1]: https://ziglang.org/documentation/master/
It does.
> It's not spacially memory safe: extern unions, sentinel-terminated pointers, and multi-element pointers break it.
We've been through that. Those are syntactically delineated unsafe features for C/hardware interop. Rust has them, too.
> This isn't a particularly interesting property because it's trivially true for any language
That's right, but Zig is much closer to Rust than to C in that regard. It has clearly marked unsafe features for C or hardware interop, which aren't used in other situations and could be mechanically excluded -- just as in Rust.
> Zig claims to be a general-purpose language, not just a low-level one.
Surely you agree it's also a low-level language?
> It's better to have more guarantees if the benefit of the guarantees outweighs the cost, not if there is no cost.
Yep, and we don't know if we're there in low level languages. So far it seems that some people find the cost of Rust acceptable and others do not. In other words, there's no consensus on what the acceptable cost is.
> It means that the opposite position is a fringe view.
So disagreeing that the only right design is that of a language that's struggling to get 1% of the market is a fringe view? That's like a Haskeller declaring that it is a fringe view to disagree that non-strict pure functional programming is the only right way to write programs. I think that Odin and JAI, two other low level languages in development, also don't go down the full memory-safety soundness path. Seems to me to be quite far from a fringe view.
If people aren't buying what Rust is selling -- regardless of how strongly some feel about the justice of its approach -- I think that those of us who care about correctness must explore alternatives, and Zig is certainly a fascinating alternative. It might well be the case that neither Rust nor Zig succeed in the market, but even in that case, both can certainly serve as inspiration for the languages that follow.
And again we're assuming that the ones we went over in the previous thread are all there is. I found some more: @intToPtr, @bitCast, @alignCast. Some of those @ functions are spatially-memory-safe, and some are not: the differences are not clearly called out.
(I'm going to charitably assume that taking a pointer to an element in a dynamically-allocated array, and then shortening that array and dereferencing that pointer, is a temporal memory safety violation rather than a spatial one.)
> That's right, but Zig is much closer to Rust than to C in that regard. It has clearly marked unsafe features for C interop.
How are they clearly marked, when they're neither relegated to a separate section of the documentation nor behind a switch? As far as I can tell, the person who has gone through the most effort to isolate the spatial memory safe subset of Zig is me, in these HN threads.
> So disagreeing that the design of a language that's struggling to get 1% of the market is the only right way is a fringe view now?
Again, "struggling to get 1% of the market" is a weird way to describe a language that's serving billions of users right now.
No one is assuming that. Like Rust, Zig has a set of unsafe operations that are well known to Zig programmers.
> How are they clearly marked, when they're neither relegated to a separate section of the documentation nor behind a switch?
They are syntactically distinct from the safe features, and they might be hidden behind a switch when there's demand for such a feature.
> As far as I can tell, the person who has gone through the most effort to isolate the spatial memory safe subset of Zig is me, in these HN threads.
So not only is disagreeing with you a fringe opinion, you're now the most knowledgeable on Zig's safety, a subject that is of great interest to Zig programmers? Those who spend the two days required to learn Zig know which operations are unsafe.
> Again, "struggling to get 1% of the market" is a weird way to describe a language that's serving billions of users right now.
Haskell and Erlang are also "serving billions of users" in the same way. The fact is that at an age where almost all programming languages (Python might be the sole exception) were in the ballpark of their all-time peak popularity, only a tiny portion of developers choose Rust. Like Zig, Rust is a language whose future success is uncertain.
Look, not everyone would like Zig, not everyone would like Rust, and for all we know it's quite possible that the main difference between the two approaches is that they appeal to different people. But trying to make Rust's design appear inevitable or uniquely legitimate for low-level languages when that language is doing poorly, or claiming to speak on behalf of a consensus where there clearly isn't one and several other languages targeting the same domain prefer a very different approach, make you sound detached from reality.
I find it a questionable choice to design a new complex language when complex languages tend to do poorly in the market, or to attempt a language for low-level programming that tries to appear high level on the page after C++'s lacklustre success with that approach, but I recognise that not everyone has the same taste as me, and I wouldn't call my opinions a consensus.
Which language and which project is this referring to?
This is an extremely strange argument. How much market share do you think C has in 2022?
You seem to massively underappreciate the dominance of the web and the hegemony of languages like JavaScript and PHP. System languages are a very tiny niche and there's much less changes there than in other domains.
Rust has obviously way less than 1% market share but it's still extremely successful in the niche it's targeting. (And btw, we're talking about the only niche that still hasn't embraced memory safety, mainly because there was no acceptable tools for that meeting their requirements)
Extremely successful? It's not even mediocre. A more realistic description of its current position in its niche domain might be "still hanging in there", "not yet completely written off" or "not out of the race but waiting for a miracle."
Rust is barely at 5% of the low-level market. Its performance in its target domain is so abysmal at over seven years old that some who'd want to try it don't because its future looks so uncertain. For comparison, almost every programming language reached or at least neared its all-time peak popularity around age 10. Even if things improve we're looking at a peak of 20% of its target niche before the novelty wears off and other languages join the fray. It needs to double its market share in the next couple of years not to be "extremely successful" but just to stay relevant.
Actually, out of job postings, which, however imperfect, is the best metric we have: https://www.devjobsscanner.com/blog/top-8-most-demanded-lang...
The numbers are in line with older numbers (i.e. showing some growth), obtained by other people: https://www.hiringlab.org/2019/11/19/todays-top-tech-skills/
> Oh yeah, I guess Objective-C peaked in 1993, Python peaked in 2001, and Java, PHP, Ruby and JavaScript peaked in 2005.
Objective-C is irrelevant (as its adoption is tied to that of another product, kind of like VBA), and with the exception of Python, pretty much yes (I said neared or reached, not reached). Other than Python, no language showed surprising growth after a decade, including C (1983) and C++ (1995).
> but it will steadily entrench itself as foundational building block of everything that surrounds you, as it has already started.
The evidence suggests otherwise, but things could change. I'm not saying Rust will never succeed, just that current performance and the historical trend don't bode well. Of course, other languages -- Zig, Odin, JAI, and those that don't exist yet -- will also enter the game, and it's not unreasonable to expect that the low-level programming world will experience a similar fragmentation to that of the applications world, where no new language is particularly dominant.
I think it is quite possible that Rust will achieve similar success in the low-level world as Go reached in the applications world. Anything beyond that is not out of the realm of possibility, but there are no current indicators to support that. Rust's adoption rate, in its target domain, is -- today -- lower than that of languages that have achieved unusual popularity in that domain or in others.
> to bash the language
I don't bash the language at all. I bash unfounded claims about it, such as those made in this discussion: that it's achieved extreme success, that all other designs are "fringe", and that it's well established as the best way to achieve correctness. None of these things are known to be true. As for the language itself, I find it too complex and reliant on implicitness for my taste, but I've said over and over that that design is certain to appeal to others. Moreover, I think Rust's "grand idea" of the borrow checker and type-checked lifetimes is nothing short of genius, although I wish it came in a simpler language.
I also don't understand people who become so attached to languages that they deny reality. Clojure is one of my favourite languages, but it's silly to deny that its adoption is low; obviously, it's not many people's cup of tea. I find TLA+ to be one the most useful tools for me, but clearly many don't. I don't understand why people who like Rust need make believe that it's doing well, inevitable, or the only reasonable choice, when the truth -- as we know it today -- is that it's none of those things, yet that shouldn't stop anyone from enjoying it, just as Clojure or TLA+'s lack of popularity has no impact on my enjoying them. Why can't people say, "I use Rust because I enjoy it, I find it convenient, useful, interesting, and beautiful?" Why the need to also make up stuff about it?
> that they spent such a significant amount of their comment activity on HN
This one gave me pause, but I think you'll find that what mostly triggers my HN comments is not so much Rust but claims related to software correctness. I've spent years on this subject, I care deeply about it, and misleading claims about it abound. It's just that recently they've been...
You're mischaracterizing Mr Walton's argument here: it's not “non-Rust” design which are fringe, it's “non-memory safe”, and he's arguably correct on that front: no mainstream (even in the broadest sense) language that ever came after C++ was memory-unsafe. And C++ has been progressively abandoned from every domain where its performances characteristics weren't enough of an argument. It is the consensus in PL design, whether you like it or not, and Zig is going against that 30+ years old consensus. Rust is simply the first one to seriously challenge C and C++ on their remaining domains, but memory-safe languages are ubiquitous and have been for years.
> that it's achieved extreme success
For the domain Rust is aiming at, no other languages has ever reached this level since C++, that's it. Rust hasn't taken the crown, but it's doing things that have not been done before, and it's a hell of a success for a programming language designer!
> This one gave me pause, but I think you'll find that what mostly triggers my HN comments is not so much Rust but claims related to software correctness. […] (just as before we heard similar claims about Haskell, that triggered me just as much)
I think it's mainly a thinking framework issue. You can view software defects as belonging to one of two classes: (1) design errors, and (2) programming mistakes (typos, copy-paste error, forgetting to call a mandatory function, etc.). TLA+ is a wonderful tool to make sure that your design is correct, but it's helpless against programming mistake. Respectively, the ML family of languages (and Haskell) offer really powerful tools to reduce the number of programming mistakes in shipped code (if it compiles, it has likely no programming errors) but it is completely helpless against broken design. The frequency or gravity of software defects caused by those two kinds of bugs are context dependent but they are both sources of bugs, so in a sense (even discounting memory-safety) Rust is improving software correctness by reducing the number of programming mistakes, even if does nothing (if we set memory issues aside) to reduce design errors.
There is no Rust vs TLA+ like there is Coq vs TLA+, Rust doesn't claim it can prove the high level requirements of your problem, it just claim it can prove memory-safety and thread-safety and give you a nice mistake-prone development environment. If you want design correctness, use Rust to implement the design you've validated in TLA+!
> Actually, out of job postings, which, however imperfect, is the best metric we have: https://www.devjobsscanner.com/blog/top-8-most-demanded-lang...
Ctrl-F for Rust on this page returns no results…
> Objective-C is irrelevant (as its adoption is tied to that of another product, kind of like VBA), and with the exception of Python, pretty much yes (I said neared or reached, not reached). Other than Python, no language showed surprising growth after a decade, including C (1983) and C++ (1995).
That's a surprisingly high number of wrong statements per n-gram…
As an aside, in a non-emotional discussion about a programming language, you should probably refrain yourself from insulting one of its designer. Because, yes, saying to a PL designer that his language is “struggling to find relevance” is an insult, the same way calling someone else's mom “fat and ugly”, regardless of the factual accuracy of the statement.
I don't understand that logic, as we're only talking about low-level languages. Of all the low-level languages developed after C++, including D, Rust, Zig, Odin, and JAI, the majority aren't memory safe.
> It is the consensus in PL design, whether you like it or not
It clearly isn't even the majority opinion in low-level PL design, let alone the consensus.
> but it's doing things that have not been done before, and it's a hell of a success for a programming language designer!
Sure, by that metric it is a great success.
> it just claim it can prove memory-safety and thread-safety
I know, but the reason it does so is as a means to an end. The reason why anyone wants memory safety is that it eliminates certain classes of bugs that can be quite harmful. The reason why we may not want memory safety is that sometimes it can come at the cost of other bugs, overall not helping correctness. Anyway, software correctness is a complex issue, and it is not currently known whether Rust's approach or Zig's -- if either -- is more effective at achieving correctness.
> Ctrl-F for Rust on this page returns no results…
Yeah, it's an image or something, but it's there.
> you should probably refrain yourself from insulting one of its designer.
Sorry about that.
It's funny because you've included a language built around garbage collection (D), and a language that doesn't really exist yet (Jai, which is actually a placeholder name). Btw, this list (which basically contains only names we can see every once in a while on HN) shows you're really not familiar with the PL design space (which is fine actually but you should probably not be arguing about academic domains you're not familiar with).
> I know, but the reason it does so is as a means to an end. The reason why anyone wants memory safety is that it eliminates certain classes of bugs that can be quite harmful. The reason why we may not want memory safety is that sometimes it can come at the cost of other bugs, overall not helping correctness. Anyway, software correctness is a complex issue, and it is not currently known whether Rust's approach or Zig's -- if either -- is more effective at achieving correctness.
The idea that Rust may cause more bugs than it avoids is backed by zero evidence. Is Rust worth it, from a engineering team perspective, given its other constraints (low number of trained practitioners, slow compilation time, or even an hypothetical productivity cost) is a fine question, especially when I see Rust being used for back-end roles where other entrenched languages are doing fine, but claiming that “maybe Rust some unknown type of bugs we cannot be sure” is a fallacy (same fallacy applied to a different context: “climate is a complex issue, maybe there's some non-anthropic cause for global warming”).
Zig doesn't particularly address “correctness”, more than any typical language: it doesn't address “design errors” more than Rust, and is arguably addressing less “programming mistakes”. There is no trade-off in correctness between those two (Rust is trading learning curve against correctness, and it might even trade productivity for correctness, but it's not trading one kind of correctness in favor of another).
One can argue that “programming mistakes” are unimportant overall, because they get ironed out easily, and that it's a matter of team experience and proficiency, and in fact in managed languages it may be true, and that would explain why functional programming never took off, but when in comes to memory management, we've had enough CVEs to show that no, programming mistakes don't get ironed out easily.
If you want to see “Zig safety story” in action, have a look at the only commercial user of the language, and go search for “segfault” in the github issues…
Oh, I'm familiar enough (my job requires me to be), but I wanted to list languages people here have heard about. Also, I'm not arguing about an academic domain. Having spent just the other night at a gathering with PL researchers in the UK, some interested in Zig, I know that even if we restrict the discussion to academia alone there is absolutely no consensus over the matter. It is an empty and false assertion, plain and simple.
Also, let's not forget that Rust leans quite heavily on a garbage collector, too, albeit a rather crude one.
> The idea that Rust may cause more bugs than it avoids is backed by zero evidence.
I never claimed that it does. I said we don't know which approach leads to more correct software, and that anyone who says we do is simply unfamiliar with the field or misleading. I explain more below.
> that “maybe Rust some unknown type of bugs we cannot be sure” is a fallacy
That's not what I meant at all. Just as an example of things that Rust's design could adversely affect to the point of adversely affecting correctness, consider two techniques that have proven extremely valuable in improving software correctness: code reviews and tests. A complex language with a lot of implicitness, long compilation time, and possibly longer code-writing time, can slow down or hinder these two techniques. Those issues are related to why so many in software correctness research today focus on reducing soundness; soundness has a cost of slowing down very effective unsound techniques, and given that full-soundness is something most have given up on, whether the price is worth it is always a hard question with no easy answers.
> Zig doesn't particularly address “correctness”, more than any typical language...
I think it does, and Zig's designer thinks so too (in the sense that he's designing the language and it tools with correctness as a primary goal) -- I don't know if it's more than any "typical" language (working on a "typical" language myself and caring a lot about correctness, too), but certainly not to any lesser extent than Rust. In particular, there's a very strong emphasis on explicitness over explicitness (no hidden control flow, local reasoning) and there's a strong emphasis on fast compilation and good testing support (including a design that makes isolating units and testing them easier) to facilitate faster and more rigorous testing.
Those who arrive at correctness from academic PL are often unfamiliar with such reasoning, which is now increasingly more common in formal methods research where the power of unsoundness is now appreciated.
> There is no trade-off in correctness between those two
I gave an example above that explains why some people think there could well be. No one can claim that either Zig or Rust yield more correct software, because we really don't know.
> One can argue that “programming mistakes” ...
That's not the argument at all. Memory errors are, indeed, both tricky and dangerous, and it is important to avoid them, but not at the expense of missing other, equally tricky and equally dangerous bugs.
> If you want to see “Zig safety story” in action, have a look at the only commercial user of the language, and go search for “segfault” in the github issues…
If you choose to eliminate bugs of class Y, you'll have none of them, and if you don't -- you will. This has no bearing at all on the question of overall correctness, which is what memory safety ultimately aims to serve. That is why there's no consensus over it.
How do you want anyone to take any your words seriously when saying things like this… Rust has reference-counting primitives in its standard libraries, but saying in “leans heavily” on it is a “very original” take (in fact, Rust leans more on “epoch-based memory reclamation” than it does on reference counting, but even if you had that in mind, it's still quite far from “leaning heavily”).
> That's not what I meant at all. Just as an example of things that Rust's design could adversely affect to the point of adversely affecting correctness, consider two techniques that have proven extremely valuable in improving software correctness: code reviews and tests
It “could”, in the same sense that “vaccine could cause autism” or “the US could never have put men on the moon and staged the moon landing in Hollywood”
> I think it does, and Zig's designer thinks so too
Interestingly enough, you spend much, much, more time talking about it than himself…
> I gave an example above that explains why some people think there could well be. No one can claim that either Zig or Rust yield more correct software, because we really don't know.
So the gist of your argument is that we don't know because for “some reason” Rust could make testing (this is ironic when you know how much of an improvement Rust testing story is compared to most languages) and code review less practical, to a point where it would more than compensate for a class of bug that have empirically proven really really hard to avoid with conventional methods like testing, code review or runtime tooling. Wonderful.
> If you choose to eliminate bugs of class Y, you'll have none of them, and if you don't -- you will. This has no bearing at all on the question of overall correctness, which is what memory safety ultimately aims to serve. That is why there's no consensus over it.
I was referring to this quote of yours above: “Zig has a pretty good memory safety story”. Which is empirically not so good.
No. The claim "design with tradeoffs X leads to more correct programs than design with tradeoffs Y" is the one that requires evidence. The null hypothesis is that it doesn't.
> Interestingly enough, you spend much, much, more time talking about it than himself…
As I said, software correctness is my thing. When I saw Zig's brilliant, revolutionary design, I thought, wow, that's a powerful and interesting approach to software correctness. I thought pretty much the same when I saw Rust's design. My aesthetic preferences lean toward simpler languages, just as others' lean toward a more refined type system, but both of these languages make correctness a major focus of their design, they go after it in very different but equally interesting and novel ways, and it will be fascinating to learn which, if any, can achieve better correctness. However, anyone who says we already know is not telling the truth, and probably has a shaky understanding of the subject.
> So the gist of your argument is that we don't know
No. The reason we don't know is that we don't have evidence one way or another. I gave you one example as an intuition for why your hypothesis might be false.
> I was referring to this quote of yours above: “Zig has a pretty good memory safety story”. Which is empirically not so good.
You're saying it's not good because it doesn't try to completely eliminate such errors? That's called begging the question.
Now, you can say many things about me, but when talking about technical subjects I try pick my words precisely. I'll gladly keep discussing the substance of the matter -- I've devoted a lot to it and I care deeply about it (look at my blog) -- but if you're trying to poke at my words you will most likely waste both our time.
Yes, Zig has a pretty good memory safety story. It's a combination of sound spatial safety, precise pointer tracking, as well as some tools, to make catching temporal safety issues easier. It's not only a pretty good story, it's also interesting and rather novel one -- like Rust's -- only its particulars are very different. Zig's memory safety story is not perfect because the cost of perfection, Zig's philosophy believes, is too high, to the point of working against the goal of correctness.
There are two relevant open questions: If correctness is all you care about, what price should you pay for memory safety? And what if you also care about other things? I don't know the answer to these questions -- nobody does -- but we need both Zig and Rust to help us learn.
What's the argument here? Is it OK then to question the existence of the Apollo program because “the yanks never went to the moon” is the null hypothesis?
We've plenty of evidence that Rust offers better guarantees than C (even though with your reasoning there could be a hidden second-order effect that makes Rust actually worse than C, we cannot be sure after all, the Rust compiler is slower than C's… /s).
Now since Zig doesn't address the most prominent source of critical defects in C, the null hypothesis is that it won't be an improvement compared to C. (I actually don't think that hypothesis is true either, C is very dated and there are tons of room for small UX improvements, but getting an improvement as big as what Rust offers is a big step to climb with small improvements).
> As I said, software correctness is my thing. When I saw Zig's brilliant, revolutionary design, I thought
Yet you're like two thousand words in and you've not even begun to hint at what part of Zig designs makes it especially good for correctness compared to C.
> However, anyone who says we already know is not telling the truth, and probably has a shaky understanding of the subject.
Like with climate modeling or immunology, we're far from knowing as much as we'd like, but that doesn't mean we know nothing: for instance we know that 1) distributed systems are practically impossible to get right without tools (and TLA+ is a blessing), and we know that 2) manual memory management isn't tractable by a human without assistance. For these two problems, we have decades of empirical evidence that shows that the human brain just isn't able to do it reliably. We also know that 3) so far sanitizer and other runtime tools haven't been enough to get it right in practice.
Zig basically says that even if 2) is true, 3) will not hold for long because it will have “better tools”® than what exists for C. Hard to tell how far these tools will eventually go, but for the moment it has yet to prove anything on that front.
> You're saying it's not good because it doesn't try to completely eliminate such errors?
Yes I am, because ”eliminating completely* such errors” is the standard for every language designed after 1985 that has reached even limited use. (And we're not talking about some low-level stuff that only C or C++ could do, but about a product that competes with another written mostly in JavaScript).
By letting this kind of errors happen, it's a step back of more than 35 years ! And by “happen” or “completely eliminate” I mean “happen enough that it surfaces significantly to the user” (and resp.), I'm not arguing that it should be proven that it cannot happen (in fact, even Rust does make such a claim),but at least it should be exceptional in practice, not one of your most common issue keyword on github…
If Zig empirically had like 0.1% memory issues, then arguing that improving on any other fronts is more important would be fine (like Go not being memory safe in the presence of data race, we can agree that this isn't a significant factor in software reliability using that language and move on), but it's not what's happening. What happens is that the only commercial use of Zig so far is facing a double-digit amount of memory-related crash reported by its users. We're not talking about CVEs found by an adversary here, just Joe the user who has his software randomly crashing at startup. Correctness you said?
> Zig's memory safety story is not perfect because the cost of perfection, Zig's philosophy believes, is too high, to the point of working against the goal of correctness.
As a side note, this is a strawman, Rust doesn't aim at ”perfect...
The argument is that you don't have a hypothesis and then put the burden of proofs on others to prove that it's untrue. The justification for why science must work like this is that most associations must not be true correlations.
> We've plenty of evidence that Rust offers better guarantees than C
True, but our starting point was that neither C (let's call it 0 sound safety) nor Idris (let's call it 100 sound safety) are the best approach, i.e. we know that the most effective way is something in the middle, i.e. we already know that more soundness is sometimes better and sometimes worse.
> Now since Zig doesn't address the most prominent source of critical defects in C
No, that's your claim. Zig is as different from C as Rust is. Zig does make sound guarantees of spatial memory safety (which neither C nor C++ do), and unlike C or C++, pointers cannot be created from "thin air" with pointer arithmetic or with hidden casts such as unions, i.e. Zig has precise knowledge of what a pointer is. This makes tooling for detecting temporal memory unsafely much more powerful and precise in Zig than in either C or C++.
> Yet you're like two thousand words in and you've not even begun to hint at what part of Zig designs makes it especially good for correctness compared to C.
I hope I now did. Plus, its expressiveness is that of C++ (or Rust), not C, while being very simple (two languages are as expressive if there aren't programs in one that require more lines in the other than by a constant factor; C++ has program facilities that require exponentially more lines in C).
> but that doesn't mean we know nothing
Well, whether Rust makes it easier to write correct programs is something we don't know.
> so far sanitizer and other runtime tools haven't been enough to get it right in practice.
You're talking about sanitisers for C/C++. Zig is very different. Again -- full spatial safety, and precise pointers.
> but for the moment it has yet to prove anything on that front.
Sure, and Rust too.
> Yes I am, because ”eliminating completely* such errors” is the standard for every language designed after 1985 that has reached even limited use
That is a very bad argument. You could just as well say that the standard is not to have safety based on substructural types because that's probably too costly. I think it's funny to pretend that Rust's way to memory safety isn't very different from, say, Java's, and doesn't come at a significant cost. It obviously is, and does, and the question we don't know the answer to is: is that a better tradeoff than Zig's?
Also, the number of low-level languages designed after 1985 that have reached even limited use is too small to make any generalisation, let alone a standard, and it opens you to a far worse argument: despite the popularity of memory safety in the application space, no low-level language that has achieved significant use has been memory-safe. Don't try to build statistics on a small sample. Not only is the argument bad, but it can just as easily be turned against you.
> And by “happen” or “completely eliminate” I mean “happen enough that it surfaces significantly to the user”
This is the argument Rust is making that those who aren't so involved in software correctness find compelling, but it is nonetheless false. It goes like this: we have lots of kinds of bugs, if we can eliminate some with soundness, then that must be better! Most formal methods researchers found that argument so convincing in the 70s that they almost accepted it axiomatically. Except it turned out not to be true. Less sound approaches proved more effective overall despite not "eliminating" classes of bugs. But we don't know where the sweet spot is yet.
> Correctness you said?
I don't understand your complaint. First, I hope you're not claiming t...
In the nineties I worked on a big defence project that was written half in C++ and half in Ada. Ada was the Rust of the day, plus it had the weight of the US DoD behind it, which was no small thing. But at the time it was a much more complex language than C++, so we had to have "language lawyers", and, just as bad, its build time was much worse, that in the end we just couldn't test it as well as our more ostensibly sloppy C++ code, the result being that we gradually shifted away from Ada.
I'm not saying that the vision of the seventies of "more language; more formal soundness" is always wrong, but it's certainly isn't always right. The biggest improvement in software correctness that saved us from the total software collapse prophesied by the "formalists" of the seventies, like Dijkstra and Tony Hoare, was the advent of automated unit tests. It's been so effective that it surprised those formalists (like Hoare) as well as confounded those PL people who believed that more and better types are always better (so much so that correctness differences between languages have been very hard to find in recent years except in special circumstances, such as JS vs TypeScript). We learnt that "more language" isn't always the best answer, although sometimes it could be. We just don't know where the "best" tradeoffs are, or even if they're universal. In the past couple of decades we've also learnt more about software correctness from complexity theory, "hard" results that just weren't known to Dijkstra, and that put limits on the effectiveness of soundness. We also learnt some empirical "soft" results -- such as this one [1] -- that showed that sometimes soundness just pushes the bugs elsewhere (i.e. people write code that satisfies the language, yet manage to do this without addressing the fundamental issue, so the catastrophic bug just manifests differently).
None of that is surprising in retrospect. Bugs occur due to a lack of exhaustiveness in human reasoning (or even machine reasoning, as we now have the complexity theory to understand that), so if you're writing an algorithm whose object-lifetimes considerations are too onerous for humans, it is likely that there are other aspects of it that are equally onerous. So what is the right price to pay to prevent that algorithm failing due to use-after-free specifically?
So when a language offers to eliminate certain classes of bugs, even important classes, but possibly at the cost to both static and dynamic functional reasoning -- through reviews and tests -- it is in no position to say that it's obviously the right approach, and that's why there's no consensus that it is. Zig opts to eliminate fewer classes of bugs, up to the point that doing so is free. That's certainly an equally valid hypothesis, a-priori at least, and it will be interesting to see how things develop.
[1]: https://www.usenix.org/system/files/conference/osdi14/osdi14...
> so if you're writing an algorithm whose object-lifetimes considerations are too onerous for humans, it is likely that there are other aspects of it that are equally onerous.
The thing is that you have lifetimes considerations in Zig too. You need to know when to free memory, so you explicitly need to reason about it, just like in Rust in the worse case (when RAII alone isn't enough) but you don't have tools to helps you know when to free and when not to (and only tools to diagnose when you've missed it) so Zig actually adds cognitive burden, not removes it. In the end you'll be reclaiming the memory at the same place (which is where the object is not used anymore and safe to free).
And you keep pointing to reviews and tests, as if rust made it harder, when in fact it makes it marginally easier than for most languages, with its built-in test framework well integrated in the entire stack, and the ability to see where mutations happen. Of course it's not revolutionary nor even unique, but on those two specific subjects in is in fact in among the best languages out there.
So you keep talking about Rust's cost, but the thing is that you can't really pinpoint what types of cost this is about (except with the hand-wavy concept of “language complexity”), and the examples you give are off.
Obviously! But my point was that that reasoning isn't additive. If an algorithm is complex enough that you have to carefully reason about its object lifetime, then you might have to carefully reason about it even if you're guaranteed to get the lifetime right. Or, rather, sometimes you might, sometimes maybe not, and other times the extra burden of the language is just a chore.
> so Zig actually adds cognitive burden, not removes it
In that regard -- absolutely, in others, it reduces it. Rust's soundness obviously does some good things -- at a price. The question isn't whether those things work, but if they're worth the price. I'm not saying Rust doesn't give me value for my effort; we just don't know if it's more or less than what Zig gives us.
> but on those two specific subjects in is in fact in among the best languages out there.
Except Zig takes that to another level. Rust has some brilliant innovations -- like the borrow checker -- but Zig's entire design is a quite revolutionary, and in multiple ways. That's why I find comparisons between it and C to be so misleading. We've never seen anything like it before.
> So you keep talking about Rust's cost, but the thing is that you can't really pinpoint what types of cost this is about
I don't need to justify why Rust isn't the best approach out there; the onus is on Rust. If we knew which of Rust's approach or Zig's or maybe others altogether worked best, then we wouldn't be trying all of them. We are because we don't know.
But assumptions that soundness was the best approach proved wrong in a surprising ways in the past, and a combination of soundness and unsoundness (those "hand wavy" techniques of testing and reviews) are what proved effective. Bot Zig and Rust believe in such a combination, only in different measures. Perhaps in time we'll find out which works better, but you can't say, "fine, sometimes soundness is better and sometimes it's worse, but my mix is better than yours because it has more soundness."
Now, I'm not trying to convince you, or anyone, that Zig's approach to correctness works better than Rust's; we simply don't know. What I'm trying to get across is why both approaches are novel and interesting enough that we need to try both.
BTW, there's another axis we need to consider. The goal of software correctness from the industry's perspective is not how to write more correct software, but how to write more correct software with the programmers we have. That's why, even though it's possible that the few who can make effective use of Idris might (although maybe not) be able to produce more correct programs than others, few consider Idris as the probably solution to the problem because so few programmers would be able to put it to good use. A language that improves correctness by X around for Y programmers contributes less overall to correctness than a language that improves it by X/2 for 5Y programmers.
That's a very very strong claim without any supporting argument. And I'd be very surprised if it was true. (the success of the Stylo project on Firefox is a significant counter-example for instance).
> -- at a price.
once again, the abstract “price” is invoked, without any characterization… thousands of words later, we still don't know what price you're talking about…
> Except Zig takes that to another level. Rust has some brilliant innovations -- like the borrow checker -- but Zig's entire design is a quite revolutionary, and in multiple ways.
pron waves hands vigorously
You've shown a real difficulty so far to substantiate your argument with anything concrete (on the “price” of Rust, as well as on the “revolutionary” aspects of zig), though you've spent litterally thousands of words on the topic (and not just this discussion, but many before). As the French quote goes ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire viennent aisément, it makes me think you've mostly a gut feeling (Rust bad, Zig good) about this things and not a rational argument.
> I don't need to justify why Rust isn't the best approach out there; the onus is on Rust.
Nope, Rust is the state of the art, and Rust has demonstrated significant benefits over the previous state of the art. Now if Zig comes and wants to challenge it[1], fine but the burden of the proof is on Zig. Want to prove that essential oils are better than antibiotics? Go ahead, but the onus is on you.
> BTW, there's another axis we need to consider. The goal of software correctness from the industry's perspective is not how to write more correct software, but how to write more correct software with the programmers we have.
> […]
> A language that improves correctness by X around for Y programmers contributes less overall to correctness than a language that improves it by X/2 for 5Y programmers.
Yup, and that's why garbage collected languages are the clear winners of the past three decades.
But Rust is especially well-placed in that regard, because most of its users (even the early adopters) are coming from a managed-language background. And anecdotally, making low level code accessible to more developers coming from a more general-computing background is the main reason why Linus Torvalds is interested to get Rust to the kernel.
[1]: in fact this has never been an explicit goal of Zig's creator, who just want to make his programming language without bothering anyone else. He has nothing to prove, and he's never shown any willingness to take part of the kind of silly arguments, this is only the reactionary “Rust bad, need a champion to rant against Rust in online forums” crowd, who does that.
I'm afraid you completely misunderstand my position. I'm merely pointing out that because we know that more soundness is not always better, the claim that Rust is more effective than Zig is not obviously true. I'm not saying it necessarily isn't. We simply don't know yet.
> the success of the Stylo project on Firefox is a significant counter-example for instance
A counter-example for what? No one is saying that Rust doesn't work well or that it doesn't offer more correctness than C++.
> You've shown a real difficulty so far to substantiate your argument with anything concrete
But I don't have any hypothesis to substantiate. I'm pointing out what we don't know.
I did give concrete examples for cases where unsoundness worked better than soundness, but because we already know that the most effective approach is not on either end, we cannot extrapolate from any specific comparison to another.
If someone wants to say language X works better for correctness than Y, they must compare X and Y, not X and Z. But I'm not making any such claim about Rust and Zig.
> Now if Zig comes and wants to challenge it[1], fine but the burden of the proof is on Zig.
No one is claiming that Zig works better than Rust, no one wants to "challenge" Rust with Zig, and no one is challenging the claim that Rust works better than C++. I want both languages to challenge the status quo.
> But Rust is especially well-placed in that regard
Of course. Rust and Zig are both well-placed in that regard, and people who care about correctness want both:
First, we don't know which, if any, works better than the other.
Second, even if one of them does work better than the other, I think it's pretty uncontroversial that they both provide better correctness than C++ (they both provide stronger guarantees, and neither is significantly more complex than C++). But because it seems that there are people who don't like Rust, and there are people who don't like Zig, software will be better served by having both.
Those who say they want Zig to not exist (like pcwalton) are not serving software correctness. I want Rust; I want Zig. We don't know what works best, neither of them is for everyone, so we need both.
> in fact this has never been an explicit goal of Zig's creator, who just want to make his programming language without bothering anyone else
Indeed. More correctness than C and C++ is, of course, one of Zig's goals; more correctness than Rust isn't. But more correctness than Zig isn't a goal of Rust, either. We want both to exist, if only because different people would prefer different languages, and both are probably improvements over the status quo. It's pcwalton who said he doesn't think Zig should exist. So let's not bother anyone else by making unsubstantiated claims about which is better, and certainly not by saying that the other shouldn't exist. Okay?
> I'm afraid you completely misunderstand my position. I'm merely pointing out that because we know that more soundness is not always better, the claim that Rust is more effective than Zig is not obviously true. I'm not saying it necessarily isn't. We simply don't know yet.
This isn't in any way related to the claim that I qualified as “very strong”: you said “But my point was that that reasoning isn't additive”, which is a very strong claim and likely to be false. The Firefox team successfully shipping their multi-threaded CSS engine in Rust while they had failed to do so in two or three previous in C++ hints that implementing complex algorithms and at the same time having to be sure you don't mix things up with lifetime is harder than just implementing the same complex algorithm without having to think about mixing things up with lifetimes. The great shift towards Java in the 90s is also an indication of it. Taking the responsibility to manage memory manually is hard, very hard and adds a significant burden on the programmer. And this isn't “unknown”.
> and certainly not by saying that the other shouldn't exist. Okay?
Where in my comments can you find a single occurrence of this claim?
I'm just arguing that at this point your reasoning of saying “we don't know which is better” is as fact-based as people arguing that “we don't know if vitamin D or Hydroxychloroquine are better than vaccines”. Zig doesn't have to be on par with Rust to have its right to exists, there's no point overselling with on the “correctness” argument that has never been its main stated motivation. And you, the “Java guy who doesn't like Rust” are practically the only one having this argument on HN, you should try leaving Rust and Zig alone for once.
Anyway, you've long stopped giving arguments and have been parroting the same “we don't know” over and over and over without any attempt to add anything new to the discussion, so I'm not interested in pursuing. Too bad, I won't have a single example of how Rust incurs a cost in correctness, nor how Zig's design is so brilliant it will make thinking about memory more practical than C and avoid memory management to get in the way of correctness, so much virtual ink spent in vain.
You've misunderstood. I am not trying to make a claim about how reasoning works, but to give possible explanations for why assumptions that more soundness is always better often turn out wrong, i.e. how it could work. The question of why it is that we get such "surprising" outcomes in software correctness is interesting, but we until we get an answer to it, we just know that we get surprising answers.
> I'm just arguing that at this point your reasoning of saying “we don't know which is better” is as fact-based
This doesn't make sense at all. Not knowing is the default. Until there's conclusive evidence, the fact is that we don't know.
> Too bad, I won't have a single example of how Rust incurs a cost in correctness
I don't know that it does. I gave you several examples of how it might: reading it is hard as it has implicitness and compiling it takes long making testing more burdensome. Maybe there are other reasons, maybe there are none.
Now, this is handwaving, but it's more than we need. It's okay to believe that Rust yields more correctness than Zig, the same amount, or less, but until we have empirical findings one way or the other, we don't know, even without any handwaving.
> nor how Zig's design is so brilliant it will make thinking about memory more practical than C and avoid memory management to get in the way of correctness
I explained that, too. Not only does Zig provide sound spatial memory safety -- which neither C nor C++ do -- but it also has precise pointers, i.e. you can soundly track where your pointers are, which is not the case in C/C++, where you can magically create bad pointers from good ones with pointer/array index arithmetic, or magically create pointers from non-pointers with silent casting (like unions). Zig, like Rust and GC languages has precisely tracked pointers. Good pointers can turn bad through user-after-free in Zig, but they can't be "born" bad as in C and C++.
> Where in my comments can you find a single occurrence of this claim?
Not in yours. In pcwalton. You've just tried inverting the rules of science by saying that if you assert something is true and someone else points out that it's an unsubstantiated hypothesis, the burden of proof is on them, thereby making your hypotheses true by default.
Again, I think there can be a wide consensus that both Zig and Rust provide more correctness than C or C++ because they both make stronger sound guarantees and neither is worse at reasoning or testing than C++, but the question of whether any of them is more effective at correctness than the other is unknown, and unknowable until we empirically compare the two. That something is unknown is not a claim that requires proof; until we have proof for something -- we don't know.
Here's what happened with Haskell: Some Haskellers kept insisting that Haskell yields more correctness than some other languages, and that that should be accepted as the null hypothesis until proven otherwise. Then there were a number of empirical tests that believed they'd be able to show it, and they couldn't find any large effect. So even after the empirical examination some Haskellers insisted their hypothesis should be taken as true by default, because the empirical tests weren't good enough. The result is that people who care to claim about correctness get sucked into these beliefs and not even empirical findings (or lack thereof) can shake them. That's not how we move correctness forward. Of course, Rust is not quite in the same position as Haskell because it hasn't been around the long, but it's important not to get too attached to religious beliefs that "this is the on...
[…]
> You've just tried inverting the rules of science by saying that if you assert something is true and someone else points out that it's an unsubstantiated hypothesis, the burden of proof is on them, thereby making your hypotheses true by default.
You should definitely take epistemology classes on coursera or elsewhere, because by our definition of “knowing”, we never get to know anything.
And unfortunately this “but we cannot know it's too complex” is way too common nowadays, from climate change to pandemic management “we don't know” is a convenient fallacy. There are key things that we actually do know :
- that Rust is memory safe while Zig isn't (not even from a spacial perspective because there are escape hatches).
- that memory safety is a deep issue and tracking object lifetime by hand isn't something humans are good at, at all. (and use of Zig in the wild shows that the issue is unsurprisingly very common in Zig, as it is in C).
So, yes we cannot be sure that there aren't second orders or third orders effects that makes Rust less than optimal and compensate for this massive difference, but there exist no convincing list of such hypothetical effects that could have a significant impact in Rust's ability to build correct software (to take your examples about legibility and testing, Rust has a strong emphasis on explicitness and incremental builds are more than fast enough for efficient testing, so there's little margin for gains on these fronts).
So have clear evidences of a strong first order effect in favor of Rust, and no compelling evidences for adverse higher orders effects, that's what our current knowledge is.
That's a big difference with your Haskell example, because Haskell cannot really pinpoint a significant edge over other languages, it's more a collection of convenient little things, so the improvement is much more vulnerable to higher order effects. The same could be said if we had to compare Rust and Java for instance: I much prefer use Rust than Java because there are many things that I like but at the same time there are little things that are decisively in favor of Rust (Send and Sync trait for compile-time thread safety is nice, but really workload dependent) so I'd be very wary of saying that Rust leads to more correct code than Java.
But Zig carries a significant burden in that regard (and I believe it should really think about introducing a borrow-checker-like in its design before it's too late and compatibility with existing code makes it impossible, while eschewing the whole ML-style functional stuff that Rust has, because that part is definitely in the “nice to have but not really significant” category).
I was talking about the common scientific method. You can define "know" as "the vast majority of the target community is sufficiently convinced that something is true."
> and use of Zig in the wild shows that the issue is unsurprisingly very common in Zig, as it is in C
You've seen absolutely no such thing.
> So, yes we cannot be sure that there aren't second orders or third orders effects that makes Rust less than optimal and compensate for this massive difference, but there exist no convincing list of such hypothetical effects that could have a significant impact in Rust's ability to build correct software
I am not doubting Rust's ability to build correct software, just the claim that it's obviously the best approach.
> Rust has a strong emphasis on explicitness
I think you don't understand what "explicitness" means in this context, as Rust relies on more implicitness than most popular languages.
> So have clear evidences of a strong first order effect in favor of Rust, and no compelling evidences for adverse higher orders effects, that's what our current knowledge is.
Taken as is, you're once again claiming that your belief requires no evidence. Taken more charitably, what you're saying is that you believe it because it is very obvious to you. In that case, either it will be easily verified by the evidence and rather quickly, or it will be shown wrong just like previous "obvious" beliefs regarding software correctness.
What you can't do is is demand evidence from others because what's obvious to them isn't obvious to you, and at the same time claim that what's obvious to you and isn't obvious to others should be assumed true.
> because Haskell cannot really pinpoint a significant edge over other languages
I don't know if you're aware how this kind of argumentation sounds to others, but are you really comfortable making such arguments to support what is a scientific claim? Not only did Haskell supporters say the exact same thing (their edge over, say, Clojure was, of course the type system) but even after time and again we see how complex this subject is, how elaborate the interactions, you make an argument that is not much stronger than, "well, I have more money in my wallet than you, and since I can't immediately see any indication that you have more in your bank we can safely assume I'm richer than you."
> But Zig carries a significant burden in that regard
And Rust carries a significant burden, too: it hinders, in comparison, the two most effective assurance methods we have, tests and code reviews. Just as importantly, too many people find complex languages unappealing, and so the impact a language that not many people would use cannot be large.
Now, I am not trying to convince you that you're wrong, just that different things are obvious to different people, and unless something is obvious to pretty much everyone -- which clearly isn't the case here -- you cannot expect others to just accept your belief, however strongly you believe it, while demanding evidence from them for not accepting it.
The fact is that however obvious it may seem to you, other do not not seem to think that it is obvious that Rust leads to more correct software than, say, Zig. If you're trying to convince others of that, then you have to support it by their standard, not yours (of "faith alone suffices"). I would suggest not repeating arguments that are not only logically weak but have failed just recently, and prefer empirical evidence.
But hey, do what you want, and if you believe that everyone should be convinced or that perhaps everyone is already convinced -- that's fine, too. Just don't be surprised when others find such assertions of faith somewhat cultish and not a good look for programmers.
A...
> You've seen absolutely no such thing.
Just go ahead, grab a few popular projects in Zig (for instance Bun or the zig compiler) and their issue tracker and see how fine the situation is.
And as an epistemological conclusion to this discussion, I should note that while you use “beliefs” pejoratively, but “knowledge” is in fact nothing more than rationally founded “beliefs” that's open to perpetual questioning ;).
Here you just refuse to accept to even think about the rational arguments because they go against your beliefs, hence the reluctance to address the arguments when I've exposed them, falling back to parroting your common sense over and over.
To this day I think the top 3 popular Zig projects are Bun, as you mentioned, then River [1] and TigerBeetle [2].
[1] https://github.com/riverwm/river [2] https://github.com/tigerbeetledb/tigerbeetle
Up to you to decide how fine is the situation in those projects.
And about tigerbeetle, this gives you an idea of how compelling the zig memory safety story is today:
> All memory must be statically allocated at startup. No memory may be dynamically allocated (or freed and reallocated) after initialization.
And then both river and bun have their shares of segfaults, with river looking substantially better than bun, but it suspect it also has much less usage in the wild.
Overall, it looks pretty much like C as I said.
I don't understand. Zig's approach to correctness means giving up on some sound memory safety guarantees in exchange for benefits elsewhere, i.e. it prefers some memory bugs in exchange for fewer others. What conclusion is it, again, that you're trying to draw from the existence of such bugs, and how do you conclude that they occur with the same frequency as in C? Your claim is statistical and I don't see what statistical method you used on the bugs you saw to support it.
> Here you just refuse to accept to even think about the rational arguments because they go against your beliefs
My only relevant belief here is that we do not have evidence supporting the claim that Rust yields more correct software than Zig, and the only rational argument that could go against that belief is the presentation of such evidence. I have no belief regarding which of Rust or Zig yields more correct programs (if either). The reason I have no such beliefs is that I know how complex and unintuitive software correctness is, and both languages have chosen interesting and novel approaches that are not directly comparable based on prior evidence, and so they themselves will have to produce that evidence over time.
Because you asked me to address your arguments (which aren't such a presentation of empirical evidence), the reason why they're unconvincing is as follows. When comparing both Zig and Rust to C++, it is reasonable to accept the claim that they both lead to more correct programs. Why? Because the claim is that they both dominate C++, i.e. they catch all the bugs that you'd catch in C++ plus more. They both make more sound guarantees, and their readability is no worse.
But that is not the same argument used to compare Rust and Zig, because they're incomparable: Rust makes more sound guarantees but it's more complex and requires more non-local reasoning to understand (and might appeal to fewer people), while Zig makes fewer sound guarantees but in exchange it strives to be easier to understand (and to appeal to more people). I.e., the argument for comparison here is not one of dominance but one of a more profitable tradeoff. Your claim that we should value the "hard", formal soundness aspects more than the "softer", informal, aspects is unconvincing because the history of software correctness shows it's a mistake to do so -- "soft" correctness techniques have proven at least as powerful as hard, formal ones, if not more. So, when the tradeoff involves both the formal and informal components of software correctness -- an interaction known to be complex and surprising -- it cannot be settled by simple argumentation, but only by empirical evidence.
That is my one and only argument: because the two languages are not directly comparable as they consciously make different tradeoffs in their chosen paths for correctness, comparing their outcomes requires an empirical test.
Since I've written about software correctness quite a bit over quite a few years now, I think the claim that I am not open to reason in that area is easily disproven by the available material. On the other hand, when someone tries to convince other professionals and fails to do so, saying "you're not convinced just because you're not open", does not lend more credence to the argument. I guess we could call that, "proof by plea", which is not, as far as I know, established as a legitimate form of knowledge gathering in science. But, like I said before, if you think the problem is me and not the strength of your argument, you can put that to the test: publish a scientific paper arguing that Rust leads to more correct programs than Zig (not C or C++), and see how many are convinced by it. If I'm the only holdout, then I'd know the problem is me; i...
You're talking about rigor but you keep making these laughably strong claims. This one is an extraordinary one, and it's most likely also false just because I'm pretty convinced that copy/move constructors can make some (rare) patterns much simpler and as such avoid bugs in practice. It's not clear if copy/move constructors are a net win, and the overall effect is almost certainly minimal anyway, but that's enough to refute the domination claim.
> I don't understand.
That's the key. And you don't want to understand, I'm afraid.
Everything else is just a response to you asking for more context and examples, as well as explanations for why your arguments are so unconvincing, which you then misunderstand as further claims that they are not (e.g. I do not claim that either Zig or Rust yields more correct programs than C/C++). In fact, I do not claim that any language yields more correct programs than any others (not that I don't think that could be true, I'm just hesitant to make such claims). All I did was explain why such an argument would be more convincing than the argument you're making for Rust vs. Zig.
Seems like we're stuck in a circle where you can't understand what I'm saying and I can't understand what you're saying.
In any event, we've gone full meta. Like I said, if you think I am the problem, that can be easily tested. Put your argument in a paper so that it can be properly critiqued. This way you'd at least know if it's me who doesn't want to understand or that your arguments are just not very convincing. If most software correctness people find it convincing -- yay for you; if not, you'll learn how to make your argument more convincing, so also yay for you.
> Zig does make sound guarantees of spatial memory safety
Mr Walton gave an insightful overview of the many caveats that comes with this statements.
> two languages are as expressive if there aren't programs in one that require more lines in the other than by a constant factor
This is a very concise way of describing explicitness, I like it.
> Don't try to build statistics on a small sample. Not only is the argument bad, but it can just as easily be turned against you. […] Second, you're trying to draw a trend out of tiny samples again; this never ends well.
The famous “statistics” tropes… you know, getting a massive amount of data point and making regressions on top is not the only way to produce knowledge. Once again, epistemology classes for all are sorely needed… Fortunately, the parachutes inventors didn't wait for the numbers to get big enough before handing them to paratroopers ;).
> Also, the number of low-level languages designed after 1985
Yes, but I already answered to this argument: this has nothing to do with low-level here, in that particular case Zig is trying to replace JavaScript, which means it's fair to compare it to JavaScript and other languages.
> I don't understand your complaint. First, I hope you're not claiming that programs written in Rust don't have very serious bugs, just as bad as segfaults.
No, this paragraph is part of the sub-discussion about the statement “Zig has a pretty good memory safety story”, it doesn't involve Rust in any ways.
> You're a step away from saying, 100% of commercial Zig programs crash, <100% commercial C programs crash, therefore it's better not to have spatial memory safety. It's like talking about a person who dies from some illness
I have another analogy for you: it's like talking about someone who's just eaten an unknown mushroom and is now dying. I can't be sure that it's the mushroom that's killing him (and the standard scientific procedure to be sure about that doesn't involve giving the said mushroom to 100 person just to get a big enough sample set), but we been told not to eat random mushrooms and “it's not the mushroom fault” is not the most reasonable answer at that point, even though the sample is “just 1”. But hey, I can wait until more people it that mushrooms so I can have more data point, I'll keep counting.
> Moreover, I think Rust made the same big mistake C++ did: trying to get a low-level language to look like a high-level one on the page (so-called "zero-cost abstractions"). I think that design philosophy has little pros and too many cons.
This is the main issue in fact. You don't like the language (which is fine) because it takes too much inspiration from C++, but then you're trying to give rational argument of why “it's not that good”. And that's why your argument aren't compelling, and so hand-wavy for the first few thousand words.
In fact there are quite a few people here on HN who've picked Zig as the “herald of the fight against rust dominance” because they where offended by the Rust Evangelism Strikeforce, like what happened with Nim earlier (a decade-old language that interestingly enough had a popularity boost on HN as an alternative to Rust when Rust's influence grew, before disappearing into oblivion when the next champion (Zig) rose).
As a side note it's actually interesting to see how Mr Walton has evolved over the year as a reaction to the “we need a champion against Rust” crowd: he went from “Rust is nice, you should try it” to straight “stop advocating memory-unsafe languages just because you don't like Rust for heaven's sake”.
This is an extremely vague claim with so many caveats that it doesn't end up meaning anything yet if you state it confidently you might fool idiots into thinking you said something consequential.
It'd be great if there was all the real competition you seem imagine for Rust, but we don't see that. What we see are people pretending that it doesn't matter if they produce crap software using unsafe languages, but their customers are starting to notice.
As to "crap software", most of application software these days -- crappy or excellent -- is written in safe languages, and nearly all low-level code is written in unsafe languages, including some of the world's most dependable software, from avionics to OSes. We can say with close to certainty that we can do better than C, but we can also say that full soundness (Idris) is not the answer, so the sweet spot is obviously somewhere in the middle. But we really don't know where exactly -- except that it's not at either end -- or even how wide the sweet spot is (or maybe there are multiple ones, which could be either universally equivalent or dependent on some variables).
There's more we don't know about software correctness than what we know -- it's extremely complicated and affected by factors ranging from formal languages and complexity theory to management, economics, psychology, and social psychology -- but we believe noe that the ideas of the 1970s of full soundness being the only path have proven wrong (including an acknowledgment even by Tony Hoare [1]), and, indeed, Rust doesn't adopt soundness fully, and relies on testing, code reviews and other unsound processes as the main means for correctness, like virtually all mainstream programming languages.
Anyone who cares about correctness (like me -- https://pron.github.io) knows to be very skeptical of any claims for absolute answers, let alone simple ones, on that extremely complex subject.
[1]: http://176.9.41.242/docs/math/1996-hoare.pdf
@pron I was with you before: I think pcwaltons' take on zig is ... Err, unduly negative to the point of rudeness and closed minded — and kinda paints a clear picture for why we're seeing all of the defensiveness in twitter from andrewkelly and the zig folks.
But — I think you're coming into it similarly here against Rust. Unnecessarily rude, antagonistic, and on technical points: closed minded.
@pcwalton The zig team feels they've made good pragmatic choices around memory safety? Cool. Leave a few reasons why it's different from/and why rust took another approach and your take. Dope.
@pron The Rust folk are happy and proud of the inroads they've made in adoption. Dope. Sure, there's different ways to slice the numbers and you feel what? They've taken unearned pride in their work?
I'm a fan of all of your work, but man. This thread has been disheartening.
Not at all. I think Rust is a groundbreaking and influential language. Regardless of its success in market, it is a great and lasting contribution to programming language design.
I am, however, triggered by misleading claims about software correctness -- a subject I care deeply about -- which recently tend to come from the Rust community (replacing Haskell), and then annoyed further by claims of inevitability that I find hard to reconcile with the data. Sorry, but I am human :)
The Rust team is rightfully proud of their achievements, in language design, documentation, and also in offering those of us who are interested in software correctness another novel approach to consider.
The idea it's either "Rust or Zig" allows the poorly considered logical jump to Zig. I wouldn't use Rust because it's annoying too, but I also wouldn't choose Zig because I consider part of my professional responsibility to be using...literally any language that has memory safety.
If you think it's your responsibility to use only memory-safe languages, then if you had to do low-level programming, you'd have few option, and those options have their own downsides. That's just the reality of low level programming in 2022 -- it can often only be done in non-memory-safe languages. I actually do quite a bit of low-level programming, and I consider it my professional responsibility to strive to do that in a language that is explicit and simple; there are no languages, to my knowledge, that meet my requirement and are also memory-safe, so I must compromise on something because I live in the real world.
That isn't true. You want to use a language that is more "explicit and simple". That's your prerogative, even if I disagree with it. But you do have a choice, and you are explicitly choosing to reject memory safety.
WASM-4 seems to be a technically limited "console" (64kb of RAM, 160x160 console), so it's even more of a niche than just doing game dev for WASM.
Even though I'm technically a millennial… but if the next gen start using Zig instead of JavaScript for everything, I'm on board.
I doubt JS will stop being primary language in browsers in my lifetime.
Javascript "mess" in browsers could be reduced by dividing into two parts. DOM stuff, and pure language stuff. The first part can stay as is. Probably wrapped into thin API for new lang interop. The second part is a completely new lang that compile to wasm (ideal if vice-versa) so that backend could also send wasm to browser and be able to interact with DOM too.
Next, backend js "mess" can be stopped because we have a better way for other languages to develop for the web.
People come and go either because of life or work, and complexity piles up. I don't think there are any silver bullets.
There is a reason Worse is Better. It's quicker to ship and spread.
So basically rust imposes a lot of limitations on how you can structure your program relative to something like Zig or C.
I don't see it imposing that much of a limit. If there is code you know is correct and Rust can't reason about it, do it in unsafe block.
And ECS is not just possible in Rust, but due to mutability guarantees you can make your ECS schedule systems in such way to maximize multi threading. See Bevy ECS.
And how does rust allow you to "maximize multi-threading" over what's possible in other languages? Anything you can express in rust can be expressed in C or Zig as well. The only difference is the implementation you reach will come with static guarantees about memory ownership (so long as you don't use unsafe). So the set of all rust programs is a essentially a subset of all C/Zig programs.
I kinda want to end this assumption. Unsafe only allows few things.
- access to raw pointers.
- implement or accessing unsafe functions (e.g. C FFI)
- implementing or accessing unsafe trait
- access to unsafe union
- mutate global variables.
You can't bypass borrow checker, and you wouldn't do everything in unsafe. If you write everything in unsafe you are definitely doing stuff very, very wrong.
Rust unsafe is a surgeon's equivalent of a scar. Some scars need to happen, and you can tuck them out of sight if you are clever. However if after an operation you look like a map of scars, it means your surgeon is lacking.
No language can prevent you from abusing it, but in Rust it's apparent when you do it.
> And how does rust allow you to "maximize multi-threading" over what's possible in other languages?
Bevy newbie here so take it with a grain of salt. Because Bevy knows when and how Resources are related it systems can freely run in parallel if two resources are unrelated and mutable, or related and immutable.
> Anything you can express in rust can be expressed in C or Zig as well.
Point of a good programming languagues isn't to enable writting programs that can do anything but to aid programmers in writing error-free programs.
Why do you think we use punctuation and spaces? I remember a talk[1] where he noted spaces/punctuation became a thing only when Christian monks started transcribing written words, as a way of error correction. This was how written word looked before:
Withoutspacesitsveryeasytomakierrorsandnotnoticeitinfactdidyounoticeitwhenimadeabunchrightnowassumingthispartdidntcauseheadacheforyouineithercasewrongcodeinrustlooksjustaswrongasthisparagraph
[1] EDIT: Found the talk https://www.youtube.com/watch?v=_EANG8ZZbRs&t=1418s
A few thoughts:
> You can't bypass borrow checker, and you wouldn't do everything in unsafe.
Isn't unsafe still bypassing the borrow checker, in the sense that you're mostly using it because you're doing something the borrow checker does not otherwise allow?
> Because Bevy knows when and how Resources are related it systems can freely run in parallel if two resources are unrelated and mutable, or related and immutable.
But again, I don't understand how that is a unique benefit of Rust. It's completely possible to implement something in C which allows multiple threads to run over unrelated memory locations, or the same immutable memory location. As a programmer you have more options for how to achieve this when not restricted by the borrow checker. Most of the ECS systems in existence solve exactly this problem, and probably most of them are implemented in C++.
> Point of a good programming languagues isn't to enable writting programs that can do anything but to aid programmers in writing error-free programs.
I mean, I think it can't be taken for granted that preventing errors should be the top priority of every programming language. It's probably a priority of most languages, but there's no reason it has to take the number one spot.
I would argue the universal priority of programming languages is to enable the programmer to deliver user value through their program. Rust's thesis is that memory safety issues are such an obstacle to delivering user value that the language should prioritize safety at the expense of a certain amount of pain for the programmer. Languages like Zig and Jai prioritize programmer velocity and relegate safety to optional static analysis tools.
Python is another example: it's very easy to write an incorrect Python program, but the barrier to entry is so low that it enables non-programmers like scientists to do very interesting things by copying a few lines off the internet into a notebook.
There's no one best set of tradeoffs. But as I said from the beginning, if one of the main tasks you are doing is manual memory management, as domains like game dev and HPC require a lot of, you might want to choose a language which prioritizes explicit memory management.
Not really. But using raw pointers and converting to/from memory addresses isn't something borrow checker can check.
It's a borrow checker not address verifier.
E.g. you can take raw pointer, and set two mutable variables to point to it and borrow checker can't know they point to same address.
> But again, I don't understand how that is a unique benefit of Rust.
It's statically enforced by the compiler using Rust's type system.
As far as I know Zig can't say well these two functions can run in parallel because they are at compile time guaranteed to never access same resources and it's impossible to bypass it (outside unsafe). And their content is thread-safe based on the type they satisfy.
> I mean, I think it can't be taken for granted that preventing errors should be the top priority of every programming language.
Douglas Crockford made a good case that every language should on some level try to prevent errors.
> Python is another example: it's very easy to write an incorrect Python program
Python is also older than Java, but even Python is memory safe (GC). Zig and new batch of better C aren't. In that way we definitely regressed.
> I would argue the universal priority of programming languages is to enable the programmer to deliver user value through their program.
If that is truly the case we'd be all programming in Excel and Access. Anything can deliver value, question is - can it be maintained, and at what cost.
In lieu of that a language that makes a set of errors nigh impossible is better than a fast one where those errors are trivial to cause.
That sounds an awful lot like bypassing the borrow checker.
> As far as I know Zig can't say well these two functions can run in parallel because they are at compile time guaranteed to never access same resources and it's impossible to bypass it (outside unsafe). And their content is thread-safe based on the type they satisfy.
Yeah but that's the point. Rust has one way of guaranteeing that two pieces of code don't mutate the same memory at compile time, but that's not the only way to write a correct program which guarantees that. Rust is going to force you to write your program in a certain way to achieve this. There are many other approaches you may be able to use in an unrestricted language which reach a correct and potentially more performant result which are correct, but which rustc cannot verify are correct.
> Douglas Crockford made a good case that every language should on some level try to prevent errors.
That's one opinion. There are many who disagree.
> Python is also older than Java, but even Python is memory safe (GC). Zig and new batch of better C aren't. In that way we definitely regressed.
That's not even an argument. It takes it for granted that lack of memory safety in a systems language is "a regression". That's not an established consensus.
> If that is truly the case we'd be all programming in Excel and Access.
How exactly do you come to the conclusion that Excel and Access are better at delivering value than other programming languages?
> Anything can deliver value, question is - can it be maintained, and at what cost.
Yeah exactly. The point is which language can deliver the most user value in your desired use-case at the least cost. For something like an operating system, where reliability is paramount, it may be a good tradeoff to use something like Rust which is unergonomic and slow to compile because the safety and correctness tools contribute to your use-case directly.
For something like a web front-end project, you're probably not going to choose Rust since it's going to be hard to find enough programmers who are willing or able to get over the Rust learning curve, and Rust's USP's don't do a lot for you.
For something like game-dev, where 30% of what you're doing is thinking about memory layouts, Rust's tradeoffs are actively working against you, and you might appreciate the faster code/build/run loop offered by something like Zig.
I guess you could argue it's bypassing borrow checker in weakest possible sense.
Borrow checker checks borrow. You aren't borrowing you are doing pointer manipulation, and presenting it with stuff that isn't its duty to check. I argue for this because people think that unsafe region is no mans land and that rules of borrow checking don't exist there.
That said, miri should be able to check your unsafe for undefined behavior. https://pramode.in/2020/11/08/miri-detect-ub-rust/
> Rust is going to force you to write your program in a certain way to achieve this. There are many other approaches you may be able to use in an unrestricted language which reach a correct and potentially more performant result which are correct, but which rustc cannot verify are correct.
Yes. It is a small downside, with a huge upside. Seatbelts prevent full mobility but I bet you wouldn't advocate for removing them because crashes rarely happen, and they limit your ability to move during driving.
> but that's not the only way to write a correct program which guarantees that
Rust has a provable way to eliminate a set of errors. You'd need to offer hard proof that code you wrote in alternative way, wouldn't have those issues.
And that alternative way might still be expressible in Rust using some abstraction/unsafe.
> How exactly do you come to the conclusion that Excel and Access are better at delivering value than other programming languages?
You mentioned how Python enabled more people to code. I'm willing to bet if only enabling to code then Excel and Access brought programming to more people, yet we don't see them in use, because maintaining is painful and hair tearingly frustrating. And performance is meh as well, but Python isn't winning any speed medals either.
> It takes it for granted that lack of memory safety in a systems language is "a regression". That's not an established consensus.
I value code that has less footguns than more footguns. Rust showed we can eliminate several cases of footguns, so why add them back? In that sense it's a regression. If you don't value memory safety and enjoy figuring out debugging data races, go nuts. Remove the seatbelts, you probably won't crash. However, if you do - It won't be pretty.
> That's one opinion. There are many who disagree.
3+ billion humans use spaces and punctuation as a error checking mechanism. IDOUBTYOUWANTTOGOBACKTOHOWROMANSDIDIT
Yeah exactly - you're sectioning off parts of the code and telling the borrow checker to trust you that it's ok.
You can't simultaneously argue that unsafe languages are categorically bad and also use unsafe rust as an argument against rust's limitations. Unsafe is either bad or it isn't.
> That said, miri should be able to check your unsafe for undefined behavior. https://pramode.in/2020/11/08/miri-detect-ub-rust/
Static analysis tools outside of the language would also be the way you would check for UB and unsafe behavior in languages like C and Zig.
> Yes. It is a small downside, with a huge upside.
Depending on use-case. Again if your whole programming domain is about memory layouts and the management of allocations, you might want to choose a tool with explicit memory management.
> You'd need to offer hard proof that code you wrote in alternative way, wouldn't have those issues.
Again Rust is only one way to prove those errors don't exist. And for a lot of use cases absolute guarantees of memory safety might not be the greatest concern.
For instance, let's say I am making an HPC program for identifying pricing arbitrage in the market which generates 10 million dollars a day when it's operating. If it takes 10 days longer to implement in Rust, that cost me 100 million dollars. I am not going to care if it crashes twice a day because of an NPE I didn't catch.
> And that alternative way might still be expressible in Rust using some abstraction/unsafe.
Again, once you use unsafe Rust, why not just use an unsafe language?
> You mentioned how Python enabled more people to code. I'm willing to bet if only enabling to code then Excel and Access brought programming to more people, yet we don't see them in use, because maintaining is painful and hair tearingly frustrating.
What's your point? Python is not the easiest code to maintain in the world due to lack of static typing and a host of other issues, but it allows data scientists and others to produce billions of dollars worth of value around the world in ML, AI, and business intelligence operations. You could say they could write more correct, more maintainable programs in Rust, but that pool of practitioners just don't exist who are advanced data scientists and also Rust developers. It's a different tool for a different job.
> And performance is meh as well, but Python isn't winning any speed medals either.
And it doesn't matter because performance isn't relevant in most of the applications where it's used. Just another example of a tradeoff.
> I value code that has less footguns than more footguns.
You might value that but it doesn't mean it's an objective measure of a programming language for all people and all use cases.
> Rust showed we can eliminate several cases of footguns, so why add them back?
It's not "adding them back". Strict ownership enforcement is not a universally accepted advancement in programming languages which every new language gets measured against. It's an experiment Rust is running. It remains to be seen whether it's the right way to do programming.
> 3+ billion humans use spaces and punctuation as a error checking mechanism.
I don't even know what to say to this. Spaces and punctuation got accepted because they're more ergonomic and universally accepted by consensus as the better solution for making text readable. It's a better UX for reading.
Most system programmers do not program in rust. There's no consensus that it has chosen the right tradeoffs.
I'm not arguing philosophically. I'm arguing from a safety viewpoint. A language that's 100% unsafe is worse than a language that's 1% unsafe.
Saying it's not perfectly safe is sophistry. Nothing is perfectly safe, but you still don't hand out your sensitive bank information to random person on the Internet/street/etc.
> Again, once you use unsafe Rust, why not just use an unsafe language?
Assume data race happen. Would you prefer to audit 30k lines or 3? Unsafe language is unsafe everywhere. In Rust, you can limit your search to unsafe regions.
> Static analysis tools outside of the language would also be the way you would check for UB and unsafe behavior in languages like C and Zig.
Define outside language? Miri is maintained by rust-lang team. And Clippy and so on. Sure valgrind and so forth aren't, but their checks are somewhat complementary.
> For instance, let's say I am making an HPC program for identifying pricing arbitrage in the market which generates 10 million dollars a day when it's operating. If it takes 10 days longer to implement in Rust, that cost me 100 million dollars. I am not going to care if it crashes twice a day because of an NPE I didn't catch.
Sure, but if your implementation has a data race error, that when triggered happens causing massive loss of funds. First you'll have to find the issue (good luck searching most of language and deps). Then you need to patch it to prevent future errors. And it can happen again. So maybe 3 days here, 5 days there, 4 days there, and so on.
Granted it's a contrived example, but hey... If you want HPC and safety use Java/C#/Lisp, no Rust necessary.
Point being - Strength of Rust isn't in speed of development, so much as in avoiding certain sets of bugs. And borrow checker isn't the only tool to achieve this.
> Depending on use-case.
On that I agree. If your game is one and done (no maintenance), no user content, no MP, basically worse that can happen is crash sure go ahead. Jams are in that way perfect candidates for small langs where speed of development is crucial.
I'd argue most sold games aren't one and done.
> I don't even know what to say to this. Spaces and punctuation got accepted because they're more ergonomic and universally accepted by consensus as the better solution for making text readable.
Keep in mind that in Rome everything was written without spaces for hundreds of years. From their POV the spaces would be just unnecessary fluff. And there are still languages that have little to no spaces, so spaces aren't even universally accepted. See Chinese and Japanese.
> Most system programmers do not program in rust.
I don't understand, this wasn't specific about just systems language? Going from C# to Zig is a safety downgrade (but a possible performance uplift). And GC langs have been used in OS implementations.
> There's no consensus that it has chosen the right tradeoffs.
Sure, but consensus is a matter of current status and it's not set in stone.
Status quo is C, which has null - a trillion dollar mistake (adjusted for inflation and software spread :P)
> What's your point? Python is not the easiest code to maintain...
My point that we use Python won in ML because allowing people to achieve value isn't the only important aspect. There are many aspects. Sure you get to pick your own, but I've seen too many CVEs caused by memory unsafety.
But safety and reducing footguns should be ideals for any language to strive. Reintroducing footguns? What's next? Return of GOTO Spaghetti monster.
You want to make a nuanced argument that calculated unsafety is better than general unsafety, but you don't want to accept a nuanced argument that Rust's safety tools maybe a detriment in some use-cases.
> Assume data race happen. Would you prefer to audit 30k lines or 3? Unsafe language is unsafe everywhere. In Rust, you can limit your search to unsafe regions.
It depends on the use-case.
> Sure, but if your implementation has a data race error, that when triggered happens causing massive loss of funds. First you'll have to find the issue (good luck searching most of language and deps). Then you need to patch it to prevent future errors. And it can happen again. So maybe 3 days here, 5 days there, 4 days there, and so on.
This is a strawman argument which doesn't reflect reality. C/C++ is actually the main language used in HPC applications like high frequency trading, and they have massive incentives to choose the correct tool for the job.
> If you want HPC and safety use Java/C#/Lisp, no Rust necessary.
You can't. I chose HPC deliberately as an example: in HPC performance is the most important constraint. You couldn't use a garbage collected language because you will not be able to optimize memory performance beyond a certain point since you don't have direct control over allocations.
> On that I agree. If your game is one and done (no maintenance), no user content, no MP, basically worse that can happen is crash sure go ahead. Jams are in that way perfect candidates for small langs where speed of development is crucial.
Then what are we arguing about if you agree with me?
> Keep in mind that in Rome everything was written without spaces for hundreds of years. From their POV the spaces would be just unnecessary fluff.
You don't know that. They might have looked at spaces and understood immediately that it was an improvement.
> And there are still languages that have little to no spaces, so spaces aren't even universally accepted. See Chinese and Japanese.
What point are you trying to make? Wouldn't that support my argument that there's room for different modes of programming, both safe and unsafe?
> I don't understand, this wasn't specific about just systems language? Going from C# to Zig is a safety downgrade (but a possible performance uplift). And GC langs have been used in OS implementations.
I could have also said "most systems programmers don't program in safe languages". The point is the jury is still very much out on whether language-level memory safety is the best solution for all systems programming languages. It's relevant because Zig is the language you are cliticising.
> Status quo is C, which has null - a trillion dollar mistake (adjusted for inflation and software spread :P)
You can focus on the negatives because C is literally the most successful PL ever which the entire world is built on. People are already talking about how GC is a mistake for a lot of applications. Maybe 10 years from now we will be talking about some big mistake Rust made with async colored functions.
Maybe it will turn out Zig's approach is the right one. We don't know yet.
> My point that we use Python won in ML because allowing people to achieve value isn't the only important aspect.
It's the most important aspect. Every other aspect is just relevant to how you deliver value.
> But safety and reducing footguns should be ideals for any language to strive.
I'm sorry but you seem to be missing my entire argument. You agree there are tradeoffs. You agree there are use-cases where safety might not be the most critical thing. You have agreed with every component of my argument but you then want to draw the conclusion ...
No. I'm making a simple argument. More safety is better than less safety. You're trying to move argument that since perfect safety is impossible it's not worth pursuing. This is the sophistry part.
> It depends on the use-case.
No it doesn't. Debugging 30k lines is always going to take more than 3/30/300 lines especially when data races are involved.
> This is a strawman argument which doesn't reflect reality.
I said it's a contrived counter example for a contrived example.
> You can't. I chose HPC deliberately as an example: in HPC performance is the most important constraint.
There are HFT systems using Java, few were on HN even. That said, you might have thought of UHFT, but those use FPGA and ASIC, so not even C/C++ would be really correct.
> You don't know that. They might have looked at spaces and understood immediately that it was an improvement.
I know human nature. What we are used to is what we consider natural/ergonomic.
And for the record ancient Greek and Romans made it point of pride to know where and how words end.
> Wouldn't that support my argument that there's room for different modes of programming, both safe and unsafe?
Well, not really. I'm saying ergonomic isn't universal. Due do mixing with English and other such languages what's considered ergonomic is shifting towards spaces and punctuation.
> It's the most important aspect. Every other aspect is just relevant to how you deliver value.
Ok, I see where you are coming from but I fundamentally disagree. If you prioritize delivering stuff fast (move fast, break things) you'll end up with a lot of broken software, and unmaintainable messes along the way.
Maintainability and safety should be primary motivatiors.
Without safety, your performance gains can be rendered moot point anyway. And without maintability your code performance will slowly rot and die.
I'm not trying to move anything. I've made the consistent argument from the beginning that more language-level safety is not the most important design constraint for all use-cases.
> No it doesn't. Debugging 30k lines is always going to take more than 3/30/300 lines especially when data races are involved.
Yes it does. See HPC use-case.
> There are HFT systems using Java, few were on HN even. That said, you might have thought of UHFT, but those use FPGA and ASIC, so not even C/C++ would be really correct.
The point still stands.
> I know human nature. What we are used to is what we consider natural/ergonomic.
Ok now I suspect you're deliberately waisting both of our time. You can't claim to know what romans thought about spaces.
> If you prioritize delivering stuff fast (move fast, break things) you'll end up with a lot of broken software, and unmaintainable messes along the way.
I never said you should prioritize delivering stuff fast. I said you should focus on delivering value. So if your code is an unmaintainable mess, cleaning up your code is going to be the shortest path to delivering more value because it affects your velocity.
If you're writing OS-level networking code, safety is going to be critical to delivering value because security is paramount to your mission.
If you're writing a game, having direct, explicit, ergonomic access to memory may be more relevant to delivering value than slowing yourself down to make sure you are 100% sure every line of code is safe.
> Maintainability and safety should be primary motivatiors.
Unless they're not. If I'm prototyping a project it might me much more important to get something in front of users to see how they like it than it is to make something safe and maintainable.
Some code is used and built on for years and years. Other code is used and thrown away after it serves its purpose.
The HFT systems I know about in Java are mostly not recognizable as Java to most Java programmers. They use static allocation of all data making sure that there is no risk of a GC interrupt and have a fixed set of threads that have assigned cores.
It is sometimes a reasonable way to build a system, but very seldom.
Why not? Rust has unsafe programming as opt-in; and the unsafe stuff is delimited with language constructs.
A nuanced argument is possible like that situation is better than unsafe computation with no opt-out, requiring very careful programming plus ad hoc tooling.
It’s still early days for Bevy but they’re making steady progress.
Independently of Bevy's progress, a parallel ECS is not a good choice for a prototype-like game project.
Current situation is it's not language-agnostic as movement, it's just c/rust mostly.
So wasm-4 seems to have more interesting examples than the other e.g. https://wasm4.org/docs/tutorials/snake/handling-user-input
The specifications are open and detailed [1]. Specifications like that can be daunting to consume if you want a place to start from instead of a complete overview of the landscape, but there are tutorials in pure web assembly if you want to get started.
[1]: https://webassembly.github.io/spec/core/text/instructions.ht...
Right now I am teaching a VM course on the back-half of the Wasm equation: how to build an engine for Wasm. The course is about more than Wasm, of course, so there is a lot of content about JVMs and dynamic object models, but the projects are based around Wasm.
In the future I envision university compiler courses getting divided into two halves, either as one course with two halves, or two full courses. The first course/half would be entirely frontend: parsing, semantic analysis, IR, translation, lowering--and the target would be WebAssembly. The second course/half would be all about compiling Wasm to machine code. If the second course wanted to go more in the VM/runtime direction, vs focusing on compilation, it could include the upcoming GC extension or a custom extension to have objects.
I think Wasm is the future of code formats and languages, so I'd like to move the needle here for PL implementors.
You read my mind, yes. That's why I said I have AST.
Is your course private? I'm interested.
On the other hand, is the SNES "The Legend of Zelda: A Link to the Past" style everyone's favourite pixel art style, or is it just me? Without tricks it did 256 colours of of 4096 in Mode 7. You can't do art that's as pretty with four colours. Is it a restriction that's too harsh or are we ok with games that just aren't very pretty?