digitalmars.D - Why does D rely on a GC?
- maik klein (19/19) Aug 18 2014 First of all I don't want to insult anyone on language design, I
- Jonathan M Davis via Digitalmars-d (25/44) Aug 18 2014 The biggest reason is memory safety. With a GC, it's possible to make co...
- bearophile (6/9) Aug 18 2014 Unless you have a very smart type system and you accept some
- Ary Borenszweig (4/13) Aug 18 2014 It's very smart, yes. But it takes half an hour to compile the compiler
- bearophile (13/17) Aug 18 2014 I think this is mostly a back-end issue. How much time does it
- Ary Borenszweig (5/10) Aug 20 2014 Not all hope is lost, though:
- Dicebot (5/18) Aug 20 2014 btw it takes 6 minutes to build LDC package from scratch on my
- Idan Arye (13/32) Aug 18 2014 Initially all those type wrapping and scoping and lifetimes were
- Paulo Pinto (8/28) Aug 18 2014 The compilation speed is caused by the C++ code in their compiler
- Ary Borenszweig (8/32) Aug 19 2014 Actually, it's 26m to just compile Rust without LLVM. Take a look at thi...
- Daniel Murphy (2/3) Aug 19 2014 Funny, the DDMD frontend compiles in ~6 seconds.
- Ary Borenszweig (5/9) Aug 19 2014 Nimrod's compiler takes 5 second. Crystal takes 6 seconds. I think
- bearophile (8/12) Aug 19 2014 Can't they remove some type inference from the language?
- Ary Borenszweig (61/75) Aug 19 2014 Crystal has *global* type inference. If you look at the compiler's code
- Ary Borenszweig (7/86) Aug 19 2014 Also, the list seems way too big. It's ok from a purist point of view,
- Dicebot (6/9) Aug 19 2014 This is why I won't bother investing any time in it for a few
- bachmeier (9/19) Aug 19 2014 I won't look at it again for a different reason. They're the
- Dicebot (11/25) Aug 19 2014 Actually I also don't think it is a big deal. Yes, it is crucial
- bachmeier (4/6) Aug 19 2014 On that we agree. It's great for its niche. I was picturing a
- ketmar via Digitalmars-d (3/5) Aug 19 2014 Java devs can speak?! O_O
- Paulo Pinto (6/13) Aug 20 2014 I imagine you are speaking about enterprise coding drones, as I
- ponce (5/11) Aug 19 2014 Same here. Want to solve the C++ problem, solve compilation speed
- Paulo Pinto (7/17) Aug 19 2014 I like the ML syntax, the problem is the extra Perl like syntax for
- Andrei Alexandrescu (2/21) Aug 19 2014 What is the main Rust forum? Thanks, Andrei
- Paulo Pinto (3/26) Aug 19 2014 According to this post, StackOverflow
- Meta (6/7) Aug 19 2014 Until very recently it was the mailing list [0]. There is now
- Timon Gehr (18/33) Aug 19 2014 Sure, so one should point out that problem may be made out to be that
- Philippe Sigaud via Digitalmars-d (10/21) Aug 19 2014 I remember finding this while exploring Haskell, some years ago:
- Timon Gehr (5/16) Aug 19 2014 Well, not /all/ wrong.
- Kagamin (4/16) Aug 19 2014 They don't know, where is the problem:
- Andrei Alexandrescu (4/28) Aug 19 2014 Could you please substantiate this with a couple of examples?
- Nick Treleaven (12/15) Aug 19 2014 Here's an example I ran into playing with the last release. Maybe I'm
- Paulo Pinto (8/40) Aug 19 2014 A few seconds when following the tutorial examples. I haven't written
- Paulo Pinto (21/40) Aug 18 2014 A good reason is the ability to write lock-free algorithms, which
- b (20/32) Aug 18 2014 Not really accurate. First of all, don't include unique_ptr as
- Paulo Pinto (25/56) Aug 18 2014 Yes it does, when you do cascade destruction of large data structures.
- maik klein (14/15) Aug 18 2014 Are you sure that there is even a cost for creation? I mean sure
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (5/10) Aug 18 2014 Memory allocation should be in the compiler/runtime to get proper
- ketmar via Digitalmars-d (9/12) Aug 18 2014 to avoid unnecessary complications in user source code. GC is necessary
- ponce (10/21) Aug 19 2014 I work in such an environment and I tend to agree with you. We
- ketmar via Digitalmars-d (12/15) Aug 19 2014 just replace GC with stub doing only allocs (or use GC.disable) and
- ponce (8/19) Aug 19 2014 I'm well aware of all that exist to do deterministic destruction.
- ketmar via Digitalmars-d (3/3) Aug 19 2014 On Tue, 19 Aug 2014 10:24:07 +0000
- Andrei Alexandrescu (5/20) Aug 19 2014 One issue with this is e.g. hashtables have no primitive for freeing
- Brian Rogoff (24/32) Aug 19 2014 And, in 2.066, it works with @nogc. Scoped no-gc downward
- ketmar via Digitalmars-d (17/21) Aug 19 2014 On Tue, 19 Aug 2014 07:13:45 -0700
- Kagamin (15/29) Aug 19 2014 It's still scope guarded, which is not zero cost in sjlj and
- Marco Leise (19/26) Aug 26 2014 Don't dismiss his point easily. The real memory cost is not
- Kagamin (11/14) Aug 26 2014 No.
- Kagamin (2/4) Aug 18 2014 Isn't unique_ptr unique? What to do when the object is non-unique?
- Maik Klein (18/23) Aug 18 2014 Not sure what you mean by unqiue. It's like a reference counted
- Dicebot (2/14) Aug 18 2014 http://dlang.org/phobos/std_typecons.html#.scoped
- Nick Treleaven (6/10) Aug 18 2014 It uses GC allocation, but the memory will be freed deterministically:
- Peter Alexander (9/14) Aug 18 2014 Yes, unique_ptr is unique :-) It is not reference counted -- it
- Kagamin (7/23) Aug 18 2014 So if it's not known to be unique beforehand, the safe bet is to
- Nick Treleaven (5/7) Aug 18 2014 It should work, but it is bug-prone without the @disable this(this) fix
- deadalnix (11/11) Aug 18 2014 Various reasons:
First of all I don't want to insult anyone on language design, I just want to know the reason behind the "always on" GC. I know that the GC as several advantages over reference counting, especially when it comes to immutable data structures. What I don't (correct me if i am wrong) understand is why every heap allocation has to be garbage collected, like classes, dynamic arrays etc. Does a GC still have advantages over heap allocations that do not need to be reference counted such as the unique_ptr in c++? The dlang homepage stats: Destructors are used to deallocate resources acquired by an object. For most classes, this resource is allocated memory. With garbage collection, most destructors then become empty and can be discarded entirely. If I understand it correctly it means that D has a GC, so most classes don't need a destructor anymore because they don't need to do any cleanup. I am not totally convinced that this would be a good trade off in general. Maybe someone could shine some light on this statement?
Aug 18 2014
On Mon, 18 Aug 2014 10:01:57 +0000 maik klein via Digitalmars-d <digitalmars-d puremagic.com> wrote:First of all I don't want to insult anyone on language design, I just want to know the reason behind the "always on" GC. I know that the GC as several advantages over reference counting, especially when it comes to immutable data structures. What I don't (correct me if i am wrong) understand is why every heap allocation has to be garbage collected, like classes, dynamic arrays etc. Does a GC still have advantages over heap allocations that do not need to be reference counted such as the unique_ptr in c++? The dlang homepage stats: Destructors are used to deallocate resources acquired by an object. For most classes, this resource is allocated memory. With garbage collection, most destructors then become empty and can be discarded entirely. If I understand it correctly it means that D has a GC, so most classes don't need a destructor anymore because they don't need to do any cleanup. I am not totally convinced that this would be a good trade off in general. Maybe someone could shine some light on this statement?The biggest reason is memory safety. With a GC, it's possible to make compiler guarantees about memory safety, whereas with manual memory management, it isn't. It's also pretty hard to do stuff like automatic closures and delegates without a GC, and the behavior of D's dynamic arrays - particularly with regards to slices - is much harder to do without a GC. The result is that there are a number of features which you lose out on if you don't have D's GC (though they're not features a language like C++ has, since it doesn't have a GC). However, it's also not true that the GC is necessarily always on. You can disable it. It's just that you do so, you lose out on certain language features, and memory management becomes a bit harder (particularly when it comes to constructing classes in malloced memory, but the custom allocators which are in the works should fix that). However, with the way a typical D program works, a lot more goes on the stack than happens with a typical GC language, so the fact that it has a GC wouldn't be as big an impediment as it is with some other languages, if you couldn't turn it off. So, having the GC gives us a number of features that aren't really possible without it, and unlike languages like Java, you _can_ turn it off if you want to, though you do lose out on some features when you do. So, ultimately, about all we really lose out on by having the GC is having folks who want a systems language freaking out about the fact that D has a GC and frequently assume that that means that they have to it and that D is not performant. - Jonathan M Davis
Aug 18 2014
Jonathan M Davis:The biggest reason is memory safety. With a GC, it's possible to make compiler guarantees about memory safety, whereas with manual memory management, it isn't.Unless you have a very smart type system and you accept some compromises (Rust also uses a reference counter some some cases, but I think most allocations don't need it). Bye, bearophile
Aug 18 2014
On 8/18/14, 8:51 AM, bearophile wrote:Jonathan M Davis:It's very smart, yes. But it takes half an hour to compile the compiler itself. And you have to put all those unwrap and types everywhere, I don't think it's fun or productive that way.The biggest reason is memory safety. With a GC, it's possible to make compiler guarantees about memory safety, whereas with manual memory management, it isn't.Unless you have a very smart type system and you accept some compromises (Rust also uses a reference counter some some cases, but I think most allocations don't need it). Bye, bearophile
Aug 18 2014
Ary Borenszweig:It's very smart, yes. But it takes half an hour to compile the compiler itself.I think this is mostly a back-end issue. How much time does it take to compile ldc2? Can't they create a Rust with dmc back-end? :o)And you have to put all those unwrap and types everywhere, I don't think it's fun or productive that way.I've never written Rust programs longer than twenty lines, so I don't know. But I think Rust code is acceptable to write, I have seen code written in far worse situations (think about a programs one million lines of code long of MUMPS). Apparently the main Rust designer is willing to accept anything to obtain memory safety of Rust in parallel code. And the language is becoming simpler to use and less noisy. Bye, bearophile
Aug 18 2014
On 8/18/14, 9:05 PM, bearophile wrote:Ary Borenszweig:Not all hope is lost, though: https://github.com/rust-lang/rust/issues/16624 With such bugs, one can expect a lot of performance improvements in the future :-)It's very smart, yes. But it takes half an hour to compile the compiler itself.I think this is mostly a back-end issue. How much time does it take to compile ldc2? Can't they create a Rust with dmc back-end? :o)
Aug 20 2014
On Wednesday, 20 August 2014 at 13:43:19 UTC, Ary Borenszweig wrote:On 8/18/14, 9:05 PM, bearophile wrote:btw it takes 6 minutes to build LDC package from scratch on my machine - that is including cloning git repos and packaging actual tarball.Ary Borenszweig:Not all hope is lost, though: https://github.com/rust-lang/rust/issues/16624 With such bugs, one can expect a lot of performance improvements in the future :-)It's very smart, yes. But it takes half an hour to compile the compiler itself.I think this is mostly a back-end issue. How much time does it take to compile ldc2? Can't they create a Rust with dmc back-end? :o)
Aug 20 2014
On Monday, 18 August 2014 at 23:48:24 UTC, Ary Borenszweig wrote:On 8/18/14, 8:51 AM, bearophile wrote:Initially all those type wrapping and scoping and lifetimes were single-character annotations and that gave me the impression that the idea is that once you get comfortable with Rust's type system and syntax, you can use all that fine-grained control over the scope and lifetime of the data to get superior compile-time error checking and to give better cues to the compiler to get better performance, without too much effort and without hindering the readability(again - once you get comfortable with the type system). Now, though, when they remove more and more syntax to the library in an attempt to reach the elegance and simplicity of modern C++, I'm no longer sure that was the true goal of that language...Jonathan M Davis:It's very smart, yes. But it takes half an hour to compile the compiler itself. And you have to put all those unwrap and types everywhere, I don't think it's fun or productive that way.The biggest reason is memory safety. With a GC, it's possible to make compiler guarantees about memory safety, whereas with manual memory management, it isn't.Unless you have a very smart type system and you accept some compromises (Rust also uses a reference counter some some cases, but I think most allocations don't need it). Bye, bearophile
Aug 18 2014
On Monday, 18 August 2014 at 23:48:24 UTC, Ary Borenszweig wrote:On 8/18/14, 8:51 AM, bearophile wrote:The compilation speed is caused by the C++ code in their compiler backend (LLVM), which gets compiled at least twice during the bootstraping process.Jonathan M Davis:It's very smart, yes. But it takes half an hour to compile the compiler itself.The biggest reason is memory safety. With a GC, it's possible to make compiler guarantees about memory safety, whereas with manual memory management, it isn't.Unless you have a very smart type system and you accept some compromises (Rust also uses a reference counter some some cases, but I think most allocations don't need it). Bye, bearophileAnd you have to put all those unwrap and types everywhere, I don't think it's fun or productive that way.There I fully agree. If they don't improve lifetime's usability, I don't see Rust being adopted by average developers. -- Paulo
Aug 18 2014
On 8/19/14, 3:50 AM, Paulo Pinto wrote:On Monday, 18 August 2014 at 23:48:24 UTC, Ary Borenszweig wrote:Actually, it's 26m to just compile Rust without LLVM. Take a look at this: https://twitter.com/steveklabnik/status/496774607610052608 Then here someone from the team says he can't say a way to improve the performance by an order of magnitude: https://www.mail-archive.com/rust-dev mozilla.org/msg02856.html (but I don't know how true is that)On 8/18/14, 8:51 AM, bearophile wrote:The compilation speed is caused by the C++ code in their compiler backend (LLVM), which gets compiled at least twice during the bootstraping process.Jonathan M Davis:It's very smart, yes. But it takes half an hour to compile the compiler itself.The biggest reason is memory safety. With a GC, it's possible to make compiler guarantees about memory safety, whereas with manual memory management, it isn't.Unless you have a very smart type system and you accept some compromises (Rust also uses a reference counter some some cases, but I think most allocations don't need it). Bye, bearophileThis. But maybe programming in a safe way is inherently hard? Who knows...And you have to put all those unwrap and types everywhere, I don't think it's fun or productive that way.There I fully agree. If they don't improve lifetime's usability, I don't see Rust being adopted by average developers.
Aug 19 2014
"Ary Borenszweig" wrote in message news:lsviva$2ip0$1 digitalmars.com...Actually, it's 26m to just compile Rust without LLVM. Take a look at this:Funny, the DDMD frontend compiles in ~6 seconds.
Aug 19 2014
On 8/19/14, 10:55 AM, Daniel Murphy wrote:"Ary Borenszweig" wrote in message news:lsviva$2ip0$1 digitalmars.com...Nimrod's compiler takes 5 second. Crystal takes 6 seconds. I think compiling ldc2 also takes about the same time. When I compile librustc with Rust with stats on, it takes 1.1 seconds to just *parse* the code. I think there's something very bad in their code...Actually, it's 26m to just compile Rust without LLVM. Take a look at this:Funny, the DDMD frontend compiles in ~6 seconds.
Aug 19 2014
Ary Borenszweig:Then here someone from the team says he can't say a way to improve the performance by an order of magnitude: https://www.mail-archive.com/rust-dev mozilla.org/msg02856.html (but I don't know how true is that)Can't they remove some type inference from the language? Type inference is handy (but I write down all type signatures in Haskell, sometimes even for nested functions) but if it costs so much in compilation time then perhaps isn't it a good idea to remove some type inference from Rust? Bye, bearophile
Aug 19 2014
On 8/19/14, 11:51 AM, bearophile wrote:Ary Borenszweig:Crystal has *global* type inference. If you look at the compiler's code you will find very few type annotations (mostly for generic types and for arguments types restrictions). Compiling the compiler takes 6 seconds (recompiling it takes 3 seconds). D also has auto, Nimrod has let, and both compilers are very fast. I don't think type inference is what makes their compiler slow. Here are the full stats: $ time CFG_VERSION=1 CFG_RELEASE=0 rustc -Z time-passes src/librustc/lib.rs time: 0.519 s parsing time: 0.026 s gated feature checking time: 0.000 s crate injection time: 0.170 s configuration 1 time: 0.083 s plugin loading time: 0.000 s plugin registration time: 1.803 s expansion time: 0.326 s configuration 2 time: 0.309 s maybe building test harness time: 0.321 s prelude injection time: 0.363 s assigning node ids and indexing ast time: 0.023 s checking that all macro invocations are gone time: 0.031 s external crate/lib resolution time: 0.046 s language item collection time: 1.250 s resolution time: 0.027 s lifetime resolution time: 0.000 s looking for entry point time: 0.023 s looking for plugin registrar time: 0.063 s freevar finding time: 0.126 s region resolution time: 0.025 s loop checking time: 0.047 s stability index time: 0.126 s type collecting time: 0.050 s variance inference time: 0.265 s coherence checking time: 17.294 s type checking time: 0.044 s check static items time: 0.190 s const marking time: 0.037 s const checking time: 0.378 s privacy checking time: 0.080 s intrinsic checking time: 0.070 s effect checking time: 0.843 s match checking time: 0.184 s liveness checking time: 1.569 s borrow checking time: 0.518 s kind checking time: 0.033 s reachability checking time: 0.204 s death checking time: 0.835 s lint checking time: 0.000 s resolving dependency formats time: 25.645 s translation time: 1.325 s llvm function passes time: 0.766 s llvm module passes time: 40.950 s codegen passes time: 46.521 s LLVM passes time: 0.607 s running linker time: 3.372 s linking real 1m46.062s user 1m41.727s sys 0m3.333s So apparently type checking takes a long time, and also generating the llvm code. But it seems waaaay too much for what it is.Then here someone from the team says he can't say a way to improve the performance by an order of magnitude: https://www.mail-archive.com/rust-dev mozilla.org/msg02856.html (but I don't know how true is that)Can't they remove some type inference from the language? Type inference is handy (but I write down all type signatures in Haskell, sometimes even for nested functions) but if it costs so much in compilation time then perhaps isn't it a good idea to remove some type inference from Rust? Bye, bearophile
Aug 19 2014
On 8/19/14, 12:01 PM, Ary Borenszweig wrote:On 8/19/14, 11:51 AM, bearophile wrote:Also, the list seems way too big. It's ok from a purist point of view, to make the compiler nice and clean. But that's not a good way to make a fast compiler. The sad thing is that Mozilla is behind the project, so people are really excited about it. Other languages don't have a big corporation behind them and have faster compilers (and nicer languages, I think ^_^).Ary Borenszweig:Crystal has *global* type inference. If you look at the compiler's code you will find very few type annotations (mostly for generic types and for arguments types restrictions). Compiling the compiler takes 6 seconds (recompiling it takes 3 seconds). D also has auto, Nimrod has let, and both compilers are very fast. I don't think type inference is what makes their compiler slow. Here are the full stats: $ time CFG_VERSION=1 CFG_RELEASE=0 rustc -Z time-passes src/librustc/lib.rs time: 0.519 s parsing time: 0.026 s gated feature checking time: 0.000 s crate injection time: 0.170 s configuration 1 time: 0.083 s plugin loading time: 0.000 s plugin registration time: 1.803 s expansion time: 0.326 s configuration 2 time: 0.309 s maybe building test harness time: 0.321 s prelude injection time: 0.363 s assigning node ids and indexing ast time: 0.023 s checking that all macro invocations are gone time: 0.031 s external crate/lib resolution time: 0.046 s language item collection time: 1.250 s resolution time: 0.027 s lifetime resolution time: 0.000 s looking for entry point time: 0.023 s looking for plugin registrar time: 0.063 s freevar finding time: 0.126 s region resolution time: 0.025 s loop checking time: 0.047 s stability index time: 0.126 s type collecting time: 0.050 s variance inference time: 0.265 s coherence checking time: 17.294 s type checking time: 0.044 s check static items time: 0.190 s const marking time: 0.037 s const checking time: 0.378 s privacy checking time: 0.080 s intrinsic checking time: 0.070 s effect checking time: 0.843 s match checking time: 0.184 s liveness checking time: 1.569 s borrow checking time: 0.518 s kind checking time: 0.033 s reachability checking time: 0.204 s death checking time: 0.835 s lint checking time: 0.000 s resolving dependency formats time: 25.645 s translation time: 1.325 s llvm function passes time: 0.766 s llvm module passes time: 40.950 s codegen passes time: 46.521 s LLVM passes time: 0.607 s running linker time: 3.372 s linking real 1m46.062s user 1m41.727s sys 0m3.333s So apparently type checking takes a long time, and also generating the llvm code. But it seems waaaay too much for what it is.Then here someone from the team says he can't say a way to improve the performance by an order of magnitude: https://www.mail-archive.com/rust-dev mozilla.org/msg02856.html (but I don't know how true is that)Can't they remove some type inference from the language? Type inference is handy (but I write down all type signatures in Haskell, sometimes even for nested functions) but if it costs so much in compilation time then perhaps isn't it a good idea to remove some type inference from Rust? Bye, bearophile
Aug 19 2014
On Tuesday, 19 August 2014 at 15:16:31 UTC, Ary Borenszweig wrote:Also, the list seems way too big. It's ok from a purist point of view, to make the compiler nice and clean. But that's not a good way to make a fast compiler.This is why I won't bother investing any time in it for a few more years at least. It may have really cool language features, big development team and famous names behind it but in terms of compiler maturity it is still a very long road to go until it gets even to DMD capabilities.
Aug 19 2014
On Tuesday, 19 August 2014 at 16:17:02 UTC, Dicebot wrote:On Tuesday, 19 August 2014 at 15:16:31 UTC, Ary Borenszweig wrote:I won't look at it again for a different reason. They're the types that say "A monad is just a monoid in the category of endofunctors, what's the problem?" but they're serious. My last interaction with Rust was when I commented that adoption would be hurt if they require an understanding of the memory model just to get started, to which they responded more or less that it's not a big deal. At that point I concluded the language was lost. I can only imagine what it will look like in five years.Also, the list seems way too big. It's ok from a purist point of view, to make the compiler nice and clean. But that's not a good way to make a fast compiler.This is why I won't bother investing any time in it for a few more years at least. It may have really cool language features, big development team and famous names behind it but in terms of compiler maturity it is still a very long road to go until it gets even to DMD capabilities.
Aug 19 2014
On Tuesday, 19 August 2014 at 17:11:21 UTC, bachmeier wrote:Actually I also don't think it is a big deal. Yes, it is crucial blocker for any "casual" adoption and will like to prevent its adoption in web service domain, for example (in a way similar to vibe.d) - but language has never been designed for such use cases. It is for complicated projects with non-trivial performance requirements and there is certain point of complexity where educating hired programmers about category theory may be cheaper than dealing with maintenance in overly lax language. It does look like a niche language but a very good one in declared niche.This is why I won't bother investing any time in it for a few more years at least. It may have really cool language features, big development team and famous names behind it but in terms of compiler maturity it is still a very long road to go until it gets even to DMD capabilities.I won't look at it again for a different reason. They're the types that say "A monad is just a monoid in the category of endofunctors, what's the problem?" but they're serious. My last interaction with Rust was when I commented that adoption would be hurt if they require an understanding of the memory model just to get started, to which they responded more or less that it's not a big deal. At that point I concluded the language was lost. I can only imagine what it will look like in five years.
Aug 19 2014
On Tuesday, 19 August 2014 at 17:16:32 UTC, Dicebot wrote:It does look like a niche language but a very good one in declared niche.On that we agree. It's great for its niche. I was picturing a Java or .NET programmer looking at the language. Java devs complain about Scala. I can't imagine what they'd say about Rust.
Aug 19 2014
On Tue, 19 Aug 2014 18:13:27 +0000 bachmeier via Digitalmars-d <digitalmars-d puremagic.com> wrote:Java or .NET programmer looking at the language. Java devs=20 complain about Scala. I can't imagine what they'd say about Rust.Java devs can speak?! O_O
Aug 19 2014
On Tuesday, 19 August 2014 at 18:13:28 UTC, bachmeier wrote:On Tuesday, 19 August 2014 at 17:16:32 UTC, Dicebot wrote:I imagine you are speaking about enterprise coding drones, as I also develop in Java and already expressed my opinion about Rust. :) -- PauloIt does look like a niche language but a very good one in declared niche.On that we agree. It's great for its niche. I was picturing a Java or .NET programmer looking at the language. Java devs complain about Scala. I can't imagine what they'd say about Rust.
Aug 20 2014
On Tuesday, 19 August 2014 at 17:11:21 UTC, bachmeier wrote:My last interaction with Rust was when I commented that adoption would be hurt if they require an understanding of the memory model just to get started, to which they responded more or less that it's not a big deal. At that point I concluded the language was lost. I can only imagine what it will look like in five years.Same here. Want to solve the C++ problem, solve compilation speed first. I can't see programmers suddenly willing to manage lifetimes explicitely, also I can see the Rust syntax create an endless stream of complaints.
Aug 19 2014
Am 19.08.2014 19:18, schrieb ponce:On Tuesday, 19 August 2014 at 17:11:21 UTC, bachmeier wrote:I like the ML syntax, the problem is the extra Perl like syntax for lifetimes and such. The way things are, Swift is probably going to get more developers than Rust. -- PauloMy last interaction with Rust was when I commented that adoption would be hurt if they require an understanding of the memory model just to get started, to which they responded more or less that it's not a big deal. At that point I concluded the language was lost. I can only imagine what it will look like in five years.Same here. Want to solve the C++ problem, solve compilation speed first. I can't see programmers suddenly willing to manage lifetimes explicitely, also I can see the Rust syntax create an endless stream of complaints.
Aug 19 2014
On 8/19/14, 10:11 AM, bachmeier wrote:On Tuesday, 19 August 2014 at 16:17:02 UTC, Dicebot wrote:What is the main Rust forum? Thanks, AndreiOn Tuesday, 19 August 2014 at 15:16:31 UTC, Ary Borenszweig wrote:I won't look at it again for a different reason. They're the types that say "A monad is just a monoid in the category of endofunctors, what's the problem?" but they're serious. My last interaction with Rust was when I commented that adoption would be hurt if they require an understanding of the memory model just to get started, to which they responded more or less that it's not a big deal. At that point I concluded the language was lost. I can only imagine what it will look like in five years.Also, the list seems way too big. It's ok from a purist point of view, to make the compiler nice and clean. But that's not a good way to make a fast compiler.This is why I won't bother investing any time in it for a few more years at least. It may have really cool language features, big development team and famous names behind it but in terms of compiler maturity it is still a very long road to go until it gets even to DMD capabilities.
Aug 19 2014
Am 19.08.2014 20:22, schrieb Andrei Alexandrescu:On 8/19/14, 10:11 AM, bachmeier wrote:According to this post, StackOverflow https://mail.mozilla.org/pipermail/rust-dev/2014-August/011019.htmlOn Tuesday, 19 August 2014 at 16:17:02 UTC, Dicebot wrote:What is the main Rust forum? Thanks, AndreiOn Tuesday, 19 August 2014 at 15:16:31 UTC, Ary Borenszweig wrote:I won't look at it again for a different reason. They're the types that say "A monad is just a monoid in the category of endofunctors, what's the problem?" but they're serious. My last interaction with Rust was when I commented that adoption would be hurt if they require an understanding of the memory model just to get started, to which they responded more or less that it's not a big deal. At that point I concluded the language was lost. I can only imagine what it will look like in five years.Also, the list seems way too big. It's ok from a purist point of view, to make the compiler nice and clean. But that's not a good way to make a fast compiler.This is why I won't bother investing any time in it for a few more years at least. It may have really cool language features, big development team and famous names behind it but in terms of compiler maturity it is still a very long road to go until it gets even to DMD capabilities.
Aug 19 2014
On Tuesday, 19 August 2014 at 18:22:46 UTC, Andrei Alexandrescu wrote:What is the main Rust forum? Thanks, AndreiUntil very recently it was the mailing list [0]. There is now also a Discourse forum [1]. [0] rust-dev mozilla.org [1] http://discuss.rust-lang.org/
Aug 19 2014
On 08/19/2014 07:11 PM, bachmeier wrote:On Tuesday, 19 August 2014 at 16:17:02 UTC, Dicebot wrote:Sure, so one should point out that problem may be made out to be that the monoidal product [1][2] is underspecified for someone unfamiliar with the convention (in this case it should be given by composition of endofunctors, and the associator is given pointwise by identity morphisms). (But of course, the more fundamental problem is actually that this characterization is not abstract enough and hence harder to decipher than necessary. A monad can be defined in an arbitrary bicategory... :o) ) What do /you/ think is the problem?On Tuesday, 19 August 2014 at 15:16:31 UTC, Ary Borenszweig wrote:I won't look at it again for a different reason. They're the types that say "A monad is just a monoid in the category of endofunctors, what's the problem?"Also, the list seems way too big. It's ok from a purist point of view, to make the compiler nice and clean. But that's not a good way to make a fast compiler.This is why I won't bother investing any time in it for a few more years at least. It may have really cool language features, big development team and famous names behind it but in terms of compiler maturity it is still a very long road to go until it gets even to DMD capabilities.but they're serious.I have a hard time believing this. While it is true that those concepts are not complicated [3], it seems to be generally acknowledged that some carefully compressed characterization/definition alone is not usually the most helpful introduction of them, especially so if the application is going to be in a more concrete setting. [1] http://en.wikipedia.org/wiki/Monoid_%28category_theory%29 [2] http://en.wikipedia.org/wiki/Monoidal_category [3] But, quite apparently, they are sometimes hard to communicate.
Aug 19 2014
I remember finding this while exploring Haskell, some years ago: http://www.haskell.org/haskellwiki/Zygohistomorphic_prepromorphisms And thinking: Ah, I get it, it's a joke: they know they are considered a bunch of strangely mathematically-influenced developers, but they have a sense of humor and know how to be tongue-in-cheek and have gentle fun at themselves. (My strange free association was: Zygo => zygomatics muscle => smile & laughter => joke). That actually got me interested in Haskell :) But, apparently, I was all wrong ;-) It got me reading entire books on category theory and type theory, though.I won't look at it again for a different reason. They're the types that say "A monad is just a monoid in the category of endofunctors, what's the problem?"Sure, so one should point out that problem may be made out to be that the monoidal product [1][2] is underspecified for someone unfamiliar with the convention (in this case it should be given by composition of endofunctors, and the associator is given pointwise by identity morphisms). (But of course, the more fundamental problem is actually that this characterization is not abstract enough and hence harder to decipher than necessary. A monad can be defined in an arbitrary bicategory... :o) ) What do /you/ think is the problem?
Aug 19 2014
On 08/19/2014 09:07 PM, Philippe Sigaud via Digitalmars-d wrote:I remember finding this while exploring Haskell, some years ago: http://www.haskell.org/haskellwiki/Zygohistomorphic_prepromorphisms And thinking: Ah, I get it, it's a joke: they know they are considered a bunch of strangely mathematically-influenced developers, but they have a sense of humor and know how to be tongue-in-cheek and have gentle fun at themselves. (My strange free association was: Zygo => zygomatics muscle => smile & laughter => joke). That actually got me interested in Haskell:) But, apparently, I was all wrong;-)Well, not /all/ wrong. http://www.reddit.com/r/programming/comments/6ml1y/a_pretty_useful_has ell_snippet/c04ako5 :-)It got me reading entire books on category theory and type theory, though.That's a lot of fun in any case. =)
Aug 19 2014
On Tuesday, 19 August 2014 at 14:51:49 UTC, bearophile wrote:Ary Borenszweig:They don't know, where is the problem: https://www.mail-archive.com/rust-dev mozilla.org/msg02865.htmlThen here someone from the team says he can't say a way to improve the performance by an order of magnitude: https://www.mail-archive.com/rust-dev mozilla.org/msg02856.html (but I don't know how true is that)Can't they remove some type inference from the language?- Non-use of arenas and &, pervasivelyThey don't use lent pointers. Just as planned.- Refcounting traffic - Landing pads - Cleanup duplication in _any_ scope-exit scenario
Aug 19 2014
On 8/18/14, 11:50 PM, Paulo Pinto wrote:On Monday, 18 August 2014 at 23:48:24 UTC, Ary Borenszweig wrote:Generally speaking how fast is the Rust compiler at compiling Rust files?On 8/18/14, 8:51 AM, bearophile wrote:The compilation speed is caused by the C++ code in their compiler backend (LLVM), which gets compiled at least twice during the bootstraping process.Jonathan M Davis:It's very smart, yes. But it takes half an hour to compile the compiler itself.The biggest reason is memory safety. With a GC, it's possible to make compiler guarantees about memory safety, whereas with manual memory management, it isn't.Unless you have a very smart type system and you accept some compromises (Rust also uses a reference counter some some cases, but I think most allocations don't need it). Bye, bearophileCould you please substantiate this with a couple of examples? AndreiAnd you have to put all those unwrap and types everywhere, I don't think it's fun or productive that way.There I fully agree. If they don't improve lifetime's usability, I don't see Rust being adopted by average developers.
Aug 19 2014
On 19/08/2014 15:09, Andrei Alexandrescu wrote:Here's an example I ran into playing with the last release. Maybe I'm doing something wrong though: fn main() { let mut x:uint = 0u; let f = ||x += 1; // closure borrows x if x == 1 {return} // error: cannot use `x` because it was mutably borrowed f(); } This seems unnecessarily restrictive.There I fully agree. If they don't improve lifetime's usability, I don't see Rust being adopted by average developers.Could you please substantiate this with a couple of examples?
Aug 19 2014
Am 19.08.2014 16:09, schrieb Andrei Alexandrescu:On 8/18/14, 11:50 PM, Paulo Pinto wrote:A few seconds when following the tutorial examples. I haven't written much Rust.On Monday, 18 August 2014 at 23:48:24 UTC, Ary Borenszweig wrote:Generally speaking how fast is the Rust compiler at compiling Rust files?On 8/18/14, 8:51 AM, bearophile wrote:The compilation speed is caused by the C++ code in their compiler backend (LLVM), which gets compiled at least twice during the bootstraping process.Jonathan M Davis:It's very smart, yes. But it takes half an hour to compile the compiler itself.The biggest reason is memory safety. With a GC, it's possible to make compiler guarantees about memory safety, whereas with manual memory management, it isn't.Unless you have a very smart type system and you accept some compromises (Rust also uses a reference counter some some cases, but I think most allocations don't need it). Bye, bearophileDiscussions like these, http://www.reddit.com/r/rust/comments/2dmcxs/new_to_rust_trying_to_figure_out_lifetimes/ http://www.reddit.com/r/rust/comments/2ac390/generic_string_literals/ -- PauloCould you please substantiate this with a couple of examples? AndreiAnd you have to put all those unwrap and types everywhere, I don't think it's fun or productive that way.There I fully agree. If they don't improve lifetime's usability, I don't see Rust being adopted by average developers.
Aug 19 2014
On Monday, 18 August 2014 at 10:01:59 UTC, maik klein wrote:First of all I don't want to insult anyone on language design, I just want to know the reason behind the "always on" GC. I know that the GC as several advantages over reference counting, especially when it comes to immutable data structures. What I don't (correct me if i am wrong) understand is why every heap allocation has to be garbage collected, like classes, dynamic arrays etc. Does a GC still have advantages over heap allocations that do not need to be reference counted such as the unique_ptr in c++? The dlang homepage stats: Destructors are used to deallocate resources acquired by an object. For most classes, this resource is allocated memory. With garbage collection, most destructors then become empty and can be discarded entirely. If I understand it correctly it means that D has a GC, so most classes don't need a destructor anymore because they don't need to do any cleanup. I am not totally convinced that this would be a good trade off in general. Maybe someone could shine some light on this statement?A good reason is the ability to write lock-free algorithms, which are very hard to implement without GC support. This is the main reason why C++11 has a GC API and Herb Sutter will be discussing about GC in C++ at CppCon. Reference counting is only a win over GC with compiler support for reducing increment/decrement operations via dataflow analysis. C++ programs with heavy use of unique_ptr/shared_ptr/weak_ptr are slower than other languages with GC support, because those classes are plain library types without compiler support. Of course, compiler vendors can have blessed library types, but the standard does not require it. RC also has performance impact when deleting big data structures. You can optimize this away big using asynchronous deletion, but eventually you are just doing GC with another name. As for feasibility of a GC in a systems programming language, just think the Mesa/Cedar environment at Xerox PARC was a system programming language using reference counting with a GC for collecting cycles. -- Paulo
Aug 18 2014
A good reason is the ability to write lock-free algorithms, which are very hard to implement without GC support. This is the main reason why C++11 has a GC API and Herb Sutter will be discussing about GC in C++ at CppCon.*some* lock free algorithms benefit from GC, there is still plenty you can do without GC, just look at TBB.Reference counting is only a win over GC with compiler support for reducing increment/decrement operations via dataflow analysis. C++ programs with heavy use of unique_ptr/shared_ptr/weak_ptr are slower than other languages with GC support, because those classes are plain library types without compiler support. Of course, compiler vendors can have blessed library types, but the standard does not require it.Not really accurate. First of all, don't include unique_ptr as if it had the same overhead as the other two, it doesn't. With RC you pay a price during creation/deletion/sharing, but not while it is alive. With GC you pay almost no cost during allocation/deletion, but a constant cost while it is alive. You allocate enough objects and the sum cost ant so small. Besides that, in C++ it works like this. 90% of objects: value types, on stack or embedded into other objects 9% of objects: unique types, use unique_ptr, no overhead ~1% of objects: shared, use shared_ptr/weak_ptr etc. With GC you give up deterministic behavior, which is *absolutely* not worth giving up for 1% of objects. I think most people simply haven't worked in an environment that supports unique/linear types. So everyone assumes that you need a GC. Rust is showing that this is nonsense, as C++ has already done for people using C++11.
Aug 18 2014
Am 18.08.2014 20:56, schrieb b:Sure, but you need to be a very good expert to pull them off.A good reason is the ability to write lock-free algorithms, which are very hard to implement without GC support. This is the main reason why C++11 has a GC API and Herb Sutter will be discussing about GC in C++ at CppCon.*some* lock free algorithms benefit from GC, there is still plenty you can do without GC, just look at TBB.Yes it does, when you do cascade destruction of large data structures.Reference counting is only a win over GC with compiler support for reducing increment/decrement operations via dataflow analysis. C++ programs with heavy use of unique_ptr/shared_ptr/weak_ptr are slower than other languages with GC support, because those classes are plain library types without compiler support. Of course, compiler vendors can have blessed library types, but the standard does not require it.Not really accurate. First of all, don't include unique_ptr as if it had the same overhead as the other two, it doesn't.With RC you pay a price during creation/deletion/sharing, but not while it is alive. With GC you pay almost no cost during allocation/deletion, but a constant cost while it is alive. You allocate enough objects and the sum cost ant so small. Besides that, in C++ it works like this. 90% of objects: value types, on stack or embedded into other objects 9% of objects: unique types, use unique_ptr, no overhead ~1% of objects: shared, use shared_ptr/weak_ptr etc.It is more than 1% I would say, because in many cases where you have an unique_ptr, you might need a shared_ptr instead, or go unsafe and give direct access to the underlying pointer. For example, parameters and temporaries, where you can be sure no one else is using the pointer, but afterwards as a consequence of destructor invocation the data is gone.With GC you give up deterministic behavior, which is *absolutely* not worth giving up for 1% of objects.Being a GC enabled systems programming language does not forbid the presence of deterministic memory management support, for the use cases that really need it.I think most people simply haven't worked in an environment that supports unique/linear types. So everyone assumes that you need a GC. Rust is showing that this is nonsense, as C++ has already done for people using C++11.I know C++ pretty well (using it since 1993), like it a lot, but I also think we can get better than it. Specially since I had the luck to get to know systems programming languages with GC like Modula-3 and Oberon(-2). The Oberon OS had quite a few nice concepts that go way back to Mesa/Cedar at Xerox PARC. Rust is also showing how complex a type system needs to be to handle all memory management cases. Not sure how many developers will jump into it. For example, currently you can only concatenate strings if they are both heap allocated. There are still some issues with operations that mix lifetimes being sorted out. -- Paulo
Aug 18 2014
On Monday, 18 August 2014 at 18:56:42 UTC, b wrote:With RC you pay a price during creation/deletion/sharing, ...Are you sure that there is even a cost for creation? I mean sure we have to allocate memory on the heap but the GC has to do the same thing. And with C++11 unique_ptr moves by default, so I think that the creation cost is exactly the same as with a GC. I also think that deletion is cheaper for a unique_ptr compared to a GC, because all you have to do is call the destructor when it goes out of scope. My initial question was why D uses the GC for everything. Personally it would make more sense to me if D would use the GC as a library. Let the user decide what he wants, something like shared_ptr(GC) ptr; shared_ptr(RC) ptr;
Aug 18 2014
On Monday, 18 August 2014 at 19:43:14 UTC, maik klein wrote:My initial question was why D uses the GC for everything.It isn't supposed to with nogc?Personally it would make more sense to me if D would use the GC as a library. Let the user decide what he wants, something like shared_ptr(GC) ptr; shared_ptr(RC) ptr;Memory allocation should be in the compiler/runtime to get proper optimizations. But D has apparently gone with nongc-allocators as a library feature.
Aug 18 2014
On Mon, 18 Aug 2014 19:43:13 +0000 maik klein via Digitalmars-d <digitalmars-d puremagic.com> wrote:My initial question was why D uses the GC for everything.to avoid unnecessary complications in user source code. GC is necessary for some cool D features (it was noted ealier), and GC is first-class citizen in D.Personally it would make more sense to me if D would use the GC=20 as a library.D is not C++. besides, you can write your own allocators (oh, we need more documentation on this) and avoid GC usage. so user *can* avoid GC if he wants to. take a look at std.typecons and it's 'scoped', for example.
Aug 18 2014
On Monday, 18 August 2014 at 18:56:42 UTC, b wrote:Besides that, in C++ it works like this. 90% of objects: value types, on stack or embedded into other objects 9% of objects: unique types, use unique_ptr, no overhead ~1% of objects: shared, use shared_ptr/weak_ptr etc. With GC you give up deterministic behavior, which is *absolutely* not worth giving up for 1% of objects. I think most people simply haven't worked in an environment that supports unique/linear types. So everyone assumes that you need a GC. Rust is showing that this is nonsense, as C++ has already done for people using C++11.I work in such an environment and I tend to agree with you. We use a combination of std::unique_ptr and raw pointers as weak ref. It works without hiccup even though people have to ensure manually that lifetimes of owners exceed lifetime of borrowers. A problem with scoped ownership is that it makes the pointer know about the lifetime, and that forces to give up type-safety a bit to write function taking any pointer type. In D having deterministic resource release is harder because scoped ownership is less polished than in C++.
Aug 19 2014
On Tue, 19 Aug 2014 07:14:17 +0000 ponce via Digitalmars-d <digitalmars-d puremagic.com> wrote:I work in such an environment and I tend to agree with you.just replace GC with stub doing only allocs (or use GC.disable) and manage resource freeing manually (or with corresponding templated struct wrappers).In D having deterministic resource release is harder because=20 scoped ownership is less polished than in C++.but why?! see 'scoped' to scope allocations. and, for example, 'File', which is refcounted internally. plus 'scope()' finalizers. i'm pretty sure that scoped ownership in D at least on par with C++, if not better and simplier either to write, to read and to use. of course, you'll loose such nice features as closures and slices, but hey, C++ doesn't have them too! ok, C++11 has lambdas, and i don't know if D lambdas can work without GC and don't leak.
Aug 19 2014
On Tuesday, 19 August 2014 at 07:26:07 UTC, ketmar via Digitalmars-d wrote:but why?! see 'scoped' to scope allocations. and, for example, 'File', which is refcounted internally. plus 'scope()' finalizers. i'm pretty sure that scoped ownership in D at least on par with C++, if not better and simplier either to write, to read and to use. of course, you'll loose such nice features as closures and slices, but hey, C++ doesn't have them too! ok, C++11 has lambdas, and i don't know if D lambdas can work without GC and don't leak.I'm well aware of all that exist to do deterministic destruction. There is no _composable_ way to do it apart from using structs exclusively and RefCounted!. I can't find the previous thread about this but there was problems, eg. Unique should work with both classes and structs but does not.
Aug 19 2014
On Tue, 19 Aug 2014 10:24:07 +0000 ponce via Digitalmars-d <digitalmars-d puremagic.com> wrote: seems that i misunderstand you. sorry.
Aug 19 2014
On 8/19/14, 12:25 AM, ketmar via Digitalmars-d wrote:On Tue, 19 Aug 2014 07:14:17 +0000 ponce via Digitalmars-d <digitalmars-d puremagic.com> wrote:One issue with this is e.g. hashtables have no primitive for freeing entries.I work in such an environment and I tend to agree with you.just replace GC with stub doing only allocs (or use GC.disable) and manage resource freeing manually (or with corresponding templated struct wrappers).They don't use GC if scoped. AndreiIn D having deterministic resource release is harder because scoped ownership is less polished than in C++.but why?! see 'scoped' to scope allocations. and, for example, 'File', which is refcounted internally. plus 'scope()' finalizers. i'm pretty sure that scoped ownership in D at least on par with C++, if not better and simplier either to write, to read and to use. of course, you'll loose such nice features as closures and slices, but hey, C++ doesn't have them too! ok, C++11 has lambdas, and i don't know if D lambdas can work without GC and don't leak.
Aug 19 2014
On Tuesday, 19 August 2014 at 14:13:38 UTC, Andrei Alexandrescu wrote:On 8/19/14, 12:25 AM, ketmar via Digitalmars-d wrote:And, in 2.066, it works with nogc. Scoped no-gc downward closures. alias dgFloatToFloat = float delegate(float) nogc; alias dgFloatPairToFloat = float delegate(float, float) nogc; float integrate(scope dgFloatToFloat f, float lo, float hi, size_t n) nogc { float result = 0.0; float dx = (hi - lo) / n; float dx2 = dx * 0.5; for (size_t i = 0; i < n; i++) { result += f(lo + i * dx2) * dx; } return result; } float integrate(scope dgFloatPairToFloat f, float x0, float x1, size_t nx, float y0, float y1, size_t ny) nogc { return integrate((y) => integrate((x) => f(x,y), x0, x1, nx), y0, y1, ny); } I was going to ask for an nogc { <fundefs> } to reduce the noise, but I just tried it and it seems to work. Nice!They don't use GC if scoped. Andreiof course, you'll loose such nice features as closures andslices, but hey, C++ doesn't have them too! ok, C++11 has lambdas, and i don't know if D lambdas can work without GC and don't leak.
Aug 19 2014
On Tue, 19 Aug 2014 07:13:45 -0700 Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:One issue with this is e.g. hashtables have no primitive for freeing=20 entries.ah, so don't use built-in AAs. templated class/struct can replace 'em, let with less beauty in declaration. i believe that something similar can be done with arrays and strings, and with RC slices. and 2.066 moved some built-in properties to functions, which will help too. but seems that *most* people are OK with GC, so such replacements should not be defaults. and if somebody will port Leandro's CDGC, "stop the world" problem can be avoided almost entirely. but maybe there is some sense to shipping alternate "nogc/rc" runtime with D. the main problem with that is that someone has to write and support it. ;-)that's great. i'm very used to GNU C extension, which allows nested functions and something like lambdas in C, and was very happy to find that feature ofically blessed in D. i'm even more happy now when i know for sure that they will not trigger allocations.i don't know if D lambdas can work without GC and don't leak.They don't use GC if scoped.
Aug 19 2014
On Monday, 18 August 2014 at 18:56:42 UTC, b wrote:Not really accurate. First of all, don't include unique_ptr as if it had the same overhead as the other two, it doesn't.It's still scope guarded, which is not zero cost in sjlj and win32 seh exception models. It also injects (inlines?) cleanup code everywhere, which wastes cache.With RC you pay a price during creation/deletion/sharing, but not while it is alive. With GC you pay almost no cost during allocation/deletion, but a constant cost while it is alive. You allocate enough objects and the sum cost ant so small.Quite the contrary: with RC creation and deletion should be cheaper because they don't scan whole memory, using the object is more expensive, because you need to track it always. With GC you pay the cost when collection runs, and it doesn't necessarily runs always.Besides that, in C++ it works like this. 90% of objects: value types, on stack or embedded into other objects 9% of objects: unique types, use unique_ptr, no overhead ~1% of objects: shared, use shared_ptr/weak_ptr etc.Aren't strings inherently shared? Do you think they account for only 1% of objects?With GC you give up deterministic behavior, which is *absolutely* not worth giving up for 1% of objects.Memory needs deterministic management only under condition of memory scarcity, but it's not a common case, and D allows manual memory management, but why force it on everyone because only someone needs it?
Aug 19 2014
Am Tue, 19 Aug 2014 07:23:33 +0000 schrieb "Kagamin" <spam here.lot>:Don't dismiss his point easily. The real memory cost is not always visible. Take for example bindings to GUI libraries where bitmap objects left to be garbage collected may have a 16 byte wrapper object, but several megabytes of memory associated with it inside a C library. The GC wont see the need to run a sweep and the working set blows out of proportion. (Happened to me a few years ago.) Other times you may just run out of handles because the GC is not called for a while. In practice you then add .close/.release methods to every resource object: and here we are back at malloc/free. Cycles aside, reference counting does a better job here. In other words, a GC cannot handle anything outside of the runtime it was written for, in short: OS handles and foreign language library data structures. -- MarcoWith GC you give up deterministic behavior, which is *absolutely* not worth giving up for 1% of objects.Memory needs deterministic management only under condition of memory scarcity, but it's not a common case, and D allows manual memory management, but why force it on everyone because only someone needs it?
Aug 26 2014
On Tuesday, 26 August 2014 at 07:10:32 UTC, Marco Leise wrote:In practice you then add .close/.release methods to every resource objectYes.and here we are back at malloc/free.No. GC exists because general purpose memory has different properties and used in a different ways than other resources. For example, you can't build a cycle of files. Hence different ways of management for memory and other types of resources. And people coming from unmanaged environments, like C++, should learn about that difference and how to manage resources in GC environment. I agree it's a problem there's no tutorial for that. Maybe, .net tutorials can be used to teach it.
Aug 26 2014
On Monday, 18 August 2014 at 10:01:59 UTC, maik klein wrote:Does a GC still have advantages over heap allocations that do not need to be reference counted such as the unique_ptr in c++?Isn't unique_ptr unique? What to do when the object is non-unique?
Aug 18 2014
On Monday, 18 August 2014 at 12:06:27 UTC, Kagamin wrote:On Monday, 18 August 2014 at 10:01:59 UTC, maik klein wrote:Not sure what you mean by unqiue. It's like a reference counted object but with a counter of 1, meaning if it goes out of scope it will be deleted. (But it does not do any reference counting). I think D also has a unique ptr. https://github.com/D-Programming-Language/phobos/blob/master/std/typecons.d#L58 Is it correct that when I create a class it will always be on the heap and therefore be garbage collected? class Foo .. So I don't have the option to put a class on the stack like in C++? auto foo = Foo(); //stack auto foo_ptr = new Foo(); // heap If I do something like: auto ptr = Unique(Foo); Would the GC still be used, or would the resource be freed by the destructor?Does a GC still have advantages over heap allocations that do not need to be reference counted such as the unique_ptr in c++?Isn't unique_ptr unique? What to do when the object is non-unique?
Aug 18 2014
On Monday, 18 August 2014 at 12:27:44 UTC, Maik Klein wrote:Is it correct that when I create a class it will always be on the heap and therefore be garbage collected? class Foo .. So I don't have the option to put a class on the stack like in C++? auto foo = Foo(); //stack auto foo_ptr = new Foo(); // heap If I do something like: auto ptr = Unique(Foo); Would the GC still be used, or would the resource be freed by the destructor?
Aug 18 2014
On 18/08/2014 13:27, Maik Klein wrote:If I do something like: auto ptr = Unique(Foo); Would the GC still be used, or would the resource be freed by the destructor?It uses GC allocation, but the memory will be freed deterministically: { Unique!Foo u = new Foo; // u's destructor will call 'delete' on its instance of Foo here }
Aug 18 2014
On Monday, 18 August 2014 at 12:06:27 UTC, Kagamin wrote:On Monday, 18 August 2014 at 10:01:59 UTC, maik klein wrote:Yes, unique_ptr is unique :-) It is not reference counted -- it just destroys the owned object when it goes out of scope. The near thing about unique_ptrs is that you can move them around, transferring ownership. If the object is non-unique, then typically C++ programmers will use shared_ptr (+ weak_ptr). I'm not sure what the status of std.typecons.Unique is. Last I heard it had some issues, but I haven't tried it much myself.Does a GC still have advantages over heap allocations that do not need to be reference counted such as the unique_ptr in c++?Isn't unique_ptr unique? What to do when the object is non-unique?
Aug 18 2014
On Monday, 18 August 2014 at 12:55:52 UTC, Peter Alexander wrote:On Monday, 18 August 2014 at 12:06:27 UTC, Kagamin wrote:So if it's not known to be unique beforehand, the safe bet is to use shared_ptr, if the ownership is not known beforehand, the safe bet is to not use weak_ptr, then you are left with all references annotated with spurious shared_ptr all over the place. It will be also easy to mess up the annotations and get dangling pointer.On Monday, 18 August 2014 at 10:01:59 UTC, maik klein wrote:Yes, unique_ptr is unique :-) It is not reference counted -- it just destroys the owned object when it goes out of scope. The near thing about unique_ptrs is that you can move them around, transferring ownership. If the object is non-unique, then typically C++ programmers will use shared_ptr (+ weak_ptr). I'm not sure what the status of std.typecons.Unique is. Last I heard it had some issues, but I haven't tried it much myself.Does a GC still have advantages over heap allocations that do not need to be reference counted such as the unique_ptr in c++?Isn't unique_ptr unique? What to do when the object is non-unique?
Aug 18 2014
On 18/08/2014 13:55, Peter Alexander wrote:I'm not sure what the status of std.typecons.Unique is. Last I heard it had some issues, but I haven't tried it much myself.It should work, but it is bug-prone without the disable this(this) fix in master. Unfortunately that won't make it into 2.066. Also, the web docs lack a concrete example - I have a pull which fixes that: https://github.com/D-Programming-Language/phobos/pull/2346
Aug 18 2014
Various reasons: 1. Memory safety. A whole class of bugs are eliminated by the use of a GC. 2. It is faster on multithreaded systems than RC (as the reference count must be synchronized properly). 3. Having all the heap under GC control is important so that the GC won't delete live objects. If you are willing to get rid of 1., D's allow you to free object from the GC explicitly via GC.free, which will bring you back to a manual memory management safety and performance level, but will still provide you with a protection net against memory leaks.
Aug 18 2014