www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - live questions

reply Dibyendu Majumdar <mobile majumdar.org.uk> writes:
Hi

I don't quite know Rust so it is bit hard to compare this feature 
with Rust. Ideally someone who knows both languages in depth 
should compare and figure out if  live is comparable to Rust 
ownership ideas.

I have following questions / suggestions:

a) I understand on its own  live is only part of what Rust does? 
Rust has lifetime annotations and I believe it can track memory 
allocation across a graph of objects and ensure there is no leak 
etc. Is my understanding correct that  live only deals with 
pointers and to compare this to Rust, one has to also include 
DIP1000?

My first suggestion is that  live and DIP1000 features should be 
documented together. I heard in the discussions that DIP1000 is 
actually not yet documented?

b) Is it also the case that DIP1000 is only available if a 
function is marked  safe?

It seems to me that both  live and  safe should be available as 
compiler flags to turn them on - and not have to rely on 
annotations. Is this possible? Certainly in Laser-D I would like 
these to be ON by default and annotation should be to suppress 
rather than enable.
Nov 21 2020
next sibling parent Max Haughton <maxhaton gmail.com> writes:
On Sunday, 22 November 2020 at 02:28:20 UTC, Dibyendu Majumdar 
wrote:
 Hi

 I don't quite know Rust so it is bit hard to compare this 
 feature with Rust. Ideally someone who knows both languages in 
 depth should compare and figure out if  live is comparable to 
 Rust ownership ideas.

 I have following questions / suggestions:

 a) I understand on its own  live is only part of what Rust 
 does? Rust has lifetime annotations and I believe it can track 
 memory allocation across a graph of objects and ensure there is 
 no leak etc. Is my understanding correct that  live only deals 
 with pointers and to compare this to Rust, one has to also 
 include DIP1000?

 My first suggestion is that  live and DIP1000 features should 
 be documented together. I heard in the discussions that DIP1000 
 is actually not yet documented?

 b) Is it also the case that DIP1000 is only available if a 
 function is marked  safe?

 It seems to me that both  live and  safe should be available as 
 compiler flags to turn them on - and not have to rely on 
 annotations. Is this possible? Certainly in Laser-D I would 
 like these to be ON by default and annotation should be to 
 suppress rather than enable.
a) Current measures are indeed not as thorough as rust's. b) No. If you want to implement the switch you can but it would not only break a lot of code (live is not ready for prime time for example) but immediately fragment the language. The memory safety features are not properly documented but the specification is not without mention of them, but in general the language is woefully underspecified.
Nov 21 2020
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 22.11.20 03:28, Dibyendu Majumdar wrote:
 Hi
 
 I don't quite know Rust so it is bit hard to compare this feature with 
 Rust. Ideally someone who knows both languages in depth should compare 
 and figure out if  live is comparable to Rust ownership ideas.
 
 I have following questions / suggestions:
 
 a) I understand on its own  live is only part of what Rust does? Rust 
 has lifetime annotations and I believe it can track memory allocation 
 across a graph of objects and ensure there is no leak etc. Is my 
 understanding correct that  live only deals with pointers and to compare 
 this to Rust, one has to also include DIP1000?
 ...
live is not particularly comparable to what Rust does. Rust ensures safety modularly, while live does not. Memory ownership is not built into Rust at the language level, only borrowing is. Forcing ownership semantics on built-in pointers does not make a lot of sense, as they have no associated allocator so pointer deallocation remains unsafe.
 My first suggestion is that  live and DIP1000 features should be 
 documented together. I heard in the discussions that DIP1000 is actually 
 not yet documented?
 
 b) Is it also the case that DIP1000 is only available if a function is 
 marked  safe?
 ...
` live` attempts to respect `return` annotations on scoped pointers even in system code. E.g., this works as expected: --- import core.stdc.stdlib; int* foo(return scope int* x) live{ return x; } live void main(){ int* p=cast(int*)malloc(int.sizeof); scope int* q=foo(p); free(p); } --- But I think there isn't really a coherent lifetime design, e.g., this is a memory leak: --- import core.stdc.stdlib; struct S{int* a,b;} void main() live{ auto q=S(cast(int*)malloc(int.sizeof),cast(int*)malloc(int.sizeof)); free(q.a); } --- And of course, as soon as you use the standard library all bets are off, e.g. this is a double free in elegant range notation: --- import std.range, core.stdc.stdlib; void main() live{ repeat(cast(int*)malloc(int.sizeof),2).each!free; } --- It also works with a standard `foreach` loop: void main() live{ foreach(p;repeat(cast(int*)malloc(int.sizeof),2)) free(p); }
 It seems to me that both  live and  safe should be available as compiler 
 flags to turn them on - and not have to rely on annotations. Is this 
 possible? Certainly in Laser-D I would like these to be ON by default 
 and annotation should be to suppress rather than enable.
` live safe` makes no sense. Per the documentation, ` safe` already ensures memory safety on its own and ` live` is just a bunch of checks and dataflow analysis without an underlying modular safety story. Indeed, putting ` safe` on the examples above will correctly reject them. Also, there is no keyword to disable ` live`.
Nov 21 2020
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/21/2020 7:37 PM, Timon Gehr wrote:
 ` live  safe` makes no sense. Per the documentation, ` safe` already ensures 
 memory safety on its own
Only if you're using the GC to manage memory. safe does not deal with lining up mallocs and frees. It's also not going to manage the memory of containers (your first example) - the user will be expected to craft the container to take care of that, for example by boxing the owning pointer.
 and ` live` is just a bunch of checks and dataflow 
 analysis without an underlying modular safety story. Indeed, putting ` safe`
on 
 the examples above will correctly reject them.
live is not redundant with nor a replacement for safe. It enables a specific set of checks that are independent from system/ trusted/ safe, though it is best used with safe.
 Also, there is no keyword to disable ` live`.
That's right. If that's the big problem with live, I'd consider live a resounding success :-/ Please understand that the current live implementation is a prototype. I expect we'll be learning a lot about how to use it properly. Rust went through considerable evolution, too. I don't expect live to wind up in the same place as Rust any more than D's functional programming capabilities turn it into Haskell.
Nov 21 2020
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Sunday, 22 November 2020 at 07:44:51 UTC, Walter Bright wrote:
 I don't expect  live to wind up in the same place as Rust any 
 more than D's functional programming capabilities turn it into 
 Haskell.
It is ok that you only do analysis of the call stack and not the heap, but it has to be context sensitive. You need to analyse all functions that call live functions and all functions that live calls. I read this paper this morning, and I found it to be a nice overview, although covering more ground than alias-analysis: https://yanniss.github.io/points-to-tutorial15.pdf You might also consider building on the datalog engine in Z3. It is written in C++, so it should be easy to integrate
Nov 22 2020
prev sibling next sibling parent reply jmh530 <john.michael.hall gmail.com> writes:
On Sunday, 22 November 2020 at 07:44:51 UTC, Walter Bright wrote:
 [snip]
 and ` live` is just a bunch of checks and dataflow analysis 
 without an underlying modular safety story. Indeed, putting 
 ` safe` on the examples above will correctly reject them.
live is not redundant with nor a replacement for safe. It enables a specific set of checks that are independent from system/ trusted/ safe, though it is best used with safe.
[snip] I haven't had a chance to watch DConf Online yet, but my understanding is that live would enable more things to be marked as safe. Is my understanding correct?
Nov 22 2020
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 22.11.20 18:28, jmh530 wrote:
 On Sunday, 22 November 2020 at 07:44:51 UTC, Walter Bright wrote:
 [snip]
 and ` live` is just a bunch of checks and dataflow analysis without 
 an underlying modular safety story. Indeed, putting ` safe` on the 
 examples above will correctly reject them.
live is not redundant with nor a replacement for safe. It enables a specific set of checks that are independent from system/ trusted/ safe, though it is best used with safe.
[snip] I haven't had a chance to watch DConf Online yet, but my understanding is that live would enable more things to be marked as safe. Is my understanding correct?
No.
Nov 22 2020
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 22.11.20 08:44, Walter Bright wrote:
 On 11/21/2020 7:37 PM, Timon Gehr wrote:
 ` live  safe` makes no sense. Per the documentation, ` safe` already 
 ensures memory safety on its own
Only if you're using the GC to manage memory.
No, always. ` safe` means memory safe, it does not mean you are using the GC.
  safe does not deal with lining up mallocs and frees.
That's because safe does not deal with `free` at all. `free` is not memory safe.
 It's also not going to manage the memory of 
 containers (your first example) - the user will be expected to craft the 
 container to take care of that, for example by boxing the owning pointer.
 ...
My point was exactly that ` live` does not help containers manage their lifetimes. You can't create a struct with a ` live` constructor and in ` live` functions the compiler will drop the entire container if you access a single pointer within it.
 
 and ` live` is just a bunch of checks and dataflow analysis without an 
 underlying modular safety story. Indeed, putting ` safe` on the 
 examples above will correctly reject them.
live is not redundant with nor a replacement for safe.
My point was that it does not make much sense to use ` live` in ` safe` code, as it can't prevent any additional memory corruption.
 It enables a 
 specific set of checks that are independent from  system/ trusted/ safe, 
Absolutely.
 though it is best used with  safe.
 ...
I highly doubt that. None of your (highly stylized) practical examples of ` live` checks are within ` safe` code.
 
 Also, there is no keyword to disable ` live`.
That's right. If that's the big problem with live, ..
It really isn't. This point was not a criticism of live, it is a criticism of the idea to make it the default in that Laser-D project.
 Please understand that the current  live implementation is a prototype.
I do. What I don't understand is where it's supposed to go. I.e., will this ever be anything but a prototype? You can have an idea how it should work before it's fully implemented; it's even typical for a prototype to partially implement some larger vision.
 I expect we'll be learning a lot about how to use it properly. Rust went 
 through considerable evolution, too.
As I said, live is not closely related to Rust. It performs checks that seem superficially similar to some of the checks in Rust. That's the extent of the similarity. If live was intended to provide modular safety guarantees like the Rust type system does, it does so in the way some people intended to attract cargo by building life-size models of airplanes out of wood. Rust had a plan, started with workable designs that were too complicated, then simplified, ergo multiple iterations. Safe memory management via type system was the central point of the language design. ` live` does not work in this way, it just does some checks. And those checks may or may not be useful in ` system` code under very specific circumstances.
 I don't expect  live to wind up in the same place as Rust
By the way, we _can't_ just copy Rust. Rust's model does not support tracing GC. In the past, I have made specific suggestions for how to approach lifetime management in D.
 any more than D's functional programming capabilities turn it into Haskell.
That's because the central points of Haskell are lazy evaluation and Hindley-Milner type inference, not the (presumed) lack of global state.
Nov 22 2020
parent reply Dibyendu Majumdar <mobile majumdar.org.uk> writes:
On Sunday, 22 November 2020 at 19:32:59 UTC, Timon Gehr wrote:

 This point was not a criticism of  live, it is a criticism of 
 the idea to make it the default in that Laser-D project.
I was thinking mainly about safe ... live cannot be made default because user has to decide where it is useful. And as mentioned in another post, I think this probably means it is redundant ... I personally dislike annotations and would prefer code in Laser-D to be clean - i.e. as noise free as possible. I will probably not document any of the annotations - obviously a perception is that these things help, but I am not sure there is any real measurable evidence that they are any better than already existing tools such as ASAN or valgrind. Rust is different because it really goes to the extreme to allow complete object graphs to be memory safe.
Nov 22 2020
parent Dibyendu Majumdar <mobile majumdar.org.uk> writes:
On Sunday, 22 November 2020 at 20:33:25 UTC, Dibyendu Majumdar 
wrote:

 Rust is different because it really goes to the extreme to 
 allow complete object graphs to be memory safe.
Actually this statement is incorrect. I meant to say that Rust goes to the extreme to ensure that at compile time it can determine whether an object graph is memory safe. It tries to guarantee that if you can compile it then it is safe (I am excluding unsafe constructs here).
Nov 22 2020
prev sibling parent reply thedeemon <dlang thedeemon.com> writes:
On Sunday, 22 November 2020 at 07:44:51 UTC, Walter Bright wrote:

 Please understand that the current  live implementation is a 
 prototype. I expect we'll be learning a lot about how to use it 
 properly. Rust went through considerable evolution, too. I 
 don't expect  live to wind up in the same place as Rust any 
 more than D's functional programming capabilities turn it into 
 Haskell.
Are there any meaningful code examples using live to look at and learn? So far I'm struggling to see how one would write any live code at all, e.g. how would I create an array of objects and sort it. Even simpler case I'm struggling with: create a pair of objects, choose one of them dynamically and show it to the user, then release the objects. Something like struct S { string name; } live void show(scope const S* p) { // this works writeln(p.name); } void release(S *p) { } // consumes the ownership // how do I make this work? live auto longer(scope const S* a, scope const S* b) { if (a.name.length > b.name.length) return a; else return b; } live void foo() { auto a = new S("aaa"); auto b = new S("bb"); auto c = longer(a,b); // I need a reference to one of them show(c); release(a); release(b); } This doesn't compile and I wonder how to fix this.
Nov 22 2020
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 23.11.20 01:21, thedeemon wrote:
 
  live void foo()
 {
      auto a = new S("aaa");
      auto b = new S("bb");
 
      auto c = longer(a,b); // I need a reference to one of them
      show(c);
 
      release(a);
      release(b);
 }
 
 This doesn't compile and I wonder how to fix this.
scope c = longer(a,b);
Nov 22 2020
parent thedeemon <dlang thedeemon.com> writes:
On Monday, 23 November 2020 at 03:39:21 UTC, Timon Gehr wrote:

 scope c = longer(a,b);
Thanks! This works indeed, and makes sense.
Nov 23 2020
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/21/2020 6:28 PM, Dibyendu Majumdar wrote:
 a) I understand on its own  live is only part of what Rust does? Rust has 
 lifetime annotations and I believe it can track memory allocation across a
graph 
 of objects and ensure there is no leak etc.
Rust has an additional capability of specifying which function argument lifetime gets attached to the return type, whereas live just takes the tightest lifetime of the supplied arguments. This was discussed a while back, and this extra (and optional) specification does not appear to add much value. We can always add it later if it turns out to be critical.
 Is my understanding correct that 
  live only deals with pointers and to compare this to Rust, one has to also 
 include DIP1000?
DIP1000 is intended to be a core feature, not an optional one. It's been around long enough and is successful enough to become the default. live assumes DIP1000.
 My first suggestion is that  live and DIP1000 features should be documented 
 together. I heard in the discussions that DIP1000 is actually not yet
documented?
DIP1000 will be for all D code, not just live.
 b) Is it also the case that DIP1000 is only available if a function is marked 
  safe?
It's an enhancement for safe, yes.
 It seems to me that both  live and  safe should be available as compiler flags 
 to turn them on - and not have to rely on annotations. Is this possible? 
 Certainly in Laser-D I would like these to be ON by default and annotation
 should be to suppress rather than enable.
My DIP to make safe the default failed. Turning live on by default would be brutal :-)
Nov 21 2020
next sibling parent reply Dibyendu Majumdar <mobile majumdar.org.uk> writes:
On Sunday, 22 November 2020 at 07:22:22 UTC, Walter Bright wrote:
 On 11/21/2020 6:28 PM, Dibyendu Majumdar wrote:
 a) I understand on its own  live is only part of what Rust 
 does? Rust has lifetime annotations and I believe it can track 
 memory allocation across a graph of objects and ensure there 
 is no leak etc.
Rust has an additional capability of specifying which function argument lifetime gets attached to the return type, whereas live just takes the tightest lifetime of the supplied arguments. This was discussed a while back, and this extra (and optional) specification does not appear to add much value. We can always add it later if it turns out to be critical.
Hi Walter, are you aware of the explicit lifetime annotation facility in Rust? https://doc.rust-lang.org/rust-by-example/scope/lifetime/explicit.html This seems critical to allow correct lifetime calculations in a graph of objects. I read in DIP1000 that there is an automatic lifetime calculation when 'scope' storage class is used? However does that work with nested object graphs? Rust had to have explicit annotations I believe as automated calculations are not sufficient.
Nov 22 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 11/22/2020 3:08 AM, Dibyendu Majumdar wrote:
 Hi Walter, are you aware of the explicit lifetime annotation facility in Rust?
Yes, and that was part of the discussion.
 This seems critical to allow correct lifetime calculations in a graph of
objects.
 
 I read in DIP1000 that there is an automatic lifetime calculation when 'scope' 
 storage class is used? However does that work with nested object graphs?
 
 Rust had to have explicit annotations I believe as automated calculations are 
 not sufficient.
I recall the examples given for why explicit annotations were needed were insufficiently compelling. But we'll see how things unfold.
Nov 25 2020
prev sibling next sibling parent reply Dibyendu Majumdar <mobile majumdar.org.uk> writes:
On Sunday, 22 November 2020 at 07:22:22 UTC, Walter Bright wrote:

 b) Is it also the case that DIP1000 is only available if a 
 function is marked  safe?
It's an enhancement for safe, yes.
 It seems to me that both  live and  safe should be available 
 as compiler flags to turn them on - and not have to rely on 
 annotations. Is this possible?
 Certainly in Laser-D I would like these to be ON by default
and annotation
 should be to suppress rather than enable.
My DIP to make safe the default failed. Turning live on by default would be brutal :-)
I read DIP1028. However, my suggestion is somewhat different - it is to allow a compiler flag - say -fdefault-safe - such that any code that is not annotated explicitly gets a default of safe. Thus anyone using this flag would not need to explicitly annotate with safe. I also suggest not changing the meaning of anything other than just defaulting as above. live is more complicated I suppose as it can't deal with GC pointers?
Nov 22 2020
next sibling parent reply Dibyendu Majumdar <mobile majumdar.org.uk> writes:
On Sunday, 22 November 2020 at 11:14:00 UTC, Dibyendu Majumdar 
wrote:

  live is more complicated I suppose as it can't deal with GC 
 pointers?
Another point is if live is only usable on functions that take non-GC pointers then someone who uses this is probably already having to analyse manually to decide whether to apply live, which kind of makes it redundant?
Nov 22 2020
parent Ola Fosheim Grostad <ola.fosheim.grostad gmail.com> writes:
On Sunday, 22 November 2020 at 11:25:11 UTC, Dibyendu Majumdar 
wrote:
 On Sunday, 22 November 2020 at 11:14:00 UTC, Dibyendu Majumdar 
 wrote:

  live is more complicated I suppose as it can't deal with GC 
 pointers?
Another point is if live is only usable on functions that take non-GC pointers then someone who uses this is probably already having to analyse manually to decide whether to apply live, which kind of makes it redundant?
Yes, this kind of pointer analysis really need to be done for the whole program. And there is no need to do it for every compile, so... Make dmd generate the verification source and use an external tool for verification... live is not heading where it should be.
Nov 22 2020
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/22/2020 3:14 AM, Dibyendu Majumdar wrote:
  live is more complicated I suppose as it can't deal with GC pointers?
It's not that it can't deal with them. It's that it treats them as any other pointer. Adding a type constructor that says "this pointer is a GC pointer" is a major escalation in complexity of the language. Other languages have done it (see Microsoft's "Managed C++") but I don't think it caught on because I haven't heard much about it in years.
Nov 25 2020
next sibling parent reply Dukc <ajieskola gmail.com> writes:
On Wednesday, 25 November 2020 at 10:51:12 UTC, Walter Bright 
wrote:
 On 11/22/2020 3:14 AM, Dibyendu Majumdar wrote:
  live is more complicated I suppose as it can't deal with GC 
 pointers?
It's not that it can't deal with them. It's that it treats them as any other pointer.
As what kind of other pointer? I quess `new int()` returns a pointer that is treated as `return scope`, right?
Nov 25 2020
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/25/2020 8:42 PM, Dukc wrote:
 On Wednesday, 25 November 2020 at 10:51:12 UTC, Walter Bright wrote:
 On 11/22/2020 3:14 AM, Dibyendu Majumdar wrote:
  live is more complicated I suppose as it can't deal with GC pointers?
It's not that it can't deal with them. It's that it treats them as any other pointer.
As what kind of other pointer? I quess `new int()` returns a pointer that is treated as `return scope`, right?
No, it returns `int*`.
Nov 25 2020
parent reply Dukc <ajieskola gmail.com> writes:
On Thursday, 26 November 2020 at 06:28:03 UTC, Walter Bright 
wrote:
 As what kind of other pointer? I quess `new int()` returns a 
 pointer that is treated as `return scope`, right?
No, it returns `int*`.
Huh? Won't that make the compiler to think the programmer is leaking the pointer when it exits the scope? If I understood correctly, ` live` requires freeing any non-null `int*`, or forwarding them to a function that takes them as non-scoped `int*`.
Nov 26 2020
parent Dukc <ajieskola gmail.com> writes:
On Thursday, 26 November 2020 at 13:07:38 UTC, Dukc wrote:
 Huh? Won't that make the compiler to think the programmer is 
 leaking the pointer when it exits the scope? If I understood 
 correctly, ` live` requires freeing any non-null `int*`, or 
 forwarding them to a function that takes them as non-scoped 
 `int*`.
Or do you mean one has to do this: ``` void leak(T)(T* ptr){} live void useGc() { auto ptr = new int(5); writeln(*ptr); ptr.leak; } ``` ? Now when I think of it, it might make some sense. You obviously do not want this when all memory is garbage-collected or intentionally leaked. But if one has to use `free()` it might be worth the additional hassle.
Nov 26 2020
prev sibling next sibling parent reply Gordan <gman-george gmail.com> writes:
On Wednesday, 25 November 2020 at 10:51:12 UTC, Walter Bright 
wrote:
 Other languages have done it (see Microsoft's "Managed C++") 
 but I don't think it caught on because I haven't heard much 
 about it in years.
Yes, it was called VC++, there were 2-3 versions to try and jump start it. Eventually it was replaced by a completely native C++ header file using modern C++ with smart pointers instead of a GC to communicate with COM objects. The C++ header implementation hasn't seen any major developments but it is still their recommended way of interfacing. By the looks of it they are focusing more on Rust and seem to be cutting out C++ altogether.
Nov 25 2020
parent Paulo Pinto <pjmlp progtools.org> writes:
On Thursday, 26 November 2020 at 05:24:22 UTC, Gordan wrote:
 On Wednesday, 25 November 2020 at 10:51:12 UTC, Walter Bright 
 wrote:
 Other languages have done it (see Microsoft's "Managed C++") 
 but I don't think it caught on because I haven't heard much 
 about it in years.
Yes, it was called VC++, there were 2-3 versions to try and jump start it. Eventually it was replaced by a completely native C++ header file using modern C++ with smart pointers instead of a GC to communicate with COM objects. The C++ header implementation hasn't seen any major developments but it is still their recommended way of interfacing. By the looks of it they are focusing more on Rust and seem to be cutting out C++ altogether.
You mean C++/CX, which was replaced by C++/WinRT. C++/CLI, the .NET variant is alive and doing quite well as more productive way to interface with native code than doing a bunch of P/Invoke declarations all over the place. As for C++/WinRT, unless we are talking about Windows dev team members used to write code with Windows Runtime Library previously, the large majority of UWP devs is quite pissed off with C++/WinRT, because Windows dev team has thrown it at us without any consideration for providing a Visual Studio experience comparable to C++/CX. So you are left editing IDL files without any kind of editor experience, and every time wrappers are generated by cppwinrt compiler, you need to manually copy and merge the outcome. Wait for ISO C++ to reach feature parity with C++/CX in metadata and reflection capabilities they say. COM libraries approach has always been header files generated out of COM type libraries (.tlb) or now with the UWP/WinRT related improvements, .NET Metadata files (.winmd). Also to have a good performance in Release/AddRef calls versus .NET GC, C++/WinRT makes use of background threads for disposal, stack allocation of handles for COM/UWP references and constexpr generation of metadata.
Nov 26 2020
prev sibling parent IGotD- <nise nise.com> writes:
On Wednesday, 25 November 2020 at 10:51:12 UTC, Walter Bright 
wrote:
 It's not that it can't deal with them. It's that it treats them 
 as any other pointer.

 Adding a type constructor that says "this pointer is a GC 
 pointer" is a major escalation in complexity of the language. 
 Other languages have done it (see Microsoft's "Managed C++") 
 but I don't think it caught on because I haven't heard much 
 about it in years.
The problem I can't see any way out of this, we need a managed pointer type. For example if we want to change the GC type globally (everything in libraries like arrays and so on) we need some kind of fat pointer that is generic. Now we are stuck in tracing GC land forever and projects cannot choose what GC that suits their need. Sure we have a reference counted in the library but this is something the programmer adds but the library is still using traced GC. Only raw pointers is limiting the versatility of D.
Nov 27 2020
prev sibling next sibling parent reply ag0aep6g <anonymous example.com> writes:
On 22.11.20 08:22, Walter Bright wrote:
 DIP1000 is intended to be a core feature, not an optional one. It's been 
 around long enough and is successful enough to become the default.  live 
 assumes DIP1000.
So far, DIP1000 is not a success. It's buggy, poorly documented, hard to understand. Phobos only compiles with -preview=dip1000 by relying on accepts-invalid bugs.
Nov 22 2020
parent Walter Bright <newshound2 digitalmars.com> writes:
On 11/22/2020 3:38 AM, ag0aep6g wrote:
 So far, DIP1000 is not a success. It's buggy, poorly documented, hard to 
 understand.
 Phobos only compiles with -preview=dip1000 by relying on 
 accepts-invalid bugs.
I've already talked about the documentation being inadequate. As for the rest, when saying such things please include a list of bugzilla issues. If you know of issues that are not in bugzilla, please add them.
Nov 25 2020
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 22.11.20 08:22, Walter Bright wrote:
 
 It seems to me that both  live and  safe should be available as 
 compiler flags to turn them on - and not have to rely on annotations. 
 Is this possible? 
> Certainly in Laser-D I would like these to be ON by default and annotation > should be to suppress rather than enable. My DIP to make safe the default failed. ...
(You could have addressed the problems with the proposal instead of retracting it, in which case it would likely have succeeded.)
 Turning  live on by default would be brutal :-)
It would also be stupid. ` live` is not some sound extension of ` safe`, it's orthogonal and it's really only useful in some niche kinds of ` system` code.
Nov 22 2020
prev sibling parent reply IGotD- <nise nise.com> writes:
On Sunday, 22 November 2020 at 07:22:22 UTC, Walter Bright wrote:
 Turning  live on by default would be brutal :-)
If you take this example. struct MyStruct { int s; } MyStruct*[string] nameLookup; MyStruct*[int] idLookup; live void addStruct(scope MyStruct* s, const string name, int id) { nameLookup[name] = s; idLookup[id] = s; } void main() { MyStruct* s = new MyStruct; addStruct(s, "id1", 1); } In the presentation you basically did a copy of the single ownership in Rust. In the function we assign nameLookup and idLookup with a borrowed pointer but not as owners. This currently compiles but your presentation I get the impression that you are going to put D under full single ownership lockdown. If I would remove the scope for the s parameter in addStruct then it would emit an error when trying to assign to idLookup as s is already consumed by nameLookup.
Nov 23 2020
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/23/2020 3:17 AM, IGotD- wrote:
 In the presentation you basically did a copy of the single ownership in Rust.
In 
 the function we assign nameLookup and idLookup with a borrowed pointer but not 
 as owners. This currently compiles
It shouldn't as nameLookup and idLoopup are globals. Looks like you found a bug!
 but your presentation I get the impression 
 that you are going to put D under full single ownership lockdown.
Sorry if I gave that impression. It will only be so at your discretion with where you place live.
Nov 25 2020
parent IGotD- <nise nise.com> writes:
On Wednesday, 25 November 2020 at 10:42:02 UTC, Walter Bright 
wrote:
 It shouldn't as nameLookup and idLoopup are globals. Looks like 
 you found a bug!

 Sorry if I gave that impression. It will only be so at your 
 discretion with where you place  live.
Yes, but you get the idea. If I would put nameLookup and idLookup in a struct for example which is usually the case, then I'm not sure what applies. struct MyStruct { int s; } struct LookUp { live void addStruct(MyStruct* s, const string name, int id) { nameLookup[name] = s; idLookup[id] = s; } private: MyStruct*[string] nameLookup; MyStruct*[int] idLookup; } void main() { MyStruct* s = new MyStruct; LookUp l; l.addStruct(s, "id1", 1); } Putting nameLookup and idLoopup in a struct also works with the DIP1000 preview which contradicts you presentation but I guess this is only a prototype. If I'm going to interpret your presentation, then an assignment of a pointer is a move with change of ownership just like Rust. Then you mention in this thread that you want to make live default, and this really worries me. Basically forced single ownership makes the common design pattern in the example above impossible and this is something people who use Rust must battle all the time (I guess they just use reference counted objects which is GC). If want to implement lifetime analysis then you need to go the full way which includes single ownership otherwise it isn't solvable. A half variant, the question is here is how useful such implementation would be. One possibility is that you make functions the barrier where the data flow analysis works, so addStruct would not be allowed to be live and inside that function is "do whatever you want" territory. This of course contradicts making live default.
Nov 25 2020