This is interesting. I've been relearning C++ after not using it for 25 years. It is hard, I was a Java dev for years, now Python with some Golang. Carbon looks much easier to take up.
// A dynamically sized array, like `std::vector`.
var circles: Array(Circle) = ({.r = 1.0}, {.r = 2.0});
Yegads, they've put effort into ensuring API and ABI compatibility with C++, but they've gone and decided to change the meaning of nouns for basic types?!
Why, just why would introducing that obvious footgun be appealing? It raises the concern that the language is full of other arbitrary choices hiding dangerous footguns.
Edit:
Strangely, their test suite makes it look like Array is bounds checked and fixed size; there is no test for resizing:
A developer familiar with C++ may believe it to be a fixed length container (perhaps with automatic bounds checking[0]) and treat it as such in memory/security/performance critical sections.
It actually can be, mathematical vectors gaurantee for example that x+y == y+x for all x,y, but no such gaurantee can be ever made on the user-defined operator+, indeed you can't even gaurantee that it is defined to begin with, let alone in the manner prescribed by linear algebra.
It's std::vector that was weirdly named. In plenty of codebases "Vector", particularly gamedev and scientific, will mean the mathematical object with that name.
Other languages don't need to replicate this mistake.
I don't see any reference to it in the GH readme, but I do wonder what they call actual arrays (as in, fixed size allocations of memory that store a contiguously typed value).
I was talking about std::vector (and Rust's Vec). Those are dynamic arrays (as in, growable allocations of memory that store a contiguously typed value).
You probably know that, but just to clarify: it's backed by a single array, reallocated repeatedly, just like std::vector in C++ (although growth factors are different, I think).
Just "List" probably risks that some people will jump to the conclusion that it's a linked list. I'd probably prefer the full "ArrayList". Although personally I'd use something like "DynArray"/"DynamicArray".
Doesn't seem particularly uncommon. Perl, JavaScript, and Ruby come to mind if you're really looking for languages that use just a raw term "array" with no extra qualifiers.
With the new versions of the JDK I think they will.
The Java Vector features will be out of incubator in the next year or so and unlike the existing Vector, it's actually useful. For context the new vector features are for SIMD support on the JVM.
I'm honestly surprised java.util.Vector still exists. It was "deprecated" in 1.2 or something like that? I guess there's no pressure to actually remove it, though.
I only know about it from dealing with J2ME crap where ArrayList wasn't available.
An std::vector is a vector in the mathematical sense, though. It's a homogeneous tuple. It's just that using an std::vector of std::vectors to store a list of points would be inefficient.
My bad. I meant to say "vector space", not "vector field". I understand the difference, but I often make this mistake because the set of a vector space is almost always the set of an algebraic field (i.e. the reals).
I guess you could make it a vector space through a bijection with the rational numbers, but something tells me C++ programmers don't have that in mind when writing std::vector<unsigned>. And it doesn't solve the problem that C++ “vectors” are resizable.
Ah, missed the N... But more interestingly, the non-negative integers 0...p-1 modulo a prime number p form a field (where -1, -2 etc. appear in a natural way), and so their tuples of some fixed length do form a vector space.
It's not. Vectors can be added together and multiplied by scalars. That they are often represented as tuples of coefficients is just notation, doesn't matter for the notion of vectors, and vice versa: a tuple is not necessarily a vector.
1. std::vector doesn't have a fixed dimensionality, as would a mathematical vector. A fixed-length array actually makes more sense as a vector.
2. It doesn't provide the operations of addition and multiplication by scalars out-of-the-box (though you can whip up your own). Moreover, in general those operations wouldn't make sense for the elements which can be stored in a std::vector. E.g. neither multiplying bank account numbers by scalars, nor adding two bank account numbers make any sense. It would be good if you modelled them with types which don't allow those operations. Yet storing them in a std::vector makes perfect sense. But std::vector (or tuple) of bank account numbers is not a vector.
Worse, they have been calling the location of a pointer to a subroutine that handles an interrupt a "vector" - the word which was originally used to refer to the entire set of such locations. (Curiously, this usage is similar to how the word "sector" is used to refer to a physical record on a disk - simply because it usually comes last in the coordinate triple (cylinder, track, sector). This would be like calling a point in the 3-dimensional space a "Z".)
1. That doesn't make it not-a-vector. It just means there isn't a one-to-one correspondence between std::vector<T> and T^n. However, a particular instance x of std::vector<T> is still a T^x.size().
2. Operations are not intrinsic to a set, but to an algebra. Why would there need to be any correspondence between the operations of linear algebra and those of banking algebra in order to call an std::vector a vector?
2. I'm not sure I understand you here. A vector is defined by those operations. A set without those operations, even if it has the same elements, is not a set of vectors anymore. I don't understand your remark about sets here. The correspondence is necessary, because those operations on vectors are induced from the operations of the relevant field of scalars. The operation of adding vectors of bank numbers would be induced from the operation of adding bank numbers, if there was any such thing. The operation of multiplying vectors by scalars (bank numbers in this case) would need to be induced from the operation of multiplication of bank numbers, if there was any such thing. Anyway, I think you got hung up on the example, when the point is you can have std::vectors of types for which those operations don't make any sense. Now, imagining that perhaps there hypothetically might exist some definitions of those operations, just to convince oneself that std::vector is a vector is really stretching it, and I'm not even sure at this point if you're not trolling.
Anyway, as another commenter pointed out, Stepanov himself, who gave this container its name, said that it has nothing to do with vectors, and he wouldn't name it vector, if he could correct this mistake.
A vector is defined as I did above. It's a homogeneous tuple, i.e. the Cartesian product of n sets, where all sets are the same. Vector addition plus scalar multiplication are not part of the set. Usually they're part of the definition of a vector space. E.g. (R^2, +, ⋅). But you can construct a vector space out of a set of non-vectors (such as matrices), or out of operations other than vector addition and scalar multiplication, and you can use vectors for purposes other than constructing vector spaces, also without involving either of those operations. For example, to store sequential information.
Then you're using a definition of vector, not used in any mathematics course.
> you can construct a vector space out of a set of non-vectors (such as matrices)
A vector is by definition no more and no less than an element of a vector space. Vectors are defined by vector spaces, not the other way around.
If you have a vector space whose elements are matrices, then those matrices are vectors. And they will be written in coefficients in a given base as tuples.
> out of operations other than vector addition and scalar multiplication
You don't "build vectors out of operations like vector addition and scalar multiplication", as in: you don't choose them. You choose the field and dimension, and those operations (vector addition and scalar multiplication) are a consequence.
> you can use vectors for purposes other than constructing vector spaces, also without involving either of those operations
Again, you don't construct vector spaces out of vectors - there are no vectors without vector spaces. And there are no vector spaces without those operations. But yes, you can use vectors from a given vector space in a greater capacity than just as vectors.
An example, which shows the futility of looking at vectors as just tuples: a real number is a vector in the vector space of real numbers over the field of rational numbers.
>Then you're using a definition of vector, not used in any mathematics course. [...] A vector is by definition no more and no less than an element of a vector space.
It's the definition I was given. If you accept that the word "vector" may be given a definition different from the one you give it, you'll need to concede that an std::vector may be a vector.
>you don't choose them. You choose the field and dimension, and those operations (vector addition and scalar multiplication) are a consequence.
You're using the phrase "vector addition and scalar multiplication" in a different sense than I meant. I was referring to component-wise addition between two vectors and to multiplication between a scalar and the individual components of a vector. You could choose different operations to construct a vector space, as long as they meet the requirements of vector spaces.
You used the phrase to refer to the constructing operations of a vector space. So yes, a vector space is indeed constructed out of the operations it is constructed out of. You could have been more charitable in your interpretation of my words, rather than assume I was saying something equivalent to "four-cornered triangle".
A vector is definitely not defined as you did above.
A vector is an element of a vector space, basically anything that you can add together and multiply with an element of a field. It has nothing to do with what you wrote above.
Ironically, C++ does have a standard container that can be added together and multiplied by scalars... and it's called an array; std::valarray, to be specific.
Indeed, "vector" appears to be relatively recent terminology, it has been "array" since the dawn of programming. But it's too late now, and we already have the std::array anyway...
>An std::vector is a vector in the mathematical sense
No, because you can't prove that std::vector<T> obeys all vector space axioms[1] for all T, which is good because it's impossible, I can trivially define a T that will break any number of axioms and the cpp compiler will happily let me instantiate std::vector on it.
Based on my quick read, “Why build Carbon?” section calls out just 1 problem with C++ which is the developer experience. Agreed.
However Carbon seems to do a whole lot more than DevEx. It’s practically a whole new language that can interop with C++. I don’t see the point in that. Would be great if someone pointed out why I should change my mind.
It's not immediately obvious from this page and GitHub org, but this is a Google led project. It's led by Chandler and the c++ toolchain team. I have no idea of it's endgoals or how open to non-Google ideas it will be.
The governance of the project is not immediately clear to me, and I have to assume that the Google team is working in good faith. That team cares a lot about C++ and its future. They are obviously aware of this stigma. I also think that Google is pretty bad at open source governance though :/
Disclosure: Former Google engineer who worked sorta adjacent to some of those people.
Huh looking at that page and saw Kate Gregory is involved. She's someone who, as a mostly outsider who dabbles in C++ occasionally, seemed incredibly dedicated to seeing C++ thrive and people come to understand the language. Her involvement here seems like a huge positive to me, but maybe that's coming from a place of ignorance.
Can we not with this tired joke. Yes we're talking about the company with hundreds of chat apps, but we're also talking about the 100,000+ employee company that developed and support Golang, Dart and Flutter. But ignoring all this, the GitHub page is pretty clear: "Carbon is currently an experimental project." You shouldn't have confidence that it will be supported but they are pretty clear about it, they're trying to find the right fit.
>> Can we not with this tired joke. . . . You shouldn't have confidence that it will be supported . . .
It is not a joke.
It is a reputation that Google has earned through its actions and inactions.
As shown by https://killedbygoogle.com/ and numerous desperate posts for help [1][2][3] on this and other web sites, Google's "must launch a new shiny thing" promotion culture and abysmal customer service have eroded public trust in the long-term viability of anything that Google creates.
The only comparable thing to an open source programming language on that list is AngularJS, and I wouldn't say that was killed but superceded by Angular 2 (which is also a lot better).
Based on what they've told me the long term governance plan is to establish an independent foundation, with development controlled by three equal lead developers from different companies.
It may have been started by mostly Googlers but they want other companies and individuals to participate
Official governance vs the effective governance is the real crux of this issue. Immediately starting from the lead developers separated by companies already puts a deep corporate interest spin on the project. Choosing to do a lot of the initial work in secret and then disclosing is also a pretty big data point.
I think this is going to be an uphill battle for them and I hope they win it but I'll be skeptical unless if I start seeing radical (for google) transparency basically immediately.
Also worth pointing out that the language is not immediately worthless even if they fail or only partially succeed in this endeavor!!
This is an odd line to take considering the language spec is unfinished and there’s no implementation. Anything less than or earlier than this phase of initial work would be akin to “let’s make a new C++; anyone have ideas?”
Also, for what it’s worth: despite being an ISO-standard language, C++ is still heavily swayed by corporate interests, with most committee members being tied to BigCos. This has the effect of somewhat-necessarily aligning language progress with its most significant users. Without this alignment, the language might be “better” in some respects, but less useful.
So you had no problem with Golang being led by Google for more than 10 years and now this new language is somehow a problem because that one is also led by Google?
C++ also has a very hard-line "you don't pay for what you don't use" philosophy, which sometimes lead to standard library APIs or language semantics which are a bit tortured.
Compare C++ <random> or <chrono> against, say, the equivalent functionality in Rust, Go, Java, C#, etc. C++'s APIs are a bit overcomplicated, or at least they look that way if you don't know the various reasons why the C++ standard defined them that way (reasons which are probably not relevant to your use cases).
"C++ also has a very hard-line "you don't pay for what you don't use"
This always felt eye-rolling false to me. We can't have a better hashmap since we all need to pay for the std::unordered_map's un-needed features like bucket access. We are certainly paying for what we don't use.
"You don't pay for what you don't use" does not mean "the compiler doesn't generate worse code than if you had written the same by hand".
These 2 things are C++ core principle, but they are 2 different things.
"You don't pay for what you don't use" means that I you do not use a C++ feature, your runtime performance won't be affected by this feature. For example, non virtual functions are not slower because virtual functions exist.
In our case here, if you do not use "std::unordered_map" and decide to implement your own unordered map, then it is as-if "std::unordered_map" never existed. You are not forced to use "std::unordered_map" and you own map won't be slower because it exists.
"the compiler doesn't generate worse code than if you had written the same by hand", or rather "What you do use, you couldn’t hand code any better", means that if you decided to implement a C++ feature by hand in C++ or C, your implementation could only hope to match C++ implementation. For instance calling a virtual function in C++ will never be slower than a similar handwritten late dispatch implementation.
No good can result from the interaction between the most complex and powerful programming language and the corporation who created the programming language for dummies.
> A key example of this is the committee's struggle to converge on a clear set of high-level and long-term goals and priorities aligned with ours [https://wg21.link/p2137].
I was frankly shocked by that goals and priorities document. The non-goals section reads like an open declaration of war against anyone whose use cases for C++ differ from GOOG and NVDA. My interpretation of Carbon is that since GOOG failed to take over the standard in favor of its narrow use cases, that they are building a new language optimized specifically for them.
> I have no idea ... how open to non-Google ideas it will be.
The most-generous attitude to take is that it will be managed similarly to Go. If your use cases and priorities are well-aligned with theirs, then feel free to use it. But while they may listen to third-party feedback, it will be their own use cases and opinions which dominate the language's development.
Why use these stock index abbrevs (or whatever they are) in this context here? GEEZ!
To the topic, it sounds a bit grumpy. If we look at languages and how many evolve... many suffer the phenomenon that they almost all are Turing complete, and try to gain concise (or simple understandable) expressiveness somehow, and then they try to not break compatibility too much to varying degrees - net result: they grow and grow where at one point they feel like too big, too much legacy dragged around (C++), the "one obvious way" lost (Python) when they cater for use case after use case.
Limiting can be good in that regard. So having key goals defined and not to cater to every small new usecase by someone is a valid attempt to not let this happen, so while I dislike Googles power, I wouldn't feel to bad with attempting this by anyone on their fresh language?!
Success for the Carbon Language requires it to successfully be an independent and community driven project. We may not succeed (this really is an experiment), but we're working hard to engage broadly and early in large part because of this being such an important goal and priority for us.
Projects like this have to start somewhere, but can grow and become community endeavors. We are also already seeing strong interest from other companies and organizations in participating in this experiment.
The README doesn't expand on what is probably the most challenging problem: how do you achieve effortless C++ interop without burdening Carbon with all the odd behaviour and memory safety / UB issues prevalent in C++?
In Rust for example, `unsafe {}` blocks are not just "local unsafety". They can freely operate on all memory, so they are infectious and are essentially a marker for "dangerous code below, be extra careful and audit lots".
But if all code can freely interoperate with C++, how do you improve upon C++, apart from relatively isolated features like a better generics system?
To what extend can a Carbon compiler that is deeply aware of C++ semantics mitigate the pitfalls?
C++ has many many issues other than memory safety. For example implicit type conversion, template duck typing, the include system, the very very very complicated name lookup system, a gazillion footguns inherited from C.
You can definitely massively improve upon C++ without touching its actual computation model.
I don't necessarily agree with all their design goals, but it is unfortunately true that getting a large coherent change through the C++ committe is an herculean task. The language ends up doing a random walk via small steps through the design space without a coherent long term vision, because nothing else is feasible.
Implementing a coherent vision might lead to a better language even if most stakeholders might disagree with every single change.
There are weird governance issues with the C++ committee too. Acceptance or rejection of a feature can depend on which reps just happen to show up that day.
I really don't see that. At the very start they say
> That said, our experience, use cases, and needs are clearly not those of every user. We aren’t pushing to directly build consensus on these points. Rather, this is presented as a vehicle to advertise our needs from C++ as a high-performance systems language.
The point of the non-goals is simply stating things they don't care about, which is pretty reasonable. After all, it's easy to say what you want, but what are you willing to give up for it?
The primary goal is clear from the P2137 document: Performance. There are optimizations both in the standard library and the language that the C++ committee will either adopt too slowly for Google’s needs or not at all.
Looks like this experiment has been going on for a couple of years, a bunch of familiar (internet-familiar, have met Chandler a couple of times but do not know any personally) names were secretly working on it, and it was only made public a few days ago:
It seems that the goal is a new language with full interop with C++, kind of like Zig's interop with C.
- I wonder how much baggage had to be maintained for interop. If some of it could be isolated, how did they do it?
- Does this fall into any of the traps that D initially did where it allowed C interop but was, by default, more limited in what C environments it could run in or is this as flexible as C++ for environments?
As for the language itself, I've not had a chance to dig into it too much but I am sad to see that it uses explicit local inference by replacing the type name with `auto` rather than eliding the type completely [0]. While it has its pains at times, this is something I've come to enjoy in Rust.
I also didn't see mention of tooling. Having out-of-the-box build, test, and code formatting would be a big help for establishing community standards / practices, even if the build/test tool might get limited when having to do C++ interop. At least for pure-Carbon libraries it would be a big help!
> Once we can migrate code into Carbon, we will have a simplified language with room in the design space to add any necessary annotations or features, and infrastructure like generics to support safer design patterns. Longer term, we will build on this to introduce a safe Carbon subset. This will be a large and complex undertaking, and won't be in the 0.1 design. Meanwhile, we are closely watching and learning from efforts to add memory safe semantics onto C++ such as Rust-inspired lifetime annotations.
I'm a bit skeptical if they push off lifetime annotations too far.
Apparently this is a google or google-adjacent project. Google was one of the most vocal committee members in favour of breaking ABI stability, so it is not surprising.
C++'s current unwillingness to specify a stable ABI (or even state that ABI stability is a goal) but also have the standard libraries avoid breaking the ABI is a worst of both worlds currently. And the refusal to break the ABI adds overhead to things like std::unique_ptr which isn't really great.
If you are like me and wondering "What makes carbon different from Rust or Zig?
1. The ability to interoperate with a wide variety of code, such as classes/structs and templates, not just free functions.
2. A willingness to expose the idioms of C++ into Carbon code, and the other way around, when necessary to maximize performance of the interoperability layer.
3. The use of wrappers and generic programming, including templates, to minimize or eliminate runtime overhead.
In otherwords, what carbon can do that Rust can't do, is take a C++ class with a `foo` method and call that method. Or create a class with a `foo` method and call that method from C++. Probably one of the biggest hurdles to get over in C++ interopt. Most don't do that, instead you'd make a C function binding and struct and move data/invoke functions through that.
Well, they are different languages made for different things. Clasp was specifically made because the author had a bunch of C++ code for his research projects, but wanted something more high level/simpler to implement things in. He landed on Common Lisp but none of the implementations had good C++ interop, so he made his own. Can recommend Christian Schafmeister's (creator of clasp) talks on it, it's interesting stuff. In particular his talk on an LLVM Conference.
A programmer could make simple mistake thinking that is declaring a variable of type Foo. Carbon eliminates this by having explicit keywords for variable and function declaration. (This style is much more Rust based than C++)
fn bar() -> Foo;
var bar : Foo;
It makes parsing easier for both the users and maintainers of the language.
If that's the only criterion then Pascal's syntax, which doesn't have "the most vexing parse" problem either, and for the same reason, is also almost better than anything else.
If Rusty syntax is objectively superior to almost everything else we've come up with, that almost should make us think before blindly copying it.
So, for those thinking “Rusty syntax is objectively superior to almost everything else we've come up with” (I don’t, if only because I don’t believe the syntax of programming languages can be compared on quality without considering the audience), what syntax do you believe it not objectively superior to?
Carbon appears to be auto-generating bi-directional bindings, and since it has the same memory model has no such awkward interactions between non-GC'd and GC'd worlds like D does.
> Also D objects have a different lifetimes & requirements, which complicates things
Does Carbon actually solve these issues, though? It would be great if it did, but they don't list complete interop w/ C++ as an actual goal of theirs, only enough to make it practically viable for development.
Carbon's memory model is compatible with C++'s[1], so where would you foresee complications? D could have been so much better here if it just hadn't chosen to be a GC'd language. That single choice pretty much kills any easy interop.
The D standard library is heavily tied to the GC. If you want to avoid the GC, you'd have to give up the standard library, and if you do that, you have to give up most of the D ecosystem.
The syntax looks a lot like Rust, though. I'm surprised they made such a break when there explicit goal is to make migration from C++ as easy as possible. Also, Rust (from my biased point of view) is currently on its way to become the standard low-level language, so I'm not too confident that Rust-but-with-OO is enough of a selling point.
> The syntax looks a lot like Rust, though. I'm surprised they made such a break
Convergent evolution. Rusty syntax is pretty close to what you get if you want to make a language look broadly similar to C/C++ while avoiding pathological and/or computationally difficult parsing.
Rust is like c++ but only the new way to doing c++ is huge rust is like subset of c++ and ownership model.
I thing is the right way c++ is harder than rust only because is so bloated.
Carbon seams less bloated "fork" of c++ whit only the new way of doing things, but allow you full interoperability whit all c++, instead of partial and i don't see ownership, i thing is taxing mentally (worth or not depends).
if i work in c++ i totally will use this.
Considering the seemingly endless list of things that deliberately don't break with the c++ legacy, new syntax is almost the only change left. And if you were about to give c++ a syntax reboot, why wouldn't you look at what successful other modern syntaxes are doing? "c++, but in a syntax for people accustomed to rust instead of in a syntax for people accustomed to C" sounds like a perfectly reasonable approach.
Your perception (and mine) that rust is about to become the new default for "true native" is perfectly consistent with this, a language for the rust generation for when they have to deal with the c++ legacy. A legacy that won't be going away any time soon. I suspect that the author (authors?) wouldn't disagree at all with "use Rust when possible, Carbon when you can't", my perception (from a quick glance at the site) is that they are fully aware of the limitations of the niche they have so clearly staked out.
C++ has virtually zero tooling and the committee is not interested in ever working on that. Comparing CMake to cargo is like comparing fifth century fireworks to the Space Shuttle. I mean we are getting modules that aren't literally copy paste maybe next year.
I read that and I was like WTF, the entire programming ecosystem exists on C/C++ tooling. But from your perspective its modules/cargo that is the tooling?
That is IMHO an odd viewpoint. As someone who despises the way cargo works, and hates not having long term explicit control over my dependencies (going so far as to track and check them in along with build artifacts) I'm not convinced that the recent toss another random dependency that itself pulls dependencies into the build is a good thing.
I like the fact that I have three dozen+ different ways to do regexp's in C depending on my priorities, and that picking one requires cognitive overhead and modifications to source control/etc. Its easy to add a line to a makefile/etc to pull crap off github in C, so its not like this is a hard problem to deal with in C/C++ but its one where the scale of the problem allows for optimization. AKA like the dynamic typing argument, making the programmer think about a problem I believe yields a better solution.
Its also one where i'm not tied to the whimsy of the library author should I decide to fork or maintain the code long after they have gotten bored or rewritten it 3 different times. I can to this day rebuild code I wrote 20 years ago on a modern machine with little effort. Can you say the same about even 10 year old node.js or python code?
Put another way, I spend a little bit more on upfront effort and it pays off long term. And I know i'm in the minority, but its also why repeatedly I've run small teams of a half dozen or so people who's products are ahead of major competitors with teams of 100's+ of engineers.
You can do things the way you do them in C++ in Rust if you want. You could `cargo vendor`, you could fork a repo & depend on a specific commit, etc. It’s up to you have the self-control to do that though and not just shovel random dependencies into your project, that’s all.
Mostly you seem to be complaining that it’s just to add dependencies? (maybe put a ‘sleep’ in your bash prompt or something?) and maybe that the Rust ecosystem doesn’t have as many duplicate libraries as C++? (of course it doesn’t?)
The problem is that cargo gets in the way (as does rustc) if you try and use it in anything other than the simple import this dependency mode. I spent a hell hole of a day or two, trying to pick up a dependency outside cargo because it didn't behave in a way that meshed with the rest of my build environment.
So, yes it handles a couple of the basic cases, but then your out of luck, stuck in a version hell/etc because rustc and cargo are so tightly integrated and the flags needed to emulate some of the behavior with just the compiler are poorly documented and/or version dependent.
It dictates, you conform (which is basically the rust way).
The problem with the typical rants about C++ is that you guys are outdated.
With Conan you can consume over 1,000 packages directly from build systems and with way more control than what Cargo seems to offer. Take a look. I did use it for a while and compared to 15 years ago things are way better now.
The problem isn't that Conan exists, but that other competing solutions are just as popular which results in fragmentation (for instance vcpkg, and cmake can also directly pull in external dependencies now). In the Rust world there's just Cargo.
In the world of build systems, I think most people want a little more consistency and a little less innovation. Sometimes a tool should just do its job and broadly resemble other tools in the space.
Fragmentation is not the problem. The future of C++ is to have metadata exchange, at least the way I see it.
This means that packages can be compiled with any build system, the one that fits you better. In the event that you cannot find a binary that fits you, your package manager can compile on the fly. There are also solutions to keep binary artifacts in Conan. This means that most of the time you can consume pre-made packages in vcpkg/Conan for casual consumption but you can still have binary repositories with fully customized builds for all your permutations of compilers and systems and debug/release. Do not forget this is a hard problem, we are talking to compilation to native, sometimes you need full speed and a custom compilation, not about portable Java bytecode.
But you can still set up and tweak recipes in Conan and upload to your binary repository (what we do at my company).
However, none of these things tie you to a build system, since conan can generate .pc, .cmake, MSBuild, XCode and way more metadata to consume those packages.
You can scale from simple to fully customized. For example before we had a libcxx that we compiled ourselves and pointed all deps and patched packages and could build something with like twenty-some dependencies with that customized libcxx optimized for us. Can you do that with Cargo? Serious question, I did not make extensive use of it.
However for simple uses you can just drop a conanfile.txt and conan install your profile and start to consume your packages. All of this works with CMake, but if I want to use Meson build system or SCons, Make and others I can do it as well. Look at the generators page: https://docs.conan.io/en/latest/reference/generators.html
I do not think fragmentation in build systems is even a real problem anymore because the "not fragmented but simple" philosophy leaves many things out of the box, such as compiling something custom when you really need it.
The system is very flexible. True that the learning curve is harder at first, but much simpler than it used to be in the past.
I can have full projects, not even with Conan, just with simple Meson wraps (Meson wraps are source-only dependencies though) pointing interdependencies to the same version of a library with a very reasonable amount of work: sometimes a single switch in the options, sometimes a small patch that you can keep in your subprojects/ directory or somewhere else.
I can easily generate .cmake and .pc files from Meson itself without trouble, which are two of the most used build systems. But if on top of that you build a Conan recipe then you can have many consumers of your packages for free.
It is nice to have a tool that is more ore less streamlined sometimes, but build systems is a difficult topic and probably there are some that do a few things better than others: cross-compilation, linux tweaks, generating VS solutions for you if your company uses VS, XCode or whatever. It is not bad to have a choice as long as you can interchange.
I would say it is even better than having the one-size-fits-all thing and later when you want to go to the real native stuff then you discover that your tool is too basic and cannot switch.
Besides having lsp (language server protocol), Visual C++, CLion and others, I have been successfully using CMake/Meson paired with Conan and I can tell from experience that it is amazing what you can achieve.
Someone will say Cargo or whatever, which is nice and simple. But with these tools you can choose all details and optimizations as well, something that other tools just hide. But you can still keep it simple with a conanfile.txt for your dependencies and the stock add_executable etc. in CMake/Meson and get done with it. If you feel CMake is subpar (bc its syntax and DSL are terrible, I agree with that) then you can use Meson. It works pretty well.
> C++ has virtually zero tooling and the committee is not interested in ever working on that
This sentence makes no sense at all:
1 - Tooling does not stop to the build systems
2 - The tooling set in C++ (and C) has been built over decades. It is indeed not a single shiny CLI cargo-style but it several order of magnitude bigger and more powerful than anything you will ever find in any other programming language: memtracers, profilers, thread sanitizers, debuggers, disassemblers, static analyzers, packages managers, bindings generators, ABI checkers, crash analyzers, loggers and I am sure I forget still many others.
Most of the tools you mention work below the language level, and thus work automatically for non-C/C++ languages too (or at least LLVM-based languages).
Hahaha you have zero clue. C++ has the best tooling in the world. From static analysers to best in class debuggers to best in class performance profiling tools etc. No other language comes even close.
Most of the tools you mention are actually language agnostic (debuggers and profilers). And static analyzers are much more important for C and C++ than other languages.
Java has far more extensive tooling in all the categories that you've mentioned. I don't know if it's "the best tooling in the world", but if I had to make an educated guess, I'd bet on Java - and I don't even like it as a language.
> Comparing CMake to cargo is like comparing fifth century fireworks to the Space Shuttle
You are wrong here. Cargo serves a set of fixed "this-is-how-to-do-it" thing. In C++ you can build anything. I do not mean it is better, but C++ software already exists and that is the solution that it works better for it. :)
> and the committee is not interested in ever working on that
Regarding C++. IMHO - it’s not getting intrinsically better. More complex. Easy things become a bit less verbose, but the hardest things remain as hard and the compiler is as unhelpful as before.
I agree C++11 and it’s successors are sugaring the language to be a lot nicer but fundamentally nothing has changed.
Rust is fundamentally better in it’s compiler warnings (they are actually helpful), and contains specific solutions to the things that are hard and bite you in C++.
C++ is not going away and it’s my main professional language but Rust does have features that are better.
Fundamentally, it has smart pointers and std::make_unique now, which means I never have to touch a raw pointer in most of my code. They can even be adapted to wrap Win32 objects. That's a huge improvement and I don't mind using C++ for new projects now.
I had the same question as you so I checked. C++ 11 standard was released in 2011 of course. Rust development started in 2006 and Mozilla announced it officially in 2010.
It's a bit weird to take the release date for one, and the start of the development for the other. By that measure, the first pre-alpha (!) release of Rust was in 2012; the first stable release in 2015. On the other hand, the first RFC for C++0x was in 2008.
Rust 1.0 is 2015. Hence this is sometimes referred to as "2015 edition" in Rust's edition system.
But the sort of people who are here to tell you about how great C++ is will say well, actually Rust existed all the way back to 2006 as Graydon's personal project. There were no numbered releases until Rust 0.1 (after C++ 11) and modern features like Traits don't appear until much later, but sure, in this sense Rust existed in 2006.
As far as I'm concerned, C++ is there for legacy purposes only.
There are some nice frameworks and tools using it, sure. Yes, you are required to learn it if you are studying CS.
Any serious new development today is done using more modern languages such as Rust (i.e.: the linkerd service mesh proxy [1] for encrypted pod communication in a k8s cluster).
As even the Linux kernel is slowly transitioning to using Rust [2],
it's only a matter of time before an inflection point is reached and it goes mainstream (if not already.)
To be fair, parts of my work codebase are touching on 25 years old, and I work for a startup from 2020. The codebases we're building on have roots in the mid 90s, and the platforms they run on didn't support modern C++ standards for a very long time after that.
So anything including "windows.h" isn't really new development then? Sounds like a strange definition.
I'd say that there is a lot of new projects being started with C++, still way more than there are new projects in Rust, at least if you only count serious ones.
I mean a lot of these things rely on copying old code. AFAIK a lot of new games in bigger studios start by essentially copying the old engine into a new tree.
It really depends on what bit of computer science you are learning.
C++ is definitely past its prime and has been surpassed in many areas by other languages but there are still a bunch of domains where it is the primary language.
How about almost all domains? Everything in the world runs on top of browsers/operating systems/drivers/VMs/networks/embedded systems etc. that are written in C/C++. Not to mention that the tools used to design chips and manufacture them are also written in C/C++. No other language comes even close.
Having C or C++ somewhere in the lower levels of your stack doesn't make them the primary language for your domain. Other wise CPU microcode would be the primary language of every domain.
In fact there is plenty that can be expressed only in C++. A person making effective use of the power of the language finds anything else a huge step down.
Anyone not having fun when coding C++ is doing it wrong.
In C#, nested classes are effectively friends with their outer class, and it's used quite often in practice.
On the other end of expressivity, in Eiffel, every class member is declared as visible to specific other classes; if you want something to be public, you say that it's visible to ANY, which is the universal base class similar to e.g. Object in Java.
what languages you learn at university highly depends on the specific school you are at, the professors, and which companies are donating the most money. it's certainly not a great representation of what is going on in the industry as a whole.
Yes that is true but I'm responding to the up stream comment saying "you are required to learn it if you are studying CS". There is a common perception that computer science degrees are about learning things like C++ but my experience is that most emphasise more abstract skills like data structures, algorithms, complexity, formal program design, etc.
Not at all. Computer science and engineering (I think this is different degrees in US but in Spain it was a BS + Master when I studied) is about algorithms, data structures, big O notation complexity in algorihtms, client/server architecture, hardware and assembly, understanding all the underlying math, networking, even HPC and advanced data structures when you keep choosing specialized subjects, but not learning a single tool for the sake of it for programming.
In fact, it is the least relevant part when you are studying. You learn tools better after you end the degree IMHO.
Hahaha wow. There are more than 5 million C++ programmers out there. Starting new C++ projects every day. I am pretty sure more new C++ projects are started every day than Rust projects. Everything (including Rust) runs on top of browsers/operating systems/drivers/compilers/VMs written in C/C++. Rust code is like a drop in the ocean compared. Maybe in 30 years that will changed? Don’t count on it.
But it's worth investigating what you can do when you aren't tethered to wild inconsistencies and odd behaviors and workarounds because the community is terrified of breaking backcompat.
I'm still in the C++ world for work, and have kept reasonably up to date with things to C++17, but I'm sitting here looking at C++20 and wondering is it really worth the effort...
> I suspect that the author (authors?) wouldn't disagree at all with "use Rust when possible, Carbon when you can't"
That is in fact explicitly stated on the Carbon introduction:
"Existing modern languages already provide an excellent developer experience: Go, Swift, Kotlin, Rust, and many more. Developers that can use one of these existing languages should."
> If you want to use Rust, and it is technically and economically viable for your project, you should use Rust. In fact, if you can use Rust or any other established programming language, you should. Carbon is for organizations and projects that heavily depend on C++; for example, projects that have a lot of C++ code or use many third-party C++ libraries.
> Rust (from my biased point of view) is currently on its way to become the standard low-level language
The evidence seems to suggest the opposite. Other than a lot of talk on programming fashion publications that are always more aspirational than representative (such as this site) Rust seems to have reached 0.3% of the market [1], up from 0.1% a couple of years ago [2], and while that is ok growth, programming languages with few exception tend to reach, approach, or at least point toward their all-time peak market penetration around age 10, and Rust is already 7. Any language could, of course, be an exception to historical trends, but there's nothing to suggest that is the case.
More anecdotal adoption stories are just as bleak. Even at this relatively advanced age, many companies dabble in Rust — as they did in, say, Haskell — but not many established companies have yet to really bet big on it.
The only positive is that among the low-level languages discussed on aspirational sites, Rust is, indeed, the most talked-about language, but history also suggests that that is a very bad predictor of long-term market success.
> programming languages with few exception tend to reach, approach, or at least point toward their all-time peak market penetration around age 10
Notable exceptions from the links you've provided:
C#, Java, Go, PHP. All appear to have an upward trajectory today.
Javascript has also seen a similar penetration boost when nodejs came on the scene.
With rust looking to get integration both into the Linux kernel and GCC, that points to some pretty positive things for the language's penetration. Particular in the embedded world.
They might have an upward trajectory, but they're not posed to break well beyond their respective records. With the possible exception of Python, how popular a language is at age ten is a reasonable rough indicator of how popular it's ever going to be. At its current growth rate Rust would reach 1% market share at age ten. Again, there can certainly be surprises, but I think it's weird to say that actual current evidence clearly points to success for Rust. On the contrary, to become a success it would need to buck the trend and be quite a surprise. So it could happen, but I don't see much to support the claim that this is what's currently happening.
> With rust looking to get integration both into the Linux kernel and GCC, that points to some pretty positive things for the language's penetration.
I agree that it shows that the language is taken seriously and isn't dismissed as a possible option, and that that's very good. That indicates that the language isn't an immediate irredeemable failure, but I don't think it's an indicator of future success.
> That indicates that the language isn't an immediate irredeemable failure, but I don't think it's an indicator of future success.
I'd simply point to the fact that there are very few languages that have tried to get into the same space that rust exists in. Even something like D came with an optional GC which has pulled it out from consideration for things like the kernel or embedded devices.
When you say "most languages are peaked at 10 years" I'd simply point to the fact that rust is substantially different from most languages. It's not tackling the same market spaces. The ones it is hitting have been slow moving for a while now.
Major problem with GC languages is that it is horribly to link against libraries that ships with a GC. Lets say I want to use 10 libraries, if each has their own GC then my program is now running with 10 GC's each trying to optimize itself, which isn't a tenable situation.
So system level libraries has to work without a GC, even though system level programs can work fine with a GC.
For java the virtual machine provides the GC for everything, but then you can only use JVM libraries and not libraries in other languages.
The reason C and C++ libraries can easily be included in basically any other language is that they don't have a GC, so there are no such issues, just call the functions and things works fine.
> Major problem with GC languages is that it is horribly to link against libraries that ships with a GC.
I'm curious which GC languages do this. The most popular ones that come to mind for me are anything on the JVM, JS, and Go, and I've never heard anyone point this out about them.
Every language with a GC has this problem. If you want a library to be used in both Java and Python you don't write it in either Java nor Python, you write it in C++ or another language without a GC and import that to Java and Python. Trying to import a Java library in Python or vice versa is horrible, since GC's are very hard to work with from outside the language ecosystem.
I don't know about Java, but it's trivial to import a .NET library in Python with a high-level mapping that takes care of everything GC-related automatically:
But this is exactly the point, it is possible, but once you import such library into Python, you are running both Python runtime and .NET runtime, both having their own GC implementations and many other processes.
Libraries work fine in GC languages if they're written in that language. But you can't easily take a library written in Java and import it into your Python project (you can do it, but it's not efficient, and the more languages you include the less efficient it gets). Whereas libraries written in C/C++/Rust/etc can have binding in every language without issue. Consider libraries like zlib or curl and SQLite that are ubiquitous is across every language ecosystem. Those are the libraries that need (well, greatly benefit) from being written in a non-GC language.
But every language needs to get a foothold within its hype period. In a few years the hype for Rust will die down, at that point you wont get new blood unless they are forced to learn it so it will be hard to grow.
Programmers are forced to learn C++ since many jobs require it. Students were forced to learn Python since teachers choose it as a language at universities. You need some reason like this for a language to thrive after its hype cycle is over, and currently there are no such reasons forcing programmers to learn Rust and it doesn't look like there will be any within a few years either.
Except I didn't say "most languages are peaked at 10 years"; I said virtually all languages reached or neared the ballpark of their peak at age 10, from the most to the least successful ones, and those include C, C++, and D. I think Python might be the only counterexample. So it's always possible that some other language would be another exception, but there's nothing today to indicate that Rust is gearing to be such an exception or that it is substantially different from all the languages in all domains that have exhibited that behaviour.
I do agree that it's more likely that Rust is an exception than, say, Scala or perhaps even Go, but the same would be true for, say, Carbon. I.e. while the likelihood is higher, there's nothing at the moment that would indicate that's what's happening.
Obviously Rust has garnered more enthusiasm among PL fans than D ever did, and its peak would probably be higher, but technical enthusiasm and hype is very weakly correlated with long-term success in the world of programming languages. Most charitably you could say it's a necessary condition, but it is very clearly not a sufficient one.
Rust very much could still fizzle. If it does, it will be because it failed to change to be adoptable by more users. All existing users are tolerant of niche qualities. If it succeeds, the programmers who already know it will constitute less than 2% of the total, and the 98% will have picked it up after it changed to be more readily taken up.
If it fizzles, current users will always be at least 70% of the total.
So, if you want it to succeed, you will need to welcome the changes that can get it there.
I think all new languages have some challenges that would make it very hard for them to become as popular as older languages (none of the top five languages is under twenty years old).
For one, we're long since in an era of diminishing returns — new languages have a smaller ROI compared to incumbents than the incumbents had to the languages they replaced — while the cost of a switch is the same if not higher (because codebases are larger). So switching to a new language is just not as profitable today as it was twenty years ago.
For another, the market is more fragmented today than it was, say, 15 years ago. For example, while Java is not the only game in town on the server as it was in, say, 2003-2006, no other single language shows any signs of becoming as dominant as that either. Some use Python for server-side applications, some use JS, some use C#, some use Kotlin, and some use Go. There is no single language that people flock to and so Java is still the dominant server-side language (although for a while PHP seemed like it could be it). So even if Rust does gain actual traction, it's very unlikely to become the standard low-level language. Some may use Rust, some may use Zig, some will use C++, some will use C, and maybe some may use Carbon. The only new language around that seems capable of reaching a popularity similar to ~25 year-old languages is TypeScript.
I also think Rust has a fundamental problem specific to it, and that is that it's a complex, rich, language. Rich/complex languages have never been super-popular, and while C++ is arguably more-or-less as complex as Rust, it wasn't when it gained its market share (only to lose much of it shortly after).
Language complexity is a poor measure. Better is the complexity of using a language to achieve an aim. C and Pascal are pretty simple as languages, but they make it substantially more complex to complete a task, because they lack the expressive power needed to help any.
C++11 is substantially more complex than C++98, but much simpler to program with. Rust is both simpler than C++ (at surface level, because it leaves behind cruft C++ cannot) but more complex because it makes greater cognitive demands (to satisfy the borrow checker) and also because it lacks powerful features C++ offers. C++ is better able than Rust to package semantics in a library and deliver that to users on command. But Rust is way, way better in that way than C.
I don't think rust is headed to be the norm, but I don't think it should be compared to most mainstream languages. It's not python/php/ruby.. it's a very difficult niche where a lot of efforts failed flat.
>programming languages with few exception tend to reach, approach, or at least point toward their all-time peak market penetration around age 10
How are you coming to this conclusion? I can think of more counter examples than actual examples (Almost every language on the top 10 aside from PHP where close to peak market penetration at age 10).
GP said the standard low-level language. Low-level code will always be a much smaller percentage of all code than the heaps of web apps our industry is shitting out on a daily basis.
Thus it would be completely reasonable for the de facto sysdev language to have a small market share overall(unless like for C/C++ there is a lot of legacy stuff to maintain) . Your sources don't shine any light on this at all.
I think looking only at the number of dev jobs leaves too many potential confounding factors to be useful. For instance, how many C/C++ jobs are actually companies who need those devs to move away from C/C++? What's the overlap? How much of the C/C++ share is maintaining legacy code vs starting new projects? Sure the data says something about it, can we draw any conclusions from it other than precisely the numbers you listed? Not really, not without more detailed data.
One thing I would welcome is specifically looking at new sysdev projects over time and what languages they're in.
To be clear I'm not taking a view on whether Rust will become the standard. I really don't know, and I've yet to see anything convincing me one way or the other.
Different metrics tell a different story. For example GitHub pull requests [1] are C++: 2.60%, Rust: 2.09%, C: 1.43%, with a clear trend showing Rust ahead of C++ next year. Or you could look at the Stackoverflow survey of languages used among professionals [2], which gives C++: 20.17%, C: 16.7%, Rust: 8.8%, with rust gaining 1-2% each year.
There's no best metric, they're all biased, you need to consider a few different ones. Otherwise you won't notice when you've stumbled upon one with with an extreme view.
Combining C and C++ in language stats is debatable, they should IMHO be measured separately. When grouped as a language category, "C/C++/Rust" is slowly becoming more common.
I assume 1 is pulling only from github.com public projects. Many companies A: don't make their code public, B: probably use github enterprise/other hosted solutions (esp including not git based)
Yes, public github repos, stackoverflow survey respondents, devjobscanner offers, google searches, etc are all skewed in some way.
It's very hard to qualify the effect of those biases though: for example how does the public/private repo ratio differ between languages ? Good luck giving a trustworthy answer to that. Apart from looking at lots of different source kinds, one thing that's fairly trustworthy is the trend of a specific language in a specific source.
On that topic, looking at the "SO questions" metric of the first link, C and C++ both have a strange regular spike in the last quarter of each year. I attribute that to new CS students flocking to SO at the beginning of their term. Another fun trend to look at is the hourly google searches over a week: the weekdays / workhours spike is much more pronounced for some languages than others.
Sure, but even low-level languages have tended to reach the ballpark of their all-time peak market penetration -- however high or low it is -- around age 10.
"... around age 10." C++ (not to mention C)? IIRC, I remember seeing B.S.'s "C with Classes" appear in ACM SIGPLAN Notices in the early 1980s -- 40 years ago. I don't think it hit its peak 10 or even 15 years after its early development. Given that it's C++, that's a pretty major exception.
C++ was huge in the 1990s, C++'s share is probably smaller today than back then since so much of programming has moved over to managed and scripting languages.
Key players like Microsoft and the Linux Kernel developers are only just beginning to pick up Rust. It's been considered promising, but immature for much of it's lifetime, and it's only recently gotten to the point that it's considered mature enough for core infrastructure projects (which are really it's forte) in the last couple of years.
> on its way to become the standard low-level language
It will take a very long time for Rust to get even close to the huge amount of C++ code out there. There are more than 5 million professional C++ developers employed around the world today. And that number is increasing. Don’t get me wrong: I like Rust and other attempts to move beyond C++. But don’t underestimate how much C++ code has been written the last 30+ years. And new C++ projects are started every single day. There are probably more C++ projects started every day than Rust projects. So anything that makes it possible to move beyond C++ while being 100% interoperable is good news.
Carbon is not trying to be 100% interoperable with C++. It's trying for some fuzzy notion of "good enough" - that's really not very different from what Rust is trying to do with cxx-rs. Yes there are serious challenges and I've described them here, but they're not impossible to address while staying with Rust.
Oh, that's excellent and interesting news - not a fan of exceptions. I'm not sure how that's going to work with interop when libraries rely on exceptions though. Where did you hear about this? I'd love to know more.
I don't know about it becoming the standard LL language yet. There's a lot of memory management in low level programming, and peppering everything with unsafe seems like it'd be tedious. I'd rather just write in C to begin with.
I'm interested in seeing how things are handled with the Linux kernel's rust support, if it ever becomes more than a proof of concept. That will be a good viability test.
Designing a language to interop well with a single language is short sighted in my opinion. I want a clean ffi that I know will be able to iterop with Swift, Typescript, C#, C++, C, python etc... In my current project I'm currently using Rust/protobuff to do all of this and it rarely gets in my way of how I want to do things.
This language has “zero-cost” with C and C++, “minimal cost” with anything else that is compatible with those ABIs, and “moderate cost” with everything else via protobufs :P
It's a bit of an exaggeration, but it's close. If you count all Google's C++ code base (google3 + open source) it's fairly close to one billion. If you count regardless of language, I believe it's ~3B.
There are many billions of lines in Google's monorepo[1], summing well over 80 terrabytes of data. The paper below is from 2016, and the repo has only gotten bigger since then.
Exactly how many of them are C++ is not disclosed, as far as I know. But it is public knowledge that C++ is the biggest of Google's primary languages (C++, Java, Go, Python, Javascript, and so on).
> In otherwords, what carbon can do that Rust can't do, is take a C++ class with a `foo` method and call that method. Or create a class with a `foo` method and call that method from C++. Probably one of the biggest hurdles to get over in C++ interopt. Most don't do that, instead you'd make a C function binding and struct and move data/invoke functions through that.
cxx is great but it isn't anything close to what cogman10 is describing.
It actually can't ever be, because C++ has move constructors and Rust deliberately doesn't, so you can't for example return `std::string` from a Rust function by value.
Bit hard to follow but as far as I can tell those are pinning the C++ types and wrapping them in some other object that allows a move constructor to be called on them to move them to some other pinned location.
It still doesn't let you natively move them, and if you have to wrap them in something you may as well just wrap them in `Box<>` and not move them, which is what cxx does.
I guess maybe it makes a difference for passing things into existing C++ interfaces?
I tried cxx and walked away somewhat disappointed.
One problem is that it's hard to understand the code. The whole thing is one giant proc macro, which is by itself tricky to run and debug. Also it uses techniques like implementing Deref to simulate inheritance which makes it even more confusing.
The main problem is the difficulty in extending it. Support for std::string and std::vector are "baked in" in a way that does not generalize. I tried to add support for std::wstring and it is quite non-trivial.
Because it is a proc macro it's also tricky to integrate into a build system.
To me it seems like Cxx is "purpose built" which is fine. But after working with it, I longed for a Python script that just populates a template string or something.
I would also wonder about D and Odin, neither of which are particularly successful but both of which are also supposed to be kind of like C++ replacements.
Honestly, the only thing lacking with D (for me) is the lack of good support from Qt (which I think is something Qt should tackle by making the moc multilingual). But I agree with Walter. D already did what Carbon is trying to do, but the syntax is easy enough to pick up in a weekend.
> Honestly, the only thing lacking with D (for me) is the lack of good support from Qt (which I think is something Qt should tackle by making the moc multilingual)
it's possible to do Qt without moc even in C++ with https://github.com/woboq/verdigris/, why wouldn't it be possible from D ? it should be even easier considering that D traits allow reflection of member and function names, etc.
You're talking about an entirely different thing. While OP was referring to the current state of D's ecosystem and the impact that missing key frameworks have on hindering adoption, you're arguing about the theoretical possibility of writing a framework with a language, which really does not address OP's point.
No, you are misunderstanding their point. If the problem of using Qt from D is that you need the MOC, then the fact that you can work around the need for MOC and use Qt without it seems quite relevant?
The initial complaint was that it did not have "good support." I think it is fair to say that having to spend a significant amount of effort to work around a lack of support is not "good support."
Indeed, that is what I meant. I would like to see Qt allow some sort of language-abstracted moc so I can just install Qt and a set of Qt bindings and then use them. Just because I can work around the moc doesn't mean that I can easily and productively use Qt from D.
But .. how would that work ? What does "language-abstracted" means for something which is specifically about a language ?
E.g. moc in c++ looks for your classes with a Q_OBJECT macro to generate the matching reflection & metaobject data in a .cpp: how does that work in a language that doesn't have preprocessor macros, or maybe even classes, e.g. Scheme or some BASIC dialect ? In addition, moc is only necessary for languages that do not have proper reflection & code generation facilities - if they do, it's entirely unnecessary as the metaobject code can just be generated in-language as part of the bindings you're mentioning. E.g. consider the python Qt bindings: they don't need a moc. Same for D.
dlang would have been a very serious contender to C++ had it been fully nogc, stable & lean. Also dlang unnecessarily suffered low adoption in start due to competing stdlibs, trying to be both Java & C++ at once.
Yes it is very useful addition. Hopefully stdlib will also be fully nogc soon. Of all available options I am most hopeful of dlang. While it doesn't still have taken off it still is improving a lot & has high chances of increased usage. (Python also took years).
It doesn't need to be fully nogc. Not using the parts that use the gc will cripple nothing. You'll know which ones use the gc because they won't compile with @nogc.
There's no "nogc" containers in phobos, or allocators, or an idiomatic way to do safe manual memory management. It expects you to do it the C way. It's also impossible to implement some things because of how D does moving. There's a DIP in the works to change how moving works, but it's overly complicated and bound to introduce even more bugs. https://github.com/dlang/DIPs/blob/master/DIPs/DIP1040.md
Most C++ codebases would be exactly the same with or without a GC. Probably 90% of collective programmer-intuition about memory allocation is either completely wrong or from thinking about a scaling to a point that most products don't get anywhere near.
There is more to performance than allocating memory. In fact some very performance-centric codebases do use a GC like unreal engine.
On the subject of games it always makes me chuckle when I see people complaining about garbage collection but then having 20 calls to malloc in their hot loop. All memory allocation is slow and not necessarily bounded.
I have written code that uses SoA, cache aware metaprogramming, inline asm, SIMD etc, with a GC because I knew I didn't need to allocate often.
On the subject of Java, I'm no fan of it but lots of projects would probably be fine - probably not quite as fast, but not horrifically so. On hackernews we only discuss extremely careful or expertly written code whereas in real life a lot people use C++ because it's what they got hammered into them at university 20 years ago as the fast language.
For example a lot of engineering and finance codebases are written in a very bad style of C++ code that would be improved by not having the programmers worry about memory too much - infrastructural code is more subtle, but most code serves a direct purpose like implementing some model. In these cases memory allocation is merely a means to an end rather than part of some grand strategy (i.e. it's not like writing a library)
Unreal Engine mostly uses GC for game world objects. Only C++ classes that inherit from a special base class and opt-in are subject to GC. If they used GC for everything the performance would be much worse.
I love when people bring up that UE has a GC, if it was written in Java, do you think they would have built a GC on top of Java's GC?
I guess it depends on the GC at that point, 20 mallocs isn't a lot but like the GC in D, it pauses all threads to do it's collection when you allocate. There's also a few games that use C# that have a really bad stutter because of the GC. There's nothing they can do about that though.
D doesn't do it very well. Carbon doesn't require you to write your own interface. There's also problems with extern(C++) not correctly generating the appropriate assembly. Lots of ABI bugs as it's rolling it's own implementation instead of using LLVM.
Zig is to my knowledge specifically designed to have they kinds of use after free that C and C++ have. Their claim is not to “hide” allocation by requiring everyone to implement manual retain and release.
Zig is at most, as safe as a language like Modula-2.
Definitly safer than C and C++ in regards to bounds checking and numeric conversions, but without any language protection against user after free, other than what you would already get with heap debuggers on C and C++.
> Overall, Carbon is making a compromise around safety in order to give a path for C++ to evolve. C++ developers must be comfortable migrating their codebases, and able to do so in a largely automated manner. In order to achieve automated migration, Carbon cannot require fundamental redesigns of migrated C++ code. While a migration tool could in theory mark all migrated code as unsafe, Carbon should use a safety strategy that degrades gracefully and offers improvements for C++ code, whether migrated or not.
> That does not mean Carbon will never adopt guaranteed safety by default, only that performance and migration of C++ code takes priority, and any design will need to be considered in the context of other goals. It should still be possible to adopt guaranteed safety later, although it will require identifying a migration path.
That's very interesting and pragmatic. It would be interesting if they can eventually come up with the same level of safety guarantees via a different path than Rust's borrow checker.
-------------
Since one of their goals is to automatically translate modern C++ to Carbon, I do wonder how well that is going to work in general.
I definitely welcome an alternative to C++ that would be easier to read and understand. That would be a benefit to the world.
The borrow checker is a pretty smart solution pushing checks to compile time and have efficient runtime, so yes, it would be interesting to see if there is an even better alternative. But you can't beat that kind of safety into an old C++ code base, so I am pessimistic for retrofitting.
It's not like PHP is unsafe to begin with like C++, but the language does have a ton of problems, and Meta's massive codebase could only be migrated to another language gradually. Hence, Hack. Better language, better tooling, more productive programmers.
Note that unlike Carbon/C++, Hack is backwards-compatible with PHP. So the migration is somewhat more gradual.
I wonder what would happen if Security became a compiler flag?
For instance, just like the -O1 or -O3 flags work for optimization, something like a -S1 or -S3 would be really useful.
To me, there are lots of times when I just need to get an idea into code. Then there are times when I need to make sure that code just works™.
Having different compiler flags would really make that nice, and for devops, allow anything pushed to production have to complete a -S3 successfully first.
Sorry, I wasn’t as clear as I meant to be. I was specifically thinking about things like Rust lifetimes being a compiler warning level instead of an absolute.
You mean that you want your compiler to say "I know that this will sometimes fail, but I'll let you burn yourself unless you enable a flag"? Should it also have a flag to say "Told you!" when it happens? xD
I'm as tired as you by these cosmetic successors. But for my part I think C++ has already been replaced, and to great benefits. I couldn't thank the people building Rust enough.
I still haven't seen a cross-platform production level GUI app written in Rust.
All the time, it is C++ these companies use for these apps, especially having millions of users and generating multi-millions or hundreds of millions of dollars.
"I still haven't seen a production level numerical weather prediction app written in Rust.
All the time, it is Fortran the government uses for these apps,..."
I vacillate as to whether the best response is: "Who cares?" or "give it time"? First, if C++ actually is better for GUI apps, then more power to C++ (do you have some evidence this is the case?). That doesn't mean their aren't other niches to fill for other languages, like Rust. Next, Rust is a relatively new language. It may end up that it's really great for GUI apps, but again it doesn't have to be. It can be great at other things.
GP mentioned C++ being replaced by Rust - I'd say that a replacement should be as capable as the thing it replaces, so if that's the claim, then Rust should be at the very least OK for GUI apps. If it's not, then that's also okay, but let's not call it a replacement then. :-)
I'm personally excited to see how all those languages will influence each other!
I don't think I understand - where is any kind of framework mentioned? And even if frameworks were mentioned, I think it's a fair comparison to say "language A has battle-proven / easy-to-use / etc. framework to achieve X, but language B doesn't".
From the moment it can interact with the underlying operating system? C++ doesn't specify any GUI framework as a part of the standard, and yet people manage to write GUI apps. Rust should have the same capabilities of calling into the OS, but GUI apps seem to be slow to appear there - it may be because it's still early days, or because Rust isn't super pleasant to write GUI apps in.
I'm also pretty certain we shouldn't be that pedantic about the word "replacement". Perhaps it's fine for a thing to be a "replacement for the GP" (which I think he/she is pretty clear about) or a "replacement for many uses" or for "all new uses", without being a "complete replacement"?
What's getting so weird about about the tenor of the current anti-Rust backlash is that 1) when the discussion turns to safety, it's "Hey, dude, don't harsh my buzz", but 2) when the discussion turns on the what the person meant, the Rust community's well-founded enthusiasm is interpreted in the harshest, most uncharitable, light.
But it is a cross-platform GUI app, which the post was about. Granted, it is (or was?) experimental (so not production-grade), but the PoC for GUI app in Rust should be there (assuming they didn't use something else just for the GUI, I'm not an expert on Servo).
AFAIK this is the only one what is compatible with C++ at the source level. As much as I like C++ I think it has a lot of accidental complexity built in and the syntax is too verbose at times. I also think that a lot of people (me included) do not want to switch to something like Rust immediately because of the existing C++ code and the friction of having to make it interoperable. So I believe this is actually a great experiment. Will see whether it works or not, but I hope it will.
I feel the same way. Add to that the plethora of "C++ bad" memes that every software engineer is throwing around as soon as they get a whiff of anything remotely resembling C++ - I've made my peace with the fact that I'm in a tiny minority of people who think it's generally a great language that is worthy of further development and improvement instead of abandonment.
Although I still think it should be possible to make some things obsolete in C++. The technical debt is real, and the language can hardly improve if old codebases are slowing down the evolution of the language.
I already wrote several times that I would like a new C++-like language, but without the complexity of C++. D, zig and rust are fine but they're not simple languages to use. I want the nice things of C++ (string, a few containers, a bit of syntax sugar, the most useful std stuff), with enough simplicity from python or C.
I just use the simple parts of C++, and I only want those parts. I just want the KISS simplicity. Carbon is not that, neither is rust zig or D.
> since they're heavily influcened by the Rust syntax, why not just learn Rust instead
Interestingly, when looking at their code samples, the vibe I get is more "Go++". Using `var` for variable declarations, letter casing for visibility, explicit returns even at the end of functions, using the "package" keyword for namespacing, etc. I do see some superficial syntactic similarity to Rust, like using `fn` for functions and `->` to annotate return types, using `:` for type annotations for variables, and semicolons seeming to be required at the end of lines, but overall it doesn't really _feel_ that much like Rust to me, I think due to how imperative it seems. Given the use of `class` and `let/var` seeming to be const versus mutable bindings, I'm wondering if the Rust resemblance is actually just transitive through more of a resemblance to Swift, although I don't know Swift well enough to know if this is an accurate explanation.
> but since they're heavily influcened by the Rust syntax, why not just learn Rust instead.
That's pretty extensively covered in the link, but here's a relevant snippet:
"Existing modern languages already provide an excellent developer experience: Go, Swift, Kotlin, Rust, and many more. Developers that can use one of these existing languages should. Unfortunately, the designs of these languages present significant barriers to adoption and migration from C++. These barriers range from changes in the idiomatic design of software to performance overhead."
> Interoperate with your existing C++ code, from inheritance to templates
Very important. A C++ alternative and successor needs to be compatible with C++.
The rest of these so called C++ alternatives are either rewriting everything in their own language and causing chaos with their own incompatibilities with their language features and realising that it wasn't a good idea after all to do such rewrites after being sold vacuous promises and language feature snake oil, but only to show pretty syntax sugar.
Unfortunately, the hype squads will just attempt to drown out other alternatives like this one; even if it works with the existing C++ ecosystem.
Why use Rust syntax (fn, x:Type, ...)? Syntax is one thing that is not so well-designed in Rust (in my opinion). Also, with the stated goals, it seems a bit unnecessary to overhaul C++ syntax, but then I found no explanation why syntax was changed. So what's wrong with C++ syntax if your goal is a successor of C++?
This now looks to me like a Rust-- instead of a C++++, which is a picture they might not want to give rise to. Because then I'd rather use Rust instead, which then feels like the real thing(tm).
[EDIT: If you think about downvoting, maybe answer instead as I am genuinely interested in this syntax question. I am not trying to be negative, it was just an observation and a question.]
It's not just Rust syntax. `name: Type` is the syntax used in TypeScript and Python type annotations (also Ocaml, which is probably where Rust got it from). Golang drops the colon, but still keeps the name first.
As for what's wrong with `Type name(constructor, args)`? A lot of tooling wants to be able to parse "mostly-valid C++", like IDEs and compiler diagnostics. Sure, once clang's type inference is finished, the lexer hack and most vexing parse aren't problems, but when the program isn't complete, parsing isolated fragments is impossible, and that limits the amount of useful tooling the language can have.
The syntax `name: Type` is also friendlier to type inference as you generally have a token indicating a declaration. If you have `var x: Type = …` then you can just omit the type and let inference do its job.
Even better, when you start having more complex patterns on the left-hand side of `=`, you can type annotate them as you want. Hypothetical syntax would be:
var (x: f32, y, [z1,z2,z3]) = SomeExpression();
That's harder to do when you have a type declaration on the left imho.
On the other side `name:Type` doesn't allow an IDE to suggest a name based on the type, because you type the name first. Also setting values looks pretty confusing. I claim writing the type before the name is much more readable. Compare
A blog post by Roman Elizarov (Kotlin designer) on the observation of types following the variable name [1]. It mostly states that having consistent length prefixes (fn, val/var) makes the code more readable than arbitrarily long type identifiers (in the eye of the beholder). Not scientific, but interesting.
Fixed prefixes also make a codebase significantly more grep-able. Want to find the definition of the function named `foobar`? Search `fn foobar` and that will always match, no regex required.
> The best way to address these problems is to avoid inheriting the legacy of C or C++ directly, and instead start with solid language foundations like a modern generics system, modular code organization, and consistent, simple syntax.
That last part seems to imply that the authors don't consider C++ syntax to be a good foundation for a modern successor language, so they chose to change it. As to why change it in a Rust-like direction I'd imagine that it's both because it's what fashionable at the time and possibly to attract people who are already familiar with that style.
I can't handle [] syntax for generics. It makes code unreadable as far as I'm concerned because it makes it twice as difficult to know if I'm dealing with an array indexer or a generic.
The rest I can excuse but [], I cannot. Same reason I won't touch Nim.
Using function call syntax for array indexing always made sense to me. Functions are mappings from inputs to outputs, and arrays are mappings from indexes to values.
Given that one of the languages that historically used the same syntax for array access and function invocation since day one is BASIC, I would dare say that it's not a complicated concept.
Go authors put out a good post explaining the problem with C syntax and contrasting it with Pascal/Go/Rust syntax: <https://go.dev/blog/declaration-syntax>
C and C++ are infamous for being harder to parse than it's reasonable. C has lots instances of context dependent syntax where code changes meaning depending on what a name is.
You can parse Go without a symbol table, but not C, because stuff like
item *a;
changes completely in meaning depending on the existence of a previous typedef for `item`.
C++ in order to not break compatibility with C has elevated this to insane extremes - there's so much ambiguous syntax in the language.
x = b.get<item>(r);
This expression can either be a function invocation, if `item` is a type and a template method named `get` exists, or else it's a series of comparisons.
item f(r, f);
is also ambiguous: if r and f are types, that's a function, otherwise that's a variable declaration. There's no way to know that unless you have a symbol table, which makes separating syntactical and semantic analysis impossibile at best.
The whole C++ language is full of similar ambiguities, and attempts to fix warts that backfired spectacularly. That's also the reason why writing a C++ frontend is a decade long endeavor that takes lots of people and resources. A full time team of 3 people can probably write a C parser in a few weeks in comparison, and C is big mess too, albeit a smaller mess though.
While I think rust has some serious issues with syntax (and I love rust), the things you've pointed out here are not rustisms, but programming language theory-isms.
x:Type has been used in MLs (SML, Ocaml) and recently TS. Haskells uses x::Type. This usage dates back to at least the simply typed lambda calculus in the 1930s.
fn and fun are used in SML and probably elsewhere. fun is used in OCaml, as well.
I had been thinking about something like this for a long time. There is just too much C++ code out there but C++ (despite many efforts by the standard committee) is still too verbose and hard to make sense of in many cases. So I thought "why not designing a new language that is compatible with C++?"
Indeed, from Python to Rust and newer C++ codebases you usually see CamelCaseClasses (or structs) and then snake_case for functions methods etc, which improves readability.
CamelCaseForEverything is such a waste, maybe they use it for implicit public/private as in Go? And maybe to please existing Go or Java users?
On the road map they have Broaden participation so no organization is >50%, so this has a good chance of not becoming Swiftoogle-Lang.
Also, under "Why not Rust?"
If you want to use Rust, and it is technically and economically
viable for your project, you should use Rust. In fact, if you can
use Rust or any other established programming language, you should.
Carbon is for organizations and projects that heavily depend on C++;
for example, projects that have a lot of C++ code or use many
third-party C++ libraries.
It's moderately annoying to implement because it messes with the calling convention in architecture dependent ways. So it isn't an IR transform, it's N lowerings for N architectures.
Clang and llvm understand them, and you can require them from the front end, but the cost is some backends will hard error on them as unimplemented.
Just to clarify, are you saying that a language’s calling convention is implemented differently per architecture? Or is it that the tail call implementation needs to be implemented in different ways per architecture and that would mess with the required calling convention?
Calling convention covers where values are placed in memory (or stack or registers) by the caller so that the callee can find them. There can be N of these as long as caller/callee pairs agree sufficiently. The instruction set you're compiling to influences the cost of different choices, e.g. how many and which registers to use.
Tail calls mean reusing memory (notably the stack) and arranging for there to be no work to do between the call and the return. E.g. if arguments are passed by allocating on the stack, you can't deallocate after the call, so you have to make the stack look just right before jumping.
If you've got multiple calling conventions on your architecture, they each need their own magic to make tail calls work, so you might have 'fastcall' work and 'stdcall' error. Iirc I implemented it for a normal calling convention on one arch and didn't bother for variadic calls.
I suppose one could have a dedicated convention for tail calls as well, I just haven't seen it done that way. Usually the callee doesn't know and can't tell whether it was called or tail-called.
520 comments
[ 3.3 ms ] story [ 328 ms ] threadWhy, just why would introducing that obvious footgun be appealing? It raises the concern that the language is full of other arbitrary choices hiding dangerous footguns.
Edit:
Strangely, their test suite makes it look like Array is bounds checked and fixed size; there is no test for resizing:
https://github.com/carbon-language/carbon-lang/tree/trunk/ex...
0: https://en.cppreference.com/w/cpp/container/array/at
Mathematicians are probably better suited to using R, Julia, Octave, or Wolfram.
Other languages don't need to replicate this mistake.
Zig: ArrayList
GLib: GArray
Objective-C: NSMutableArray
So List would have been the more Java/Zig way to name it (also Python, etc.)
You probably know that, but just to clarify: it's backed by a single array, reallocated repeatedly, just like std::vector in C++ (although growth factors are different, I think).
Just "List" probably risks that some people will jump to the conclusion that it's a linked list. I'd probably prefer the full "ArrayList". Although personally I'd use something like "DynArray"/"DynamicArray".
var kek: array of int;
setlength(kek, 666); // kek is now int[666]
setlength(kek, 1337); // kek is now int[1337]
The Java Vector features will be out of incubator in the next year or so and unlike the existing Vector, it's actually useful. For context the new vector features are for SIMD support on the JVM.
I only know about it from dealing with J2ME crap where ArrayList wasn't available.
https://en.wikipedia.org/wiki/Finite_field
1. std::vector doesn't have a fixed dimensionality, as would a mathematical vector. A fixed-length array actually makes more sense as a vector.
2. It doesn't provide the operations of addition and multiplication by scalars out-of-the-box (though you can whip up your own). Moreover, in general those operations wouldn't make sense for the elements which can be stored in a std::vector. E.g. neither multiplying bank account numbers by scalars, nor adding two bank account numbers make any sense. It would be good if you modelled them with types which don't allow those operations. Yet storing them in a std::vector makes perfect sense. But std::vector (or tuple) of bank account numbers is not a vector.
2. Operations are not intrinsic to a set, but to an algebra. Why would there need to be any correspondence between the operations of linear algebra and those of banking algebra in order to call an std::vector a vector?
Anyway, as another commenter pointed out, Stepanov himself, who gave this container its name, said that it has nothing to do with vectors, and he wouldn't name it vector, if he could correct this mistake.
> you can construct a vector space out of a set of non-vectors (such as matrices)
A vector is by definition no more and no less than an element of a vector space. Vectors are defined by vector spaces, not the other way around.
If you have a vector space whose elements are matrices, then those matrices are vectors. And they will be written in coefficients in a given base as tuples.
> out of operations other than vector addition and scalar multiplication
You don't "build vectors out of operations like vector addition and scalar multiplication", as in: you don't choose them. You choose the field and dimension, and those operations (vector addition and scalar multiplication) are a consequence.
> you can use vectors for purposes other than constructing vector spaces, also without involving either of those operations
Again, you don't construct vector spaces out of vectors - there are no vectors without vector spaces. And there are no vector spaces without those operations. But yes, you can use vectors from a given vector space in a greater capacity than just as vectors.
An example, which shows the futility of looking at vectors as just tuples: a real number is a vector in the vector space of real numbers over the field of rational numbers.
It's the definition I was given. If you accept that the word "vector" may be given a definition different from the one you give it, you'll need to concede that an std::vector may be a vector.
>you don't choose them. You choose the field and dimension, and those operations (vector addition and scalar multiplication) are a consequence.
You're using the phrase "vector addition and scalar multiplication" in a different sense than I meant. I was referring to component-wise addition between two vectors and to multiplication between a scalar and the individual components of a vector. You could choose different operations to construct a vector space, as long as they meet the requirements of vector spaces.
You used the phrase to refer to the constructing operations of a vector space. So yes, a vector space is indeed constructed out of the operations it is constructed out of. You could have been more charitable in your interpretation of my words, rather than assume I was saying something equivalent to "four-cornered triangle".
A vector is an element of a vector space, basically anything that you can add together and multiply with an element of a field. It has nothing to do with what you wrote above.
[] : https://en.wikipedia.org/wiki/Vector_(mathematics_and_physic...
Link to lecture by Stepanov: https://www.youtube.com/watch?v=etZgaSjzqlU
Furthermore in his book "From Mathematics to Generic Programming", Stepanov says that if he could change its name, he'd have named it "array".
No, because you can't prove that std::vector<T> obeys all vector space axioms[1] for all T, which is good because it's impossible, I can trivially define a T that will break any number of axioms and the cpp compiler will happily let me instantiate std::vector on it.
[1] https://www.math.ucla.edu/~tao/resource/general/121.1.00s/ve...
However Carbon seems to do a whole lot more than DevEx. It’s practically a whole new language that can interop with C++. I don’t see the point in that. Would be great if someone pointed out why I should change my mind.
This doesn't give me much confidence if its Corporate governance rather than open governance.
Disclosure: Former Google engineer who worked sorta adjacent to some of those people.
But yes, I agree, we should have no expectation of support for experimental or beta products.
It is not a joke.
It is a reputation that Google has earned through its actions and inactions.
As shown by https://killedbygoogle.com/ and numerous desperate posts for help [1][2][3] on this and other web sites, Google's "must launch a new shiny thing" promotion culture and abysmal customer service have eroded public trust in the long-term viability of anything that Google creates.
[1] https://news.ycombinator.com/item?id=5523992
[2] https://news.ycombinator.com/item?id=13145927
[3] https://news.ycombinator.com/item?id=31837795
It may have been started by mostly Googlers but they want other companies and individuals to participate
I think this is going to be an uphill battle for them and I hope they win it but I'll be skeptical unless if I start seeing radical (for google) transparency basically immediately.
Also worth pointing out that the language is not immediately worthless even if they fail or only partially succeed in this endeavor!!
Also, for what it’s worth: despite being an ISO-standard language, C++ is still heavily swayed by corporate interests, with most committee members being tied to BigCos. This has the effect of somewhat-necessarily aligning language progress with its most significant users. Without this alignment, the language might be “better” in some respects, but less useful.
- I don't use golang - As an outsider, the governance has seemed unhealthy like with how dependency management was dropped out of no where
However, it has been relatively successful. Dart's success has been more mixed. I am also looking more broadly at projects like Bazel.
Compare C++ <random> or <chrono> against, say, the equivalent functionality in Rust, Go, Java, C#, etc. C++'s APIs are a bit overcomplicated, or at least they look that way if you don't know the various reasons why the C++ standard defined them that way (reasons which are probably not relevant to your use cases).
This always felt eye-rolling false to me. We can't have a better hashmap since we all need to pay for the std::unordered_map's un-needed features like bucket access. We are certainly paying for what we don't use.
Every other adoption of the meaning is misuse of what Bjarne originally meant with it.
These 2 things are C++ core principle, but they are 2 different things.
"You don't pay for what you don't use" means that I you do not use a C++ feature, your runtime performance won't be affected by this feature. For example, non virtual functions are not slower because virtual functions exist.
In our case here, if you do not use "std::unordered_map" and decide to implement your own unordered map, then it is as-if "std::unordered_map" never existed. You are not forced to use "std::unordered_map" and you own map won't be slower because it exists.
"the compiler doesn't generate worse code than if you had written the same by hand", or rather "What you do use, you couldn’t hand code any better", means that if you decided to implement a C++ feature by hand in C++ or C, your implementation could only hope to match C++ implementation. For instance calling a virtual function in C++ will never be slower than a similar handwritten late dispatch implementation.
I was frankly shocked by that goals and priorities document. The non-goals section reads like an open declaration of war against anyone whose use cases for C++ differ from GOOG and NVDA. My interpretation of Carbon is that since GOOG failed to take over the standard in favor of its narrow use cases, that they are building a new language optimized specifically for them.
> I have no idea ... how open to non-Google ideas it will be.
The most-generous attitude to take is that it will be managed similarly to Go. If your use cases and priorities are well-aligned with theirs, then feel free to use it. But while they may listen to third-party feedback, it will be their own use cases and opinions which dominate the language's development.
Why use these stock index abbrevs (or whatever they are) in this context here? GEEZ!
To the topic, it sounds a bit grumpy. If we look at languages and how many evolve... many suffer the phenomenon that they almost all are Turing complete, and try to gain concise (or simple understandable) expressiveness somehow, and then they try to not break compatibility too much to varying degrees - net result: they grow and grow where at one point they feel like too big, too much legacy dragged around (C++), the "one obvious way" lost (Python) when they cater for use case after use case.
Limiting can be good in that regard. So having key goals defined and not to cater to every small new usecase by someone is a valid attempt to not let this happen, so while I dislike Googles power, I wouldn't feel to bad with attempting this by anyone on their fresh language?!
Success for the Carbon Language requires it to successfully be an independent and community driven project. We may not succeed (this really is an experiment), but we're working hard to engage broadly and early in large part because of this being such an important goal and priority for us.
Projects like this have to start somewhere, but can grow and become community endeavors. We are also already seeing strong interest from other companies and organizations in participating in this experiment.
Power C++ Syntax Plus Edition
C&₹π÷×√
In Rust for example, `unsafe {}` blocks are not just "local unsafety". They can freely operate on all memory, so they are infectious and are essentially a marker for "dangerous code below, be extra careful and audit lots".
But if all code can freely interoperate with C++, how do you improve upon C++, apart from relatively isolated features like a better generics system?
To what extend can a Carbon compiler that is deeply aware of C++ semantics mitigate the pitfalls?
You can definitely massively improve upon C++ without touching its actual computation model.
Implementing a coherent vision might lead to a better language even if most stakeholders might disagree with every single change.
> That said, our experience, use cases, and needs are clearly not those of every user. We aren’t pushing to directly build consensus on these points. Rather, this is presented as a vehicle to advertise our needs from C++ as a high-performance systems language.
The point of the non-goals is simply stating things they don't care about, which is pretty reasonable. After all, it's easy to say what you want, but what are you willing to give up for it?
https://github.com/carbon-language/carbon-lang/pull/1363
- I wonder how much baggage had to be maintained for interop. If some of it could be isolated, how did they do it?
- Does this fall into any of the traps that D initially did where it allowed C interop but was, by default, more limited in what C environments it could run in or is this as flexible as C++ for environments?
As for the language itself, I've not had a chance to dig into it too much but I am sad to see that it uses explicit local inference by replacing the type name with `auto` rather than eliding the type completely [0]. While it has its pains at times, this is something I've come to enjoy in Rust.
I also didn't see mention of tooling. Having out-of-the-box build, test, and code formatting would be a big help for establishing community standards / practices, even if the build/test tool might get limited when having to do C++ interop. At least for pure-Carbon libraries it would be a big help!
> Once we can migrate code into Carbon, we will have a simplified language with room in the design space to add any necessary annotations or features, and infrastructure like generics to support safer design patterns. Longer term, we will build on this to introduce a safe Carbon subset. This will be a large and complex undertaking, and won't be in the 0.1 design. Meanwhile, we are closely watching and learning from efforts to add memory safe semantics onto C++ such as Rust-inspired lifetime annotations.
I'm a bit skeptical if they push off lifetime annotations too far.
[0] https://github.com/carbon-language/carbon-lang/blob/trunk/do...
This paper goes into the details https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p18...
http://wiki.call-cc.org/eggref/5/bind#c-notes
https://clasp-developers.github.io/clbind-doc.html
Rusty syntax is objectively superior to almost everything else we've come up with, there's no reason it shouldn't be copied.
Those objective criteria of superiority being?..
Consider this C++ code:
A programmer could make simple mistake thinking that is declaring a variable of type Foo. Carbon eliminates this by having explicit keywords for variable and function declaration. (This style is much more Rust based than C++) It makes parsing easier for both the users and maintainers of the language.If that is Rust's entire syntax advantage, it isn't a very big one.
C++'s most vexing parse issue ceased to be a concern around a decade ago with the introduction of uniform initialization.
Templates
So, for those thinking “Rusty syntax is objectively superior to almost everything else we've come up with” (I don’t, if only because I don’t believe the syntax of programming languages can be compared on quality without considering the audience), what syntax do you believe it not objectively superior to?
You mispelled "subjectively". Rust is a hideous looking language, despite its many other benefits.
Also D objects have a different lifetimes & requirements, which complicates things ( see https://dlang.org/spec/cpp_interface.html#lifetime-managemen... )
Carbon appears to be auto-generating bi-directional bindings, and since it has the same memory model has no such awkward interactions between non-GC'd and GC'd worlds like D does.
Does Carbon actually solve these issues, though? It would be great if it did, but they don't list complete interop w/ C++ as an actual goal of theirs, only enough to make it practically viable for development.
1: "For example, C++ and Carbon will use the same memory model." https://github.com/carbon-language/carbon-lang/tree/trunk/do...
As far as I can tell, there hasn't been progress in untying the stdlib from the GC - https://github.com/dlang/projects/issues/56
https://dlang.org/blog/2019/04/08/project-highlight-dpp/
Convergent evolution. Rusty syntax is pretty close to what you get if you want to make a language look broadly similar to C/C++ while avoiding pathological and/or computationally difficult parsing.
Your perception (and mine) that rust is about to become the new default for "true native" is perfectly consistent with this, a language for the rust generation for when they have to deal with the c++ legacy. A legacy that won't be going away any time soon. I suspect that the author (authors?) wouldn't disagree at all with "use Rust when possible, Carbon when you can't", my perception (from a quick glance at the site) is that they are fully aware of the limitations of the niche they have so clearly staked out.
I have cargo today in C++ via NuGET and vcpkg, and what is great about it, I don't have to compile my depedencies from scratch.
To be fair, if you're using a language that has a reasonable compilation story, this is only every a concern the first time you compile.
I read that and I was like WTF, the entire programming ecosystem exists on C/C++ tooling. But from your perspective its modules/cargo that is the tooling?
That is IMHO an odd viewpoint. As someone who despises the way cargo works, and hates not having long term explicit control over my dependencies (going so far as to track and check them in along with build artifacts) I'm not convinced that the recent toss another random dependency that itself pulls dependencies into the build is a good thing.
I like the fact that I have three dozen+ different ways to do regexp's in C depending on my priorities, and that picking one requires cognitive overhead and modifications to source control/etc. Its easy to add a line to a makefile/etc to pull crap off github in C, so its not like this is a hard problem to deal with in C/C++ but its one where the scale of the problem allows for optimization. AKA like the dynamic typing argument, making the programmer think about a problem I believe yields a better solution.
Its also one where i'm not tied to the whimsy of the library author should I decide to fork or maintain the code long after they have gotten bored or rewritten it 3 different times. I can to this day rebuild code I wrote 20 years ago on a modern machine with little effort. Can you say the same about even 10 year old node.js or python code?
Put another way, I spend a little bit more on upfront effort and it pays off long term. And I know i'm in the minority, but its also why repeatedly I've run small teams of a half dozen or so people who's products are ahead of major competitors with teams of 100's+ of engineers.
Mostly you seem to be complaining that it’s just to add dependencies? (maybe put a ‘sleep’ in your bash prompt or something?) and maybe that the Rust ecosystem doesn’t have as many duplicate libraries as C++? (of course it doesn’t?)
So, yes it handles a couple of the basic cases, but then your out of luck, stuck in a version hell/etc because rustc and cargo are so tightly integrated and the flags needed to emulate some of the behavior with just the compiler are poorly documented and/or version dependent.
It dictates, you conform (which is basically the rust way).
With Conan you can consume over 1,000 packages directly from build systems and with way more control than what Cargo seems to offer. Take a look. I did use it for a while and compared to 15 years ago things are way better now.
Either that, or we get a box of surprises in each build.rs script.
This means that packages can be compiled with any build system, the one that fits you better. In the event that you cannot find a binary that fits you, your package manager can compile on the fly. There are also solutions to keep binary artifacts in Conan. This means that most of the time you can consume pre-made packages in vcpkg/Conan for casual consumption but you can still have binary repositories with fully customized builds for all your permutations of compilers and systems and debug/release. Do not forget this is a hard problem, we are talking to compilation to native, sometimes you need full speed and a custom compilation, not about portable Java bytecode.
But you can still set up and tweak recipes in Conan and upload to your binary repository (what we do at my company).
However, none of these things tie you to a build system, since conan can generate .pc, .cmake, MSBuild, XCode and way more metadata to consume those packages.
You can scale from simple to fully customized. For example before we had a libcxx that we compiled ourselves and pointed all deps and patched packages and could build something with like twenty-some dependencies with that customized libcxx optimized for us. Can you do that with Cargo? Serious question, I did not make extensive use of it.
However for simple uses you can just drop a conanfile.txt and conan install your profile and start to consume your packages. All of this works with CMake, but if I want to use Meson build system or SCons, Make and others I can do it as well. Look at the generators page: https://docs.conan.io/en/latest/reference/generators.html
I do not think fragmentation in build systems is even a real problem anymore because the "not fragmented but simple" philosophy leaves many things out of the box, such as compiling something custom when you really need it.
The system is very flexible. True that the learning curve is harder at first, but much simpler than it used to be in the past.
I can have full projects, not even with Conan, just with simple Meson wraps (Meson wraps are source-only dependencies though) pointing interdependencies to the same version of a library with a very reasonable amount of work: sometimes a single switch in the options, sometimes a small patch that you can keep in your subprojects/ directory or somewhere else.
I can easily generate .cmake and .pc files from Meson itself without trouble, which are two of the most used build systems. But if on top of that you build a Conan recipe then you can have many consumers of your packages for free.
It is nice to have a tool that is more ore less streamlined sometimes, but build systems is a difficult topic and probably there are some that do a few things better than others: cross-compilation, linux tweaks, generating VS solutions for you if your company uses VS, XCode or whatever. It is not bad to have a choice as long as you can interchange.
I would say it is even better than having the one-size-fits-all thing and later when you want to go to the real native stuff then you discover that your tool is too basic and cannot switch.
While not nearly as popular as Cargo (due to being blessed by the core team), Rust still has multiple build tools and package managers.
Someone will say Cargo or whatever, which is nice and simple. But with these tools you can choose all details and optimizations as well, something that other tools just hide. But you can still keep it simple with a conanfile.txt for your dependencies and the stock add_executable etc. in CMake/Meson and get done with it. If you feel CMake is subpar (bc its syntax and DSL are terrible, I agree with that) then you can use Meson. It works pretty well.
This sentence makes no sense at all:
1 - Tooling does not stop to the build systems
2 - The tooling set in C++ (and C) has been built over decades. It is indeed not a single shiny CLI cargo-style but it several order of magnitude bigger and more powerful than anything you will ever find in any other programming language: memtracers, profilers, thread sanitizers, debuggers, disassemblers, static analyzers, packages managers, bindings generators, ABI checkers, crash analyzers, loggers and I am sure I forget still many others.
The other languages benefit of them currently because they leverage LLVM (also made in C++), because their interpreter/VM are made directly in C.
How is it already ? Standing on the shoulders of giants ? :)
CMake, Meson, Waf, Conan, Visual Studio Code, Visual Studio, CLion, Intel VTune, GDB, LLDB, XCode, Artifactory, SonarQube, clang-tidy, clang-format, astyle, Incredibuild...
> Comparing CMake to cargo is like comparing fifth century fireworks to the Space Shuttle
You are wrong here. Cargo serves a set of fixed "this-is-how-to-do-it" thing. In C++ you can build anything. I do not mean it is better, but C++ software already exists and that is the solution that it works better for it. :)
> and the committee is not interested in ever working on that
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p08...
Interoperability effort for modules: https://github.com/GabrielDosReis/ipr
I agree C++11 and it’s successors are sugaring the language to be a lot nicer but fundamentally nothing has changed.
Rust is fundamentally better in it’s compiler warnings (they are actually helpful), and contains specific solutions to the things that are hard and bite you in C++.
C++ is not going away and it’s my main professional language but Rust does have features that are better.
IMO, move semantics and lambda functions have fundamentally changed the way we write C++.
Also, let's not forget that C++11 introduced a formal memory model with cross-platform atomic operations and multi-threading primitives.
Given that c++0x was a decade in the making, by that measuring stick the answer is yes, C++11 does precede Rust.
But the sort of people who are here to tell you about how great C++ is will say well, actually Rust existed all the way back to 2006 as Graydon's personal project. There were no numbered releases until Rust 0.1 (after C++ 11) and modern features like Traits don't appear until much later, but sure, in this sense Rust existed in 2006.
There are some nice frameworks and tools using it, sure. Yes, you are required to learn it if you are studying CS.
Any serious new development today is done using more modern languages such as Rust (i.e.: the linkerd service mesh proxy [1] for encrypted pod communication in a k8s cluster).
As even the Linux kernel is slowly transitioning to using Rust [2], it's only a matter of time before an inflection point is reached and it goes mainstream (if not already.)
[1] https://github.com/linkerd/linkerd2-proxy
[2] https://hackaday.com/2022/05/17/things-are-getting-rusty-in-...
I'd say that there is a lot of new projects being started with C++, still way more than there are new projects in Rust, at least if you only count serious ones.
Yeah, I'd call all of those codebases pretty old at this point.
So new (same-)old development then?
C++ is definitely past its prime and has been surpassed in many areas by other languages but there are still a bunch of domains where it is the primary language.
Anyone not having fun when coding C++ is doing it wrong.
On the other end of expressivity, in Eiffel, every class member is declared as visible to specific other classes; if you want something to be public, you say that it's visible to ANY, which is the universal base class similar to e.g. Object in Java.
In fact, it is the least relevant part when you are studying. You learn tools better after you end the degree IMHO.
Uhm, no. Sorry, thanks for playing, try again.
But it's worth investigating what you can do when you aren't tethered to wild inconsistencies and odd behaviors and workarounds because the community is terrified of breaking backcompat.
I'm still in the C++ world for work, and have kept reasonably up to date with things to C++17, but I'm sitting here looking at C++20 and wondering is it really worth the effort...
This is debatable.
It keeps getting more complex. Whether all the additions are worthwhile remains to be seen.
That is in fact explicitly stated on the Carbon introduction:
"Existing modern languages already provide an excellent developer experience: Go, Swift, Kotlin, Rust, and many more. Developers that can use one of these existing languages should."
> If you can use Rust, ignore Carbon
> If you want to use Rust, and it is technically and economically viable for your project, you should use Rust. In fact, if you can use Rust or any other established programming language, you should. Carbon is for organizations and projects that heavily depend on C++; for example, projects that have a lot of C++ code or use many third-party C++ libraries.
The evidence seems to suggest the opposite. Other than a lot of talk on programming fashion publications that are always more aspirational than representative (such as this site) Rust seems to have reached 0.3% of the market [1], up from 0.1% a couple of years ago [2], and while that is ok growth, programming languages with few exception tend to reach, approach, or at least point toward their all-time peak market penetration around age 10, and Rust is already 7. Any language could, of course, be an exception to historical trends, but there's nothing to suggest that is the case.
More anecdotal adoption stories are just as bleak. Even at this relatively advanced age, many companies dabble in Rust — as they did in, say, Haskell — but not many established companies have yet to really bet big on it.
The only positive is that among the low-level languages discussed on aspirational sites, Rust is, indeed, the most talked-about language, but history also suggests that that is a very bad predictor of long-term market success.
[1]: https://www.devjobsscanner.com/blog/top-8-most-demanded-lang...
[2]: https://www.hiringlab.org/2019/11/19/todays-top-tech-skills/
Notable exceptions from the links you've provided:
C#, Java, Go, PHP. All appear to have an upward trajectory today.
Javascript has also seen a similar penetration boost when nodejs came on the scene.
With rust looking to get integration both into the Linux kernel and GCC, that points to some pretty positive things for the language's penetration. Particular in the embedded world.
They might have an upward trajectory, but they're not posed to break well beyond their respective records. With the possible exception of Python, how popular a language is at age ten is a reasonable rough indicator of how popular it's ever going to be. At its current growth rate Rust would reach 1% market share at age ten. Again, there can certainly be surprises, but I think it's weird to say that actual current evidence clearly points to success for Rust. On the contrary, to become a success it would need to buck the trend and be quite a surprise. So it could happen, but I don't see much to support the claim that this is what's currently happening.
> With rust looking to get integration both into the Linux kernel and GCC, that points to some pretty positive things for the language's penetration.
I agree that it shows that the language is taken seriously and isn't dismissed as a possible option, and that that's very good. That indicates that the language isn't an immediate irredeemable failure, but I don't think it's an indicator of future success.
I'd simply point to the fact that there are very few languages that have tried to get into the same space that rust exists in. Even something like D came with an optional GC which has pulled it out from consideration for things like the kernel or embedded devices.
When you say "most languages are peaked at 10 years" I'd simply point to the fact that rust is substantially different from most languages. It's not tackling the same market spaces. The ones it is hitting have been slow moving for a while now.
https://www.ptc.com/en/products/developer-tools/perc
https://www.aicas.com/wp/products-services/jamaicavm/
https://www.microej.com/
https://www.astrobe.com/
https://www.wildernesslabs.co/
Ah but that isn't serious enough.
I guess battleship weapons control might be something serious,
https://dl.acm.org/doi/10.1145/2402709.2402699
So system level libraries has to work without a GC, even though system level programs can work fine with a GC.
Is this true with Java? I thought it's a single runtime that manages memory in all the code/libraries in your process.
The reason C and C++ libraries can easily be included in basically any other language is that they don't have a GC, so there are no such issues, just call the functions and things works fine.
I'm curious which GC languages do this. The most popular ones that come to mind for me are anything on the JVM, JS, and Go, and I've never heard anyone point this out about them.
http://pythonnet.github.io/
I don't see any reason why something like this cannot exist for Java, if it doesn't already.
Programmers are forced to learn C++ since many jobs require it. Students were forced to learn Python since teachers choose it as a language at universities. You need some reason like this for a language to thrive after its hype cycle is over, and currently there are no such reasons forcing programmers to learn Rust and it doesn't look like there will be any within a few years either.
I do agree that it's more likely that Rust is an exception than, say, Scala or perhaps even Go, but the same would be true for, say, Carbon. I.e. while the likelihood is higher, there's nothing at the moment that would indicate that's what's happening.
Obviously Rust has garnered more enthusiasm among PL fans than D ever did, and its peak would probably be higher, but technical enthusiasm and hype is very weakly correlated with long-term success in the world of programming languages. Most charitably you could say it's a necessary condition, but it is very clearly not a sufficient one.
Rust very much could still fizzle. If it does, it will be because it failed to change to be adoptable by more users. All existing users are tolerant of niche qualities. If it succeeds, the programmers who already know it will constitute less than 2% of the total, and the 98% will have picked it up after it changed to be more readily taken up.
If it fizzles, current users will always be at least 70% of the total.
So, if you want it to succeed, you will need to welcome the changes that can get it there.
For one, we're long since in an era of diminishing returns — new languages have a smaller ROI compared to incumbents than the incumbents had to the languages they replaced — while the cost of a switch is the same if not higher (because codebases are larger). So switching to a new language is just not as profitable today as it was twenty years ago.
For another, the market is more fragmented today than it was, say, 15 years ago. For example, while Java is not the only game in town on the server as it was in, say, 2003-2006, no other single language shows any signs of becoming as dominant as that either. Some use Python for server-side applications, some use JS, some use C#, some use Kotlin, and some use Go. There is no single language that people flock to and so Java is still the dominant server-side language (although for a while PHP seemed like it could be it). So even if Rust does gain actual traction, it's very unlikely to become the standard low-level language. Some may use Rust, some may use Zig, some will use C++, some will use C, and maybe some may use Carbon. The only new language around that seems capable of reaching a popularity similar to ~25 year-old languages is TypeScript.
I also think Rust has a fundamental problem specific to it, and that is that it's a complex, rich, language. Rich/complex languages have never been super-popular, and while C++ is arguably more-or-less as complex as Rust, it wasn't when it gained its market share (only to lose much of it shortly after).
Language complexity is a poor measure. Better is the complexity of using a language to achieve an aim. C and Pascal are pretty simple as languages, but they make it substantially more complex to complete a task, because they lack the expressive power needed to help any.
C++11 is substantially more complex than C++98, but much simpler to program with. Rust is both simpler than C++ (at surface level, because it leaves behind cruft C++ cannot) but more complex because it makes greater cognitive demands (to satisfy the borrow checker) and also because it lacks powerful features C++ offers. C++ is better able than Rust to package semantics in a library and deliver that to users on command. But Rust is way, way better in that way than C.
How are you coming to this conclusion? I can think of more counter examples than actual examples (Almost every language on the top 10 aside from PHP where close to peak market penetration at age 10).
Thus it would be completely reasonable for the de facto sysdev language to have a small market share overall(unless like for C/C++ there is a lot of legacy stuff to maintain) . Your sources don't shine any light on this at all.
C/C++ : 6.17% Rust : 0.29%
This was addressed in one of the linked sources. What would you accept as evidence, then?
1: https://www.devjobsscanner.com/blog/top-8-most-demanded-lang...
One thing I would welcome is specifically looking at new sysdev projects over time and what languages they're in.
To be clear I'm not taking a view on whether Rust will become the standard. I really don't know, and I've yet to see anything convincing me one way or the other.
And there's a ton of those job listings.
Github repos might be a better source of penetration and use.
There's no best metric, they're all biased, you need to consider a few different ones. Otherwise you won't notice when you've stumbled upon one with with an extreme view.
Combining C and C++ in language stats is debatable, they should IMHO be measured separately. When grouped as a language category, "C/C++/Rust" is slowly becoming more common.
1: https://tjpalmer.github.io/languish/#y=pulls&names=c%2B%2B%2...
2: https://survey.stackoverflow.co/2022/#most-popular-technolog...
2: Also skews towards a certain demographic
It's very hard to qualify the effect of those biases though: for example how does the public/private repo ratio differ between languages ? Good luck giving a trustworthy answer to that. Apart from looking at lots of different source kinds, one thing that's fairly trustworthy is the trend of a specific language in a specific source.
On that topic, looking at the "SO questions" metric of the first link, C and C++ both have a strange regular spike in the last quarter of each year. I attribute that to new CS students flocking to SO at the beginning of their term. Another fun trend to look at is the hourly google searches over a week: the weekdays / workhours spike is much more pronounced for some languages than others.
Key players like Microsoft and the Linux Kernel developers are only just beginning to pick up Rust. It's been considered promising, but immature for much of it's lifetime, and it's only recently gotten to the point that it's considered mature enough for core infrastructure projects (which are really it's forte) in the last couple of years.
Lol. Gave me a good chuckle!
It will take a very long time for Rust to get even close to the huge amount of C++ code out there. There are more than 5 million professional C++ developers employed around the world today. And that number is increasing. Don’t get me wrong: I like Rust and other attempts to move beyond C++. But don’t underestimate how much C++ code has been written the last 30+ years. And new C++ projects are started every single day. There are probably more C++ projects started every day than Rust projects. So anything that makes it possible to move beyond C++ while being 100% interoperable is good news.
No, it's clearly not a "fuzzy" notion of interop even in the most uncharitable interpretation. Your assertion is mis-information.
"Seamless, bidirectional interoperability with C++, such that a library anywhere in an existing C++ stack can adopt Carbon without porting the rest."
Support mixing Carbon and C++ toolchains
Compatibility with the C++ memory model
Minimize bridge code
Unsurprising mappings between C++ and Carbon types
Allow C++ bridge code in Carbon files
Carbon inheritance from C++ types
Support use of advanced C++ features
Support basic C interoperability
I'm interested in seeing how things are handled with the Linux kernel's rust support, if it ever becomes more than a proof of concept. That will be a good viability test.
As nice as a greenfield language with a clean ffi would be, "extremely close ties to C++" is Carbon's primary benefit.
Exactly how many of them are C++ is not disclosed, as far as I know. But it is public knowledge that C++ is the biggest of Google's primary languages (C++, Java, Go, Python, Javascript, and so on).
https://research.google/pubs/pub45424/
Kotlin is another such widely liked language that was designed entirely around interop with a different language.
Typescript is a superset of javascript and intentionally short sighted to fill a current need.
https://cxx.rs
It actually can't ever be, because C++ has move constructors and Rust deliberately doesn't, so you can't for example return `std::string` from a Rust function by value.
It still doesn't let you natively move them, and if you have to wrap them in something you may as well just wrap them in `Box<>` and not move them, which is what cxx does.
I guess maybe it makes a difference for passing things into existing C++ interfaces?
Anyway it looks insanely complicated.
One problem is that it's hard to understand the code. The whole thing is one giant proc macro, which is by itself tricky to run and debug. Also it uses techniques like implementing Deref to simulate inheritance which makes it even more confusing.
The main problem is the difficulty in extending it. Support for std::string and std::vector are "baked in" in a way that does not generalize. I tried to add support for std::wstring and it is quite non-trivial.
Because it is a proc macro it's also tricky to integrate into a build system.
To me it seems like Cxx is "purpose built" which is fine. But after working with it, I longed for a Python script that just populates a template string or something.
it's possible to do Qt without moc even in C++ with https://github.com/woboq/verdigris/, why wouldn't it be possible from D ? it should be even easier considering that D traits allow reflection of member and function names, etc.
You're talking about an entirely different thing. While OP was referring to the current state of D's ecosystem and the impact that missing key frameworks have on hindering adoption, you're arguing about the theoretical possibility of writing a framework with a language, which really does not address OP's point.
E.g. moc in c++ looks for your classes with a Q_OBJECT macro to generate the matching reflection & metaobject data in a .cpp: how does that work in a language that doesn't have preprocessor macros, or maybe even classes, e.g. Scheme or some BASIC dialect ? In addition, moc is only necessary for languages that do not have proper reflection & code generation facilities - if they do, it's entirely unnecessary as the metaobject code can just be generated in-language as part of the bindings you're mentioning. E.g. consider the python Qt bindings: they don't need a moc. Same for D.
On the subject of games it always makes me chuckle when I see people complaining about garbage collection but then having 20 calls to malloc in their hot loop. All memory allocation is slow and not necessarily bounded.
I have written code that uses SoA, cache aware metaprogramming, inline asm, SIMD etc, with a GC because I knew I didn't need to allocate often.
On the subject of Java, I'm no fan of it but lots of projects would probably be fine - probably not quite as fast, but not horrifically so. On hackernews we only discuss extremely careful or expertly written code whereas in real life a lot people use C++ because it's what they got hammered into them at university 20 years ago as the fast language.
For example a lot of engineering and finance codebases are written in a very bad style of C++ code that would be improved by not having the programmers worry about memory too much - infrastructural code is more subtle, but most code serves a direct purpose like implementing some model. In these cases memory allocation is merely a means to an end rather than part of some grand strategy (i.e. it's not like writing a library)
I guess it depends on the GC at that point, 20 mallocs isn't a lot but like the GC in D, it pauses all threads to do it's collection when you allocate. There's also a few games that use C# that have a really bad stutter because of the GC. There's nothing they can do about that though.
Definitly safer than C and C++ in regards to bounds checking and numeric conversions, but without any language protection against user after free, other than what you would already get with heap debuggers on C and C++.
But I don't think a re-sugaring of syntax is enough to make people switch.
> Overall, Carbon is making a compromise around safety in order to give a path for C++ to evolve. C++ developers must be comfortable migrating their codebases, and able to do so in a largely automated manner. In order to achieve automated migration, Carbon cannot require fundamental redesigns of migrated C++ code. While a migration tool could in theory mark all migrated code as unsafe, Carbon should use a safety strategy that degrades gracefully and offers improvements for C++ code, whether migrated or not.
> That does not mean Carbon will never adopt guaranteed safety by default, only that performance and migration of C++ code takes priority, and any design will need to be considered in the context of other goals. It should still be possible to adopt guaranteed safety later, although it will require identifying a migration path.
That's very interesting and pragmatic. It would be interesting if they can eventually come up with the same level of safety guarantees via a different path than Rust's borrow checker.
-------------
Since one of their goals is to automatically translate modern C++ to Carbon, I do wonder how well that is going to work in general.
I definitely welcome an alternative to C++ that would be easier to read and understand. That would be a benefit to the world.
It's not like PHP is unsafe to begin with like C++, but the language does have a ton of problems, and Meta's massive codebase could only be migrated to another language gradually. Hence, Hack. Better language, better tooling, more productive programmers.
Note that unlike Carbon/C++, Hack is backwards-compatible with PHP. So the migration is somewhat more gradual.
For instance, just like the -O1 or -O3 flags work for optimization, something like a -S1 or -S3 would be really useful.
To me, there are lots of times when I just need to get an idea into code. Then there are times when I need to make sure that code just works™.
Having different compiler flags would really make that nice, and for devops, allow anything pushed to production have to complete a -S3 successfully first.
I seem to be the only one on the planet that doesn't think the language needs to be replaced.
All the time, it is C++ these companies use for these apps, especially having millions of users and generating multi-millions or hundreds of millions of dollars.
All the time, it is Fortran the government uses for these apps,..."
I vacillate as to whether the best response is: "Who cares?" or "give it time"? First, if C++ actually is better for GUI apps, then more power to C++ (do you have some evidence this is the case?). That doesn't mean their aren't other niches to fill for other languages, like Rust. Next, Rust is a relatively new language. It may end up that it's really great for GUI apps, but again it doesn't have to be. It can be great at other things.
I'm personally excited to see how all those languages will influence each other!
Then your beef is with the GP?
I'm also pretty certain we shouldn't be that pedantic about the word "replacement". Perhaps it's fine for a thing to be a "replacement for the GP" (which I think he/she is pretty clear about) or a "replacement for many uses" or for "all new uses", without being a "complete replacement"?
What's getting so weird about about the tenor of the current anti-Rust backlash is that 1) when the discussion turns to safety, it's "Hey, dude, don't harsh my buzz", but 2) when the discussion turns on the what the person meant, the Rust community's well-founded enthusiasm is interpreted in the harshest, most uncharitable, light.
In which world has Rust replaced C++?
Although I still think it should be possible to make some things obsolete in C++. The technical debt is real, and the language can hardly improve if old codebases are slowing down the evolution of the language.
I already wrote several times that I would like a new C++-like language, but without the complexity of C++. D, zig and rust are fine but they're not simple languages to use. I want the nice things of C++ (string, a few containers, a bit of syntax sugar, the most useful std stuff), with enough simplicity from python or C.
I just use the simple parts of C++, and I only want those parts. I just want the KISS simplicity. Carbon is not that, neither is rust zig or D.
They'll need to get it into Compiler Explorer so people can really look at codegen rather than porting small programs.
Interestingly, when looking at their code samples, the vibe I get is more "Go++". Using `var` for variable declarations, letter casing for visibility, explicit returns even at the end of functions, using the "package" keyword for namespacing, etc. I do see some superficial syntactic similarity to Rust, like using `fn` for functions and `->` to annotate return types, using `:` for type annotations for variables, and semicolons seeming to be required at the end of lines, but overall it doesn't really _feel_ that much like Rust to me, I think due to how imperative it seems. Given the use of `class` and `let/var` seeming to be const versus mutable bindings, I'm wondering if the Rust resemblance is actually just transitive through more of a resemblance to Swift, although I don't know Swift well enough to know if this is an accurate explanation.
`->` syntax is included in C++11 standard, named "trailing return type", but its adoption seems to be very slow.
`auto f() -> int { return 42; }`
That's pretty extensively covered in the link, but here's a relevant snippet:
"Existing modern languages already provide an excellent developer experience: Go, Swift, Kotlin, Rust, and many more. Developers that can use one of these existing languages should. Unfortunately, the designs of these languages present significant barriers to adoption and migration from C++. These barriers range from changes in the idiomatic design of software to performance overhead."
Very important. A C++ alternative and successor needs to be compatible with C++.
The rest of these so called C++ alternatives are either rewriting everything in their own language and causing chaos with their own incompatibilities with their language features and realising that it wasn't a good idea after all to do such rewrites after being sold vacuous promises and language feature snake oil, but only to show pretty syntax sugar.
Unfortunately, the hype squads will just attempt to drown out other alternatives like this one; even if it works with the existing C++ ecosystem.
This now looks to me like a Rust-- instead of a C++++, which is a picture they might not want to give rise to. Because then I'd rather use Rust instead, which then feels like the real thing(tm).
[EDIT: If you think about downvoting, maybe answer instead as I am genuinely interested in this syntax question. I am not trying to be negative, it was just an observation and a question.]
As for what's wrong with `Type name(constructor, args)`? A lot of tooling wants to be able to parse "mostly-valid C++", like IDEs and compiler diagnostics. Sure, once clang's type inference is finished, the lexer hack and most vexing parse aren't problems, but when the program isn't complete, parsing isolated fragments is impossible, and that limits the amount of useful tooling the language can have.
Even better, when you start having more complex patterns on the left-hand side of `=`, you can type annotate them as you want. Hypothetical syntax would be:
That's harder to do when you have a type declaration on the left imho.I claim writing the name first is much more readable. Compare
or`fn`, `name: Type`, `i32`, `->` for return type. `impl` as a keyword. `Self` as a keyword.
Nothing unique to Rust, but it's interesting to see.
[1] https://elizarov.medium.com/types-are-moving-to-the-right-22...
> The best way to address these problems is to avoid inheriting the legacy of C or C++ directly, and instead start with solid language foundations like a modern generics system, modular code organization, and consistent, simple syntax.
That last part seems to imply that the authors don't consider C++ syntax to be a good foundation for a modern successor language, so they chose to change it. As to why change it in a Rust-like direction I'd imagine that it's both because it's what fashionable at the time and possibly to attract people who are already familiar with that style.
The rest I can excuse but [], I cannot. Same reason I won't touch Nim.
The real solution is [] for generics and something else for indexing.
You can parse Go without a symbol table, but not C, because stuff like
changes completely in meaning depending on the existence of a previous typedef for `item`.C++ in order to not break compatibility with C has elevated this to insane extremes - there's so much ambiguous syntax in the language.
This expression can either be a function invocation, if `item` is a type and a template method named `get` exists, or else it's a series of comparisons. is also ambiguous: if r and f are types, that's a function, otherwise that's a variable declaration. There's no way to know that unless you have a symbol table, which makes separating syntactical and semantic analysis impossibile at best.The whole C++ language is full of similar ambiguities, and attempts to fix warts that backfired spectacularly. That's also the reason why writing a C++ frontend is a decade long endeavor that takes lots of people and resources. A full time team of 3 people can probably write a C parser in a few weeks in comparison, and C is big mess too, albeit a smaller mess though.
C#++ would be the next one, but I'd pull what Microsoft did to Windows 9 and skip right to C##.
x:Type has been used in MLs (SML, Ocaml) and recently TS. Haskells uses x::Type. This usage dates back to at least the simply typed lambda calculus in the 1930s.
fn and fun are used in SML and probably elsewhere. fun is used in OCaml, as well.
CamelCaseForEverything is such a waste, maybe they use it for implicit public/private as in Go? And maybe to please existing Go or Java users?
No thanks
https://github.com/carbon-language/carbon-lang/blob/trunk/do...
Also, under "Why not Rust?"
Clang and llvm understand them, and you can require them from the front end, but the cost is some backends will hard error on them as unimplemented.
Tail calls mean reusing memory (notably the stack) and arranging for there to be no work to do between the call and the return. E.g. if arguments are passed by allocating on the stack, you can't deallocate after the call, so you have to make the stack look just right before jumping.
If you've got multiple calling conventions on your architecture, they each need their own magic to make tail calls work, so you might have 'fastcall' work and 'stdcall' error. Iirc I implemented it for a normal calling convention on one arch and didn't bother for variadic calls.
I suppose one could have a dedicated convention for tail calls as well, I just haven't seen it done that way. Usually the callee doesn't know and can't tell whether it was called or tail-called.