October 08, 2015
Am Sun, 04 Oct 2015 23:28:47 +0000
schrieb Jonathan M Davis <jmdavisProg@gmx.com>:

> On Sunday, 4 October 2015 at 21:41:00 UTC, rsw0x wrote:
> > If D has no intentions of aiding the GC, then the GC should just be dropped because it's basically just slapping Boehm on C++ right now.
> 
> I don't understand this attitude at all (and you're not the only one to voice it lately). D has a ton to offer and so little of it has anything to do with the GC. The delegate/lambda/closure situation is generally saner thanks to the GC (at least as far as safety goes), and arrays have some fantastic features thanks to the GC, but D has _way_ more to offer than that, and most of it has nothing to do with the GC. D's templates alone blow C++ totally out of the water. C++ is a great language, and I love it. But at this point, I only use it when I have to. D is just _so_ much more pleasant to program in that I have no interest in programming in C++ anymore. It's been years since I've done any kind of pet project in C++.
> 
> - Jonathan M Davis

It was probably bad wording. I understood it as D's GC works on a similar basis as Boehm now - conservative, stop the world mark & sweep. The reason in both being the nature of the host language. In fact the German Wikipedia says that Boehm GC was ported with minimal changes to druntime.

-- 
Marco

October 08, 2015
On Thursday, 8 October 2015 at 16:25:00 UTC, Marco Leise wrote:
> Am Sun, 04 Oct 2015 23:28:47 +0000
> schrieb Jonathan M Davis <jmdavisProg@gmx.com>:
>
>> [...]
>
> It was probably bad wording. I understood it as D's GC works on a similar basis as Boehm now - conservative, stop the world mark & sweep. The reason in both being the nature of the host language. In fact the German Wikipedia says that Boehm GC was ported with minimal changes to druntime.

Yes, this is what I was implying. Sorry if it was poorly worded.
D does not provide the GC with any support, it is like dropping boehm in C++.
October 08, 2015
On 10/08/2015 05:20 AM, Shachar Shemesh wrote:
> On 07/10/15 12:58, Timon Gehr wrote:
>
>>> Shachar
>>
>> struct S{
>>      @disable this();
>>      @disable enum init=0;
>> }
>>
>> void main(){
>>      S s; // error
>>      auto d=S.init; // error
>> }
>>
>
> An honest question. Would that also cover all cases where init is being
> used implicitly by the compiler?
> ...

Construction does not currently work without init, but there it is no problem. Anyway, the right question is whether there is any way that the invariant of a type can be broken by bypassing the constructor using only @safe features. That's actually what @disable this() should prevent, apparently modulo explicit usages of init (which does not make that much sense).

> I will need to do some research myself, but my gut feeling is "no".
> There are several cases where the compiler replaces the value with the
> init value, and I doubt your horrid hack changes that.
> ...

I would consider any way that init sneaks in unexpectedly to be a compiler bug related to @disable this().

> Either way, I think you'll agree that D needs to be better in defining
> what is the correct path to take on this, as, currently, nobody seems to
> know for sure.
>

Obviously. Overriding of init should be removed and the use case should be supported in a different way. (This could probably just be, e.g., make @disable this() also disable init.) I just showed what we've got, and, for better or worse, it's actually in the language by design.
October 08, 2015
On 10/08/2015 06:09 PM, Marco Leise wrote:
> Am Mon, 5 Oct 2015 12:22:59 +0300
> schrieb Shachar Shemesh <shachar@weka.io>:
>
>> On 05/10/15 10:01, Dmitry Olshansky wrote:
>>
>>>> When D structs has a destructor that is guaranteed to run for any
>>>> instance that finished construction, no matter what is the use case,
>>>> then we can have that discussion.
>>>>
>>>
>>> Supposed to be the case for structs except for any bugs.
>>>
>>
>> Check this one out (no instances on heap):
>> import std.stdio;
>>
>> struct destructible {
>>       int id;
>>
>>       @disable this();
>>       this( int id ) {
>>           writeln("Id ", id, " constructed");
>>           this.id = id;
>>       }
>>
>>       ~this() {
>>           writeln("Id ", id, " destructed");
>>       }
>> }
>>
>> void main() {
>>       struct container {
>>           destructible d;
>>
>>           @disable this();
>>           this( int id )
>>           {
>>               this.d = destructible(id);
>>               throw new Exception("some random exception");
>>           }
>>       }
>>
>>       try {
>>           container(2);
>>       } catch( Exception ex ) {
>>           writeln("Caught ", ex.msg);
>>       }
>> }
>>
>> As of dmd 2.068.2, the output is:
>> Id 2 constructed
>> Caught Some random exception
>>
>> Of course, if I do not disable this(), things are even worse.
>
> Damn this is sneaky! Now the statements
>
> "When D structs has a destructor that is guaranteed to run for
> any instance that finished construction."
>
> "When construction fails, the dtor is not run on that
> half-constructed object. Instead it is the ctors
> responsibility to roll back its actions."
>
> collide with a struct that finished construction embedded in a
> struct that failed construction. This is a deadlock.
>

Why? As I interpret those two statements, the fields that have finished construction should just be destroyed even if the enclosing object has not finished construction (and is hence not destroyed).

October 09, 2015
On 08/10/15 18:58, Marco Leise wrote:
> Am Mon, 05 Oct 2015 13:42:50 +0000
> schrieb Adam D. Ruppe <destructionator@gmail.com>:
>
>> On Monday, 5 October 2015 at 07:40:35 UTC, deadalnix wrote:
>>> Not on the heap. There are many cases where the destructor
>>> won't run and it is allowed by spec. We should do better.
>>
>> To be fair, if you new a struct in C++ and never delete it, the
>> destructor will never run there either. D's in the same boat in
>> that regard.
>
> But the D boat reads "Garbage Collector". And besides, D now
> runs dtors on new'd structs. The "many cases" may be different
> ones than you imagine.
>

There is an inherent contradiction between GC and destruction. The GC's unpredictable nature runs counter to the reason you usually want a struct to have a destructor in the first place. With that said, D has improved on that front.

By this discussion started out with using containers in order to avoid using the GC. As such, those cases are less relevant to this discussion, I think.

You'll also notice that the C++ heap does not suffer from unpredictability. You either delete at a specified time (typically, from some RAII's destructor), or leak it, in which case, well, you leaked it.

Shachar
October 09, 2015
On Friday, 9 October 2015 at 07:39:06 UTC, Shachar Shemesh wrote:
> On 08/10/15 18:58, Marco Leise wrote:
>> Am Mon, 05 Oct 2015 13:42:50 +0000
>> schrieb Adam D. Ruppe <destructionator@gmail.com>:
>>
>>> On Monday, 5 October 2015 at 07:40:35 UTC, deadalnix wrote:
>>>> Not on the heap. There are many cases where the destructor
>>>> won't run and it is allowed by spec. We should do better.
>>>
>>> To be fair, if you new a struct in C++ and never delete it, the
>>> destructor will never run there either. D's in the same boat in
>>> that regard.
>>
>> But the D boat reads "Garbage Collector". And besides, D now
>> runs dtors on new'd structs. The "many cases" may be different
>> ones than you imagine.
>>
>
> There is an inherent contradiction between GC and destruction. The GC's unpredictable nature runs counter to the reason you usually want a struct to have a destructor in the first place. With that said, D has improved on that front.
>
> By this discussion started out with using containers in order to avoid using the GC. As such, those cases are less relevant to this discussion, I think.
>
> You'll also notice that the C++ heap does not suffer from unpredictability. You either delete at a specified time (typically, from some RAII's destructor), or leak it, in which case, well, you leaked it.
>
> Shachar

Well it depends. destruction and GC are about releasing resources. You want eager resource release for scarce resources, like file handler. For resources that aren't as scarce, strategy like GC make sense.

But GC only works for memory. One also may want to GC other resources, granted they aren't too scarce. dtor make sense for this.

It is also very useful as a safety net. When the object is released, if it still hold handle to scarce resource, it make sense to log and release it, or something similar. That is surely better than running out of the resource and crashing.

October 09, 2015
On Friday, 9 October 2015 at 07:54:43 UTC, deadalnix wrote:
> It is also very useful as a safety net. When the object is released, if it still hold handle to scarce resource, it make sense to log and release it, or something similar. That is surely better than running out of the resource and crashing.

Though it's a feature nice to have, not a resource management mechanism. In .net when an object is released it can suppress its finalizer, so it won't be considered for finalization during collection and will be collected as plain garbage. AFAIK in D GC finalization is accounted as a block flag, so to suppress finalization one can reset this flag, and the block will be collected without finalization.
1 2 3 4 5 6
Next ›   Last »