www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Old Quora post: D vs Go vs Rust by Andrei Alexandrescu

reply Ali <fakeemail example.com> writes:
While randomly browsing online, I found this link below

https://www.quora.com/Which-language-has-the-brightest-future-in-replacement-of-C-between-D-Go-and-Rust-And-Why/answer/Andrei-Alexandrescu

This is a post on Quora, with some interesting statements by 
Andrei himself

"Overall it could be said that D has the downsides of GC but 
doesn't enjoy its benefits."

"A historical lack of vision"

"Of the three (D, Rust, Go), Rust is the only language with 
world-class PL theorists on roster"

"(D) 10x better than any other system language at generic and 
generative programming"

I am posting this here, because, I see a lot of comments that 
seem to suggest, that some people - me include, or me me at 
least, were under the impression that the makers of D, are not 
fully aware of its competitive advantages and disadvantages

But this post proves at least to me that the D foundation 
members, are really fully aware, how D compares to its key 
competitors

This post on Quora, makes it fully clear to me that the makers of 
D are fully aware of D's position

Anyway, it is a nice read, and reminder to some of us who follow 
this forum, that we probably dont need to remind D makers what D 
needs, or where D should go etc..
Jan 02
next sibling parent Mark <smarksc gmail.com> writes:
On Tuesday, 2 January 2018 at 16:34:25 UTC, Ali wrote:
 While randomly browsing online, I found this link below

 https://www.quora.com/Which-language-has-the-brightest-future-in-replacement-of-C-between-D-Go-and-Rust-And-Why/answer/Andrei-Alexandrescu

 [...]
Yes, it is a great post. I would be happy to read similar posts from the creators of Rust, Go, Swift, etc.
Jan 02
prev sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 2 January 2018 at 16:34:25 UTC, Ali wrote:
 "Overall it could be said that D has the downsides of GC but 
 doesn't enjoy its benefits."
Not a true statement. Go does not have long pauses, but it has slightly slower code and a penalty for interfacing with C. Go also has finalization with dependencies, so that they execute in the right order… The downsides/upsides of GC isn't something fixed for all designs.
 This post on Quora, makes it fully clear to me that the makers 
 of D are fully aware of D's position
Not sure how you reached that conclusion.
Jan 02
parent reply Ali <fakeemail example.com> writes:
On Tuesday, 2 January 2018 at 19:50:55 UTC, Ola Fosheim Grøstad 
wrote:
 On Tuesday, 2 January 2018 at 16:34:25 UTC, Ali wrote:
 "Overall it could be said that D has the downsides of GC but 
 doesn't enjoy its benefits."
Not a true statement. Go does not have long pauses, but it has slightly slower code and a penalty for interfacing with C. Go also has finalization with dependencies, so that they execute in the right order… The downsides/upsides of GC isn't something fixed for all designs.
That was not a comment about GC implementations in general, it was about D's GC implementation, check the original post on Quora, and read the statement right before this one, maybe it will make this point clearer
 This post on Quora, makes it fully clear to me that the makers 
 of D are fully aware of D's position
Not sure how you reached that conclusion.
¯\_(ツ)_/¯ Andrei is a smart guy, and the post was very honest, it was not biased at all. And it raises many concerns I see in many post by people who are a lot less involved with D, like the issues with the GC and the illusive vision
Jan 03
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 3 January 2018 at 19:42:32 UTC, Ali wrote:
 That was not a comment about GC implementations in general, it 
 was about D's GC implementation, check the original post on 
 Quora, and read the statement right before this one, maybe it 
 will make this point clearer
I read it when it was posted… D does get the key benefits of a GC (catching reference cycles and convenient memory management), but it also gets the disadvantages of a 1960s GC implementation. There are many ways to fix this, which has been discussed to death before (like thread local garbage collection), but there is no real decision making going on to deal with it. Because to deal with it you should also consider semantic/types system changes. The chosen direction seems to be to slowly make everything reference counted instead, which doesn't really improve things a whole lot IMO. At best you'll end up where Swift is at. Not bad, but also not great.
 And it raises many concerns I see in many post by people who 
 are a lot less involved with D, like the issues with the GC and 
 the illusive vision
Well, but leadership is about addressing the concerns and making some (unpopular) decisions to get here. *shrug* But I don't really care anymore, to be honest… Several other compiled languages are exploring new directions, so I'm currently content to watch where they are going… I personally think D would be in a stronger position if some hard decisions were made, but that isn't going to happen anytime soon. So there we are.
Jan 03
parent reply Mark <smarksc gmail.com> writes:
On Wednesday, 3 January 2018 at 21:43:00 UTC, Ola Fosheim Grøstad 
wrote:
 There are many ways to fix this, which has been discussed to 
 death before (like thread local garbage collection), but there 
 is no real decision making going on to deal with it.  Because 
 to deal with it you should also consider semantic/types system 
 changes.
I don't know much about GCs, but can you explain why that would be necessary?
Jan 03
next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Wednesday, January 03, 2018 22:06:22 Mark via Digitalmars-d wrote:
 On Wednesday, 3 January 2018 at 21:43:00 UTC, Ola Fosheim Grstad

 wrote:
 There are many ways to fix this, which has been discussed to
 death before (like thread local garbage collection), but there
 is no real decision making going on to deal with it.  Because
 to deal with it you should also consider semantic/types system
 changes.
I don't know much about GCs, but can you explain why that would be necessary?
Well, with how shared and casting works, it's not actually possible to have thread-local GC heaps, because objects can be passed between threads. Casting to and from shared would have to also tell the GC to change which thread manages that object's memory, and that would be a pretty big change to how casting works. It also wouldn't play well at all with how shared is used, because in order to use a shared object, you either have to use atomics (which wouldn't be a problem, since no casting is involved), or you have to temporarily cast the object to thread-local after protecting that section of code with a mutex to ensure that it's safe to treat that object as thread-local within that portion of code. Changing what manages the object's memory for that would just harm performance. Another thing to consider is that pointers don't actually know what manages their memory. That's not part of the type system. So, how would having casts move objects from the thread-local GC to the shared one (or vice versa) interact with stuff like pointers that refer to malloc-ed memory? Seemingly simple improvements to the GC fall apart _really_ fast when you consider how much you can legally do in D and how the type system doesn't really have anything in it to indicate what owns or manages a block of memory. Some of the really big GC improvements that have occurred in other GC-managed languages were able to be done, because the languages disallowed all kinds of stuff that a language like D or C++ considers perfectly legal and legitimate. Improvements can certainly be made to D's GC (and some improvements have definitely been done), but without changing how D works, we're _really_ restricted about what type of GC we can have. - Jonathan M Davis
Jan 03
parent Mark <smarksc gmail.com> writes:
On Wednesday, 3 January 2018 at 22:22:12 UTC, Jonathan M Davis 
wrote:
 [...]
Makes sense. Thanks. I use casting so little that sometimes I forget it exists.
Jan 04
prev sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 3 January 2018 at 22:06:22 UTC, Mark wrote:
 I don't know much about GCs, but can you explain why that would 
 be necessary?
Necessary is perhaps a strong word, but since D will never put restrictions on pointers then you need something else than what Java/C#/JavaScript/Go is using. There are many ways to do memory management, but if you want "smart" memory management where the programmer is relieved from the burden of manually making sure that things work then the compiler should also be able to reason about intent of the programmer and you need some way to express that intent. E.g. Pony differentiate between different types of "ownership" and can transition between them, so you can go from memory that is isolated to a single pointer, pointers that only know the address but cannot access the content, pointers that are fully shared etc. You also have something called effect-systems, which basically a sort of type system that can statically track that a file is opened before it is closed etc. So, if you have a smart compiler that is supposed to do the hard work for you, you probably also want some way to ensure that it actually is doing the smart things and that you haven't accidentally written some code that will prevent the compiler from generating smart code. For instance if you have a local garbage collector for a graph, you might want to statically ensure that there are noe external pointers into the graph when you call the collection process, although you might want to allow such pointers between collections. That way you don't have to scan more than graph itself, otherwise you would have to scan all memory that could contain pointers into the graph...
Jan 03
parent reply jmh530 <john.michael.hall gmail.com> writes:
On Wednesday, 3 January 2018 at 22:26:50 UTC, Ola Fosheim Grøstad 
wrote:
 E.g. Pony differentiate between different types of "ownership" 
 and can transition between them, so you can go from memory that 
 is isolated to a single pointer, pointers that only know the 
 address but cannot access the content, pointers that are fully 
 shared etc.
Pony relates to Rust in terms of what they are trying to accomplish with ownership. Pony's iso reference capability seems to mirror Rust's borrow checker rule that you can only have one mutable reference. D's DIP 1000 already seems to incorporate one of the borrow checker's rules on scope length. Adding something like iso would probably help in the ownership department after DIP 1000 is officially added.
Jan 04
parent reply Ola Fosheim Grostad <ola.fosheim.grostad gmail.com> writes:
On Thursday, 4 January 2018 at 19:04:36 UTC, jmh530 wrote:
 Pony relates to Rust in terms of what they are trying to 
 accomplish with ownership. Pony's iso reference capability 
 seems to mirror Rust's borrow checker rule that you can only 
 have one mutable reference.
But Rust isn't using garbage collection...
Jan 04
parent reply jmh530 <john.michael.hall gmail.com> writes:
On Thursday, 4 January 2018 at 19:18:30 UTC, Ola Fosheim Grostad 
wrote:
 On Thursday, 4 January 2018 at 19:04:36 UTC, jmh530 wrote:
 Pony relates to Rust in terms of what they are trying to 
 accomplish with ownership. Pony's iso reference capability 
 seems to mirror Rust's borrow checker rule that you can only 
 have one mutable reference.
But Rust isn't using garbage collection...
That probably makes Pony easier to compare to D. I was just noting that Rust shares some ownership stuff with Pony. I suppose I'm curious what is the bare minimum that needs to get added to D to enjoy the benefits of an ownership system (and it seemed like something like the iso type was most important).
Jan 04
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 4 January 2018 at 20:25:17 UTC, jmh530 wrote:
 That probably makes Pony easier to compare to D. I was just 
 noting that Rust shares some ownership stuff with Pony.
I get your point. Pony is probably closer to Go and Erlang, but nevertheless comparable to what some want from D based on what they say in the forums at least.
 I suppose I'm curious what is the bare minimum that needs to 
 get added to D to enjoy the benefits of an ownership system 
 (and it seemed like something like the iso type was most 
 important).
There should at least be a strategy for having transitions between pointer types and tracking of pointer types in relation to compile time code gen and run-time behaviour. So knowing that a pointer is iso can allow many things like transitioning into immutable, automatic deallocation, reusing memory without realloction, moving heap allocations to the stack… But if D is going to have a GC and no special code-gen to back it up then it becomes important to stratify/segment the memory into regions where you know that pointers that cross boundaries are limited to something known, so that you can scan less during collection. Which is rather advanced, in the general case, IMO. But a possibility if you impose some restrictions/idioms on the programmer.
Jan 04
parent reply jmh530 <john.michael.hall gmail.com> writes:
On Friday, 5 January 2018 at 00:58:12 UTC, Ola Fosheim Grøstad 
wrote:
 But if D is going to have a GC and no special code-gen to back 
 it up then it becomes important to stratify/segment the memory 
 into regions where you know that pointers that cross boundaries 
 are limited to something known, so that you can scan less 
 during collection. Which is rather advanced, in the general 
 case, IMO. But a possibility if you impose some 
 restrictions/idioms on the programmer.
I think it's a good idea. It relates to an idea I had had in the past with all the discussion on precise GC. One of the problems (as I think someone else mentioned above) with creating a precise GC for D is that it allows all sorts of things with unions and pointer arithmetic. However, it seems like just about all the stuff that makes a precise GC difficult is disabled in safe code (or at least assumed to be safe if coming through a trusted block). So you could have a safe region that is precise and a system region that is as it is now. From the current system, you would have to be able to do some kind of run-time reflection to know if the code is in a safe block or not. The simplest implementation would begin by handling just the case where you allocate in a safe block and the object is only referred to in safe blocks (that way you know it's always safe). And then you'd have to probably do something special for when point to safe code from system code. It also occurs to me that you could have a region for (completely) const/immutable data (not sure if you need to do this as a subregion within a precise region), assuming the GC can get that information. Transitive const/immutable means that pointers to this data cannot modify it. GC strategies that normally require write barriers wouldn't need them here.
Jan 04
parent reply jmh530 <john.michael.hall gmail.com> writes:
On Friday, 5 January 2018 at 03:11:42 UTC, jmh530 wrote:
 It also occurs to me that you could have a region for 
 (completely) const/immutable data (not sure if you need to do 
 this as a subregion within a precise region), assuming the GC 
 can get that information. Transitive const/immutable means that 
 pointers to this data cannot modify it. GC strategies that 
 normally require write barriers wouldn't need them here.
In std.experimental.allocator, I was thinking that in something like GCAllocator you could have the allocate function be a template that changes the behavior based on the the type you are trying to create. So for instance, if you are creating a const/immutable object do one thing and if creating a mutable object do something else. However, it looks like the allocate function is not templatized so it might require a bit of modification to get it work. It also mean the allocator would depend on the type it is trying to create, which may not be a design they want to pursue. I noticed there is a second parameter in allocate in IAllocator for TypeInfo. This is for run-time type info, but I don't see an example for it.
Jan 05
parent reply Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Friday, 5 January 2018 at 20:20:04 UTC, jmh530 wrote:
 On Friday, 5 January 2018 at 03:11:42 UTC, jmh530 wrote:
 [...]
In std.experimental.allocator, I was thinking that in something like GCAllocator you could have the allocate function be a template that changes the behavior based on the the type you are trying to create. So for instance, if you are creating a const/immutable object do one thing and if creating a mutable object do something else. However, it looks like the allocate function is not templatized so it might require a bit of modification to get it work. It also mean the allocator would depend on the type it is trying to create, which may not be a design they want to pursue. [...]
It seems you are thinking about this: https://dlang.org/phobos-prerelease/std_experimental_allocator_typed.html
Jan 05
parent jmh530 <john.michael.hall gmail.com> writes:
On Friday, 5 January 2018 at 22:09:03 UTC, Petar Kirov 
[ZombineDev] wrote:
 It seems you are thinking about this:
 https://dlang.org/phobos-prerelease/std_experimental_allocator_typed.html
Ha, that is exactly what I was thinking of!
Jan 05