by obl on 7/30/22, 6:43 PM with 217 comments
by Denvercoder9 on 7/30/22, 8:39 PM
by bbkane on 7/30/22, 7:58 PM
by Animats on 7/30/22, 8:08 PM
The reverse is true. Anything passed by value can be treated as const reference by the compiler if the compiler knows enough about access and lifetime. The compiler must be able to determine that the parameter is neither deallocated nor modified while the function is using it. Rust compilers should be able to do that.
by oneplane on 7/30/22, 7:38 PM
by fwsgonzo on 7/31/22, 7:18 AM
As an example, look at this issue from the mold linker: https://github.com/rui314/mold/issues/584
They are looking at creating an embeddable custom dynamic linker in order to greatly reduce loading times, by fixing locations as the file gets loaded in.
The equivalent in Carbon would (for example) be to create a new type of exception handling that changes how we think about exceptions, performance and their cost. Perhaps something like the static exceptions that Herb Sutter has been working on. Instead, they are not adding exceptions at all.
You will have to excuse my disappointment.
by tialaramex on 7/30/22, 9:19 PM
If you've got a 1.6 billion empty tuples in variable A, 1.4 billion in variable B and 1.8 billion in variable C, C++ can't see a way to do that on a 32-bit operating system. It needs to give each empty tuple an address, so it must think of 4.8 billion integers between 0 and 2^32 and it can't do that, so your program won't work.
Carbon is still far from finished, but if objects needn't have addresses it can do the same as Rust here, and cheerfully handle A, B and C as merely counters, counting 1.6 billion, 1.4 billion and 1.8 billion respectively is fine. Empty tuples are indistinguishable, so I needn't worry about giving you back the "wrong" empty tuple when you remove one, I can just give you a fresh one each time and decrement the counter.
by rgovostes on 7/30/22, 7:52 PM
I think this boils down to: Carbon defaults to passing parameters that fit in a single register by value, and all others by const reference. This affects a few things you might take for granted in C++, like whether you can take a reference to a parameter.
The opening example is showing two samples of Carbon and the equivalent C++ code, noting that the "undecorated" parameter `p : Point` is equivalent to `const Point& p` (pass by const reference to a struct) and `x : i32` is equivalent to `std::int32_t x` (pass by value).
by titzer on 7/31/22, 1:27 PM
I give it a -1 on innovation, it's so obviously stuck in a cul-de-sac in the design space that I see no hope for it. "We'll get around to memory safety eventually". Riiight.
That said, I'm glad they at least made the leap to, "Hey, we could actually use something other than C++?"
by matrix_overload on 7/31/22, 3:08 AM
It usually boils down to someone assuming that a particular collection or algorithm won't be on the critical path, and using a lazy O(N^2) solution. Then the codebase grows, use cases shift, someone puts another O(N^2) algorithm around an existing O(N^2) and the whole thing explodes.
Adding proper caching and switching to N*log(N) algorithms usually brings a DRAMATIC improvement (like 100x faster), while trying to squeeze out every unnecessary copy will only squeeze out about 10% of complexity.
by nyanpasu64 on 7/31/22, 12:03 AM
by IIsi50MHz on 7/31/22, 5:11 AM
by fourthark on 7/30/22, 8:40 PM
Unclear from the repo who is sponsoring it.
by funstuff007 on 7/30/22, 11:34 PM
Are they trolling Go here?
by oxff on 7/31/22, 4:20 AM
by DeathMetal3000 on 7/31/22, 8:19 PM
by t6jvcereio on 7/31/22, 12:50 PM
I find the tone strange. I understand that the author doesn't believe the statement. But I've never met anyone for whom performance matters and believes this. So, who's the audience here?
by girvo on 7/31/22, 8:10 AM
A C++ replacement that is just as difficult to bind/link/work with in other languages as C++ itself just seems like a missed mark, despite the fact I know this is not on their priority list at all.
I hope my read of this is wrong, and it will be easy to bind and link to from other languages after all.
by inoyau on 7/31/22, 2:24 AM
by tmpz22 on 7/31/22, 5:30 AM
by chubs on 7/31/22, 4:06 AM
by pyjarrett on 7/30/22, 9:23 PM
type Point is record
x, y, z : Interfaces.Integer_64;
end record;
procedure Print(p : Point);
Is `p` passed by reference or value? The compiler chooses what it thinks is best--all parameters are considered `const` unless they're `out` parameters. There's some rules for classes (tagged types), uncopyable (limited) objects, and `aliased` parameters which are always passed by reference.I can't get a pointer type (access) out of the parameter to the function, since the accessibility rules prevent it:
-- "constant" since we don't know if it is writable
type Point_Access is access constant Point;
Last_Printed : Point_Access := null;
procedure Print(P : Point) is
begin
-- P'Access is sort of like C++ std::addressof(P) to get a "pointer"
-- There's also P'Address to get the actual address, but then requires conversion to a pointer-like "access" type to be used.
--
-- Compiler Error: "non-local pointer cannot point to local object" since Point_Access type is declared at a higher level
Last_Printed := P'Access;
-- If we really, really, want to do it, "I'm smarter than the compiler", you can force it...
-- Think of "Unrestricted" and "Unchecked" as grep-able warnings signs of "this is potentially very dangerous"
Last_Access := P'Unrestricted_Access;
-- ...
end Last_Printed;
What about making and then trying to use a local pointer-like type? This doesn't work because you can only create pointer-like accesses to types which have been marked as `aliased`, since you don't know if there's a location you can point to which has the value. procedure Print (P : Point) is
type Local_Access is access constant Point;
-- Compiler Error: prefix of "Access" attribute must be aliased
Ptr_Like : Local_Access := P'Access;
-- Similar, "I am smarter than compiler" trick works here too...
Ptr_Like : Local_Access := P'Unrestricted_Access;
You can allow passing any arbitrary pointer into a function by providing `access`, but you're not allowed to store it, since you don't know which flavor of the pointer type it could be, e.g. if it points to something on the stack, or on the heap: type Point_Access is access constant Point;
Last_Printed : Point_Access := null;
-- Allow printing any pointer-like (access) to a point.
procedure Print (P : access constant Point) is
begin
-- Compile Error: implicit conversion of anonymous access parameter not allowed
Last_Printed := P;
-- If we really, really want to do this, we can force it with a cast...
Last_Printed := Point_Access (P);
-- ...
end Print;
by JadeNB on 7/30/22, 11:58 PM
by axegon_ on 7/30/22, 10:57 PM
by mgaunard on 7/31/22, 5:20 AM
The standard explicitly states that a parameter taken by value and initialized from an prvalue of the same type may elide the move constructor (which all implementations do).
by lifeplusplus on 7/31/22, 12:51 AM
by ArrayBoundCheck on 7/30/22, 9:11 PM
No thanks google. I've been saying that for years now. You jumped the shark
by booleandilemma on 7/30/22, 9:19 PM
by spullara on 7/30/22, 11:12 PM
by ISL on 7/30/22, 9:59 PM
It is interesting to contemplate the most-ambiguous and least-comprehensible/googleable name one might be able to give to a piece of software. "the"? "Biden"? "Russia"? "water"? "air"? "dog"? "person"? "!"? "?"? " "?
by glouwbug on 7/30/22, 10:31 PM
by NonNefarious on 7/30/22, 8:27 PM