Notably, when it was written before there was not a package manager available. Now there is, so I rewrote that section. It should finish deploying in a couple minutes.
Notably, when it was written before there was not a package manager available. Now there is, so I rewrote that section. It should finish deploying in a couple minutes.
It is true that `c.d` might call a function, but it’s not because of @property functions (which exist but are discouraged), it’s because the parens are optional to call a function/method if there are no arguments.
underneath there is literally assembly to take current state, push it to the stack, then jump into another location in memory and start executing.
And then when done, do the reverse. jump back to another memory location and pop everything back off the aforementioned stack and into registers.
interrupts are also control flow but, again, there are no conditionals there.
control flow is about the order of execution, one common way to get there is using conditionals, but it's not the only way.
Having said that, even if you disagree with Andrew's wording, the overarching idea remains. You always know explicitly if the flow changes.
However I think the notion that “flow control” has to do only with conditionals is not a common one. FWIW the definition on Wikipedia, which aligns with my experience is not this restrictive… the lowly goto is flow control. Basically anything that controls the program location is flow control.
Yeah, flow control isn't just conditional jumps. You can kinda treat branchless code as a form of flow control as well.
That's the common understanding of flow control, the other poster is right in that it's not typically just conditionals. There are a few posters who were under that misapprehension, but that's never been the common understanding of it, it's just that conditionals are typically where people worry over flow control because otherwise it's linear.
And flow control and indirection are not two concepts I’ve ever grouped together as complementary either. A function call is not something I’ve ever heard as “indirection”.
Unless you ditch optimizations completely, it is hard to know without looking at the generated asm. Of course you can make educated guesses.
struct S {
int m_field;
int field() { return m_field; }
void field(int c) { m_field = x; }
}
just to future proof the field access. Don't bother with the access functions until they are actually needed.So I overrode the field access that operated directly on the byte array.
PS: It was in Kotlin, using @get/@set, but it doesn't matter for the philosophy.
If anything, I would argue that explicit accessors make it clearer because in e.g. C# you can't write a method that looks like a getter (but mutates state) by accidentally naming it as such. If someone made something a property, that's because they thought its semantics are property-like, which includes not mutating global state. Sure, people will still get that wrong occasionally, just as they run mutating "get" methods, but it is surprisingly rare.
Suppose you include a logging statement in your accessor, which hides a race condition. You're gonna tear your hair out.
When I was new to their corresponding GUI frameworks, the dot + property notation was appealing because it looked clean. However, as I got more experienced I'm no longer seeing the advantage of saving two parentheses characters at the expense of potentially hiding function calls where anything can happen.
I'm not sure why D joined the club given it doesn't have a corresponding de facto GUI framework, and its users even discourage it.
Attribute access is reading a value, invoking a function is different (as mentioned, using a stack, etc.), although it is certainly possible a function only reads and returns a value.
All that to say my answer is yes, providing flow control mechanisms makes it flow control... and falling trees make a sound!
I'm not saying Zig will go the same way, I hope it succeeds. But success in industry funding is not a guarantee, successful transition to large team contributions is not a guarantee, and even if all of that does pan out, by then the language may be markedly different.
Look at Rust in 2012 vs its 1.0 in 2015 and ask yourself if you'd want you and your team to have to make so many changes to production code. Ask yourself how many unknown costs you are willing to risk in exchange for whatever you believe is the actual upside of using Zig for a particular project.
Sure, somebody has to break that cycle by making those bets, but be sure before deciding to be among them. Somebody else making that bet only changes the odds so much.
(I'm not even willing to entertain the notion that they would fork Zig and maintain it long term. Even if they somehow did which would be nuts on its own, they'd still be cut off from the rest of the ecosystem and lose out on that front.)
My best case for Zig is that it offers a worthwhile option to clean up existing C & C++ projects without incurring, or at least deferring, the more substantial costs of rewriting outright in Rust, bindings or no. "Maintain it in Zig" is a sensible value proposition, or at least it will be once that Zig code has a compatibility promise so it's not trading one maintenance cost for another.
Look at how costly it was for the ecosystem to migrate from Python 2 to Python 3, even despite how many participants in that ecosystem were themselves large, well-funded corporations. Situations like that are why Go and Rust have made permanent 1.0 compatibility promises even at the cost of some tech debt which they know will only accrue further. Zig will too, but it hasn't yet, and anybody adopting it now risks unknown migration costs.
> Then again, I can’t predict the future and it could very well be that bun and zig both blow up. Same could be said for Rust.
Sure, lots of things are possible, but ask yourself which is more likely. That's all I'm saying here. Rust has already been where Zig is now and is in a meaningfully different place today: a stability promise and substantial industry adoption and contribution. It no longer depends on any one person and a lot of investment is going in to its continued success.
Anything can still fail, but there aren't that many examples of languages outright failing after reaching this point in industry adoption. There are many examples of languages outright failing by pushing backwards-incompatible changes on the industry right in the middle of what should have been a healthy growth curve. There are also many examples of simply not offering enough marginal value to justify their marginal costs.
The title here is "C++, D, and Rust" and, I'm sorry to say, but one of these is not like the other ones. Zig will have a lot of work to do in order to end up more like Rust than D, especially when memory and thread safety are a big part of why the industry is adopting Rust in the first place. Notice how Chromium does not have a Zig branch just like it never had a D branch. It was all C++ until Rust offered clear improvements to safety in exchange for its adoption costs.
Chromium has a rust branch because “Rust has X feature”, not because zig does too and there was never a decision: rust or zig.
That’s apples and oranges my friend. All I’m saying is Zig, while lagging behind its corporate sponsored behemoths, is going to be around for quite a while. There’s a lot of game dev happening with zig too. Bun is just an easy target to use as an example.
I do agree with your argument about “why choose X over Y to rewrite your codebase” but to clarify, I never made such comparisons. I wouldn’t recommend zig for a c++ refactor. Maybe a rewrite if it was small. Definitely for green field development. A stability promise is still just a promise. Backwards compatibility is a valid argument to make. Will my code from a decade ago compile today? Zig still has some growing to do before that is true.
D also supports the following memory allocation strategies:
1. RAII
2. stack allocation
3. malloc/free
4. custom alloctors
Each has its tradeoffs, you can pick the most appropriate one. The D compiler itself uses all of them :-/
You can see this happening with the duplicate stories that show up on Hacker News; in general, it's a good thing:
“There are only two kinds of languages: the ones people complain about and the ones nobody uses.” ― Bjarne Stroustrup
Ghostty - A new terminal emulator written in Zig - https://zig.show/episodes/32/
Note: the original article title could perhaps be updated to include Golang as it is mentioned a few times.