May 25, 2012
Le 25/05/2012 17:00, Andrei Alexandrescu a écrit :
> On 5/25/12 8:06 AM, Dmitry Olshansky wrote:
>> On 25.05.2012 17:04, Alex Rønne Petersen wrote:
>>> So I was writing a container class and in some test code, I called
>>> container.clear(). Reasonable enough, right? Hell, it even compiled!
>>>
>>> Turns out, my program completely broke at runtime. Apparently, I'd
>>> forgotten to implement clear() on my container class, and
>>> *object.clear() was being called instead*.
>>>
>>> I don't blame UFCS for this. It just happened to be the reason this
>>> compiled at all. But, what I do think is: clear is the *ABSOLUTELY MOST
>>> HORRIBLE NAME EVER* for a function that actually finalizes and zeroes an
>>> object. Did it not seem obvious to call it, I don't know, *finalize*?
>>> And even ignoring the naming, having a symbol called clear in the
>>> 'global' namespace is absolute insanity.
>>>
>>> Am I the only person with this opinion?
>>>
>>
>> No, there are thousands like you. Let's call clear "nuke", breaking TDPL
>> and saving the day. :)
>>
>> P.S. Obviously first clear goes through normal deprecation cycle.
>
> Since this is a recurring issue we should probably change the name.
>
> Andrei
>
>

It has already been suggested, but finalize is something that is explicit, and it is already used in other languages. We should go that way IMO.
May 25, 2012
On Fri, 25 May 2012 11:03:33 -0400, Alex Rønne Petersen <alex@lycus.org> wrote:

> On 25-05-2012 16:56, Steven Schveighoffer wrote:
>>
>> Wow, you're right, it's not documented. That should be fixed!
>
> Before we do, we should deprecate clear and rename it to finalize, though.

I don't like finalize because it's not a finalizer.

I think we should mimic other languages that have a finalizer and a deterministic dispose function.

-Steve
May 25, 2012
On 25-05-2012 17:23, Steven Schveighoffer wrote:
> On Fri, 25 May 2012 11:03:33 -0400, Alex Rønne Petersen
> <alex@lycus..org> wrote:
>
>> On 25-05-2012 16:56, Steven Schveighoffer wrote:
>>>
>>> Wow, you're right, it's not documented. That should be fixed!
>>
>> Before we do, we should deprecate clear and rename it to finalize,
>> though.
>
> I don't like finalize because it's not a finalizer.
>
> I think we should mimic other languages that have a finalizer and a
> deterministic dispose function.
>
> -Steve

But it calls rt_finalize...?

-- 
Alex Rønne Petersen
alex@lycus.org
http://lycus.org
May 25, 2012
On Fri, 25 May 2012 11:28:07 -0400, Alex Rønne Petersen <alex@lycus.org> wrote:

> On 25-05-2012 17:23, Steven Schveighoffer wrote:
>> On Fri, 25 May 2012 11:03:33 -0400, Alex Rønne Petersen
>> <alex@lycus..org> wrote:
>>
>>> On 25-05-2012 16:56, Steven Schveighoffer wrote:
>>>>
>>>> Wow, you're right, it's not documented. That should be fixed!
>>>
>>> Before we do, we should deprecate clear and rename it to finalize,
>>> though.
>>
>> I don't like finalize because it's not a finalizer.
>>
>> I think we should mimic other languages that have a finalizer and a
>> deterministic dispose function.
>>
>> -Steve
>
> But it calls rt_finalize...?

Yeah, because non-deterministic destruction is part of deterministic destruction.

finalize -> destroy non-gc resources
dispose -> 1. do deterministic destruction involving possible GC resources 2. call finalize.

e.g. a buffered file:

finalize -> close the file handle
dispose -> flush the GC allocated buffer into the handle, then close the handle

-Steve
May 25, 2012
On Fri, 25 May 2012 11:37:52 -0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> On Fri, 25 May 2012 11:28:07 -0400, Alex Rønne Petersen <alex@lycus.org> wrote:
>
>> On 25-05-2012 17:23, Steven Schveighoffer wrote:
>>> On Fri, 25 May 2012 11:03:33 -0400, Alex Rønne Petersen
>>> <alex@lycus..org> wrote:
>>>
>>>> On 25-05-2012 16:56, Steven Schveighoffer wrote:
>>>>>
>>>>> Wow, you're right, it's not documented. That should be fixed!
>>>>
>>>> Before we do, we should deprecate clear and rename it to finalize,
>>>> though.
>>>
>>> I don't like finalize because it's not a finalizer.
>>>
>>> I think we should mimic other languages that have a finalizer and a
>>> deterministic dispose function.
>>>
>>> -Steve
>>
>> But it calls rt_finalize...?
>
> Yeah, because non-deterministic destruction is part of deterministic destruction.
>
> finalize -> destroy non-gc resources
> dispose -> 1. do deterministic destruction involving possible GC resources 2. call finalize.
>
> e.g. a buffered file:
>
> finalize -> close the file handle
> dispose -> flush the GC allocated buffer into the handle, then close the handle

I take it back, dispose is no good.  That should be the name of the deterministic destructor in the object.

Now I don't have a good name.  Finalize isn't right, and neither is dispose...

-Steve
May 25, 2012
On 25-05-2012 17:37, Steven Schveighoffer wrote:
> On Fri, 25 May 2012 11:28:07 -0400, Alex Rønne Petersen
> <alex@lycus..org> wrote:
>
>> On 25-05-2012 17:23, Steven Schveighoffer wrote:
>>> On Fri, 25 May 2012 11:03:33 -0400, Alex Rønne Petersen
>>> <alex@lycus..org> wrote:
>>>
>>>> On 25-05-2012 16:56, Steven Schveighoffer wrote:
>>>>>
>>>>> Wow, you're right, it's not documented. That should be fixed!
>>>>
>>>> Before we do, we should deprecate clear and rename it to finalize,
>>>> though.
>>>
>>> I don't like finalize because it's not a finalizer.
>>>
>>> I think we should mimic other languages that have a finalizer and a
>>> deterministic dispose function.
>>>
>>> -Steve
>>
>> But it calls rt_finalize...?
>
> Yeah, because non-deterministic destruction is part of deterministic
> destruction.
>
> finalize -> destroy non-gc resources
> dispose -> 1. do deterministic destruction involving possible GC
> resources 2. call finalize.
>
> e.g. a buffered file:
>
> finalize -> close the file handle
> dispose -> flush the GC allocated buffer into the handle, then close the
> handle
>
> -Steve

But if clear() *does* run the finalizer *now*, then finalize would be a better name, no?

I'm all for the dispose model, but then we need a way to suppress finalizers too.

-- 
Alex Rønne Petersen
alex@lycus.org
http://lycus.org
May 25, 2012
On Fri, 25 May 2012 11:42:57 -0400, Alex Rønne Petersen <alex@lycus.org> wrote:

> On 25-05-2012 17:37, Steven Schveighoffer wrote:
>> On Fri, 25 May 2012 11:28:07 -0400, Alex Rønne Petersen
>> <alex@lycus..org> wrote:
>>
>>> On 25-05-2012 17:23, Steven Schveighoffer wrote:
>>>> On Fri, 25 May 2012 11:03:33 -0400, Alex Rønne Petersen
>>>> <alex@lycus..org> wrote:
>>>>
>>>>> On 25-05-2012 16:56, Steven Schveighoffer wrote:
>>>>>>
>>>>>> Wow, you're right, it's not documented. That should be fixed!
>>>>>
>>>>> Before we do, we should deprecate clear and rename it to finalize,
>>>>> though.
>>>>
>>>> I don't like finalize because it's not a finalizer.
>>>>
>>>> I think we should mimic other languages that have a finalizer and a
>>>> deterministic dispose function.
>>>>
>>>> -Steve
>>>
>>> But it calls rt_finalize...?
>>
>> Yeah, because non-deterministic destruction is part of deterministic
>> destruction.
>>
>> finalize -> destroy non-gc resources
>> dispose -> 1. do deterministic destruction involving possible GC
>> resources 2. call finalize.
>>
>> e.g. a buffered file:
>>
>> finalize -> close the file handle
>> dispose -> flush the GC allocated buffer into the handle, then close the
>> handle
>>
>> -Steve
>
> But if clear() *does* run the finalizer *now*, then finalize would be a better name, no?
>
> I'm all for the dispose model, but then we need a way to suppress finalizers too.

This is what I think clear (or function to be named later) should do:

if(obj.dispose())
  rt_finalize(obj);
else
  rt_suppressFinalize(obj);

That way you can write code like this:

class File
{
   bool dispose()
   {
      flush();
      return true;
   }

   ~this()
   {
      close(handle);
   }
}

and you don't have to repeat the finalize code inside the dispose routine if it's a normal part of deterministic destruction.

-Steve
May 25, 2012
On 25-05-2012 17:59, Steven Schveighoffer wrote:
> On Fri, 25 May 2012 11:42:57 -0400, Alex Rønne Petersen
> <alex@lycus..org> wrote:
>
>> On 25-05-2012 17:37, Steven Schveighoffer wrote:
>>> On Fri, 25 May 2012 11:28:07 -0400, Alex Rønne Petersen
>>> <alex@lycus..org> wrote:
>>>
>>>> On 25-05-2012 17:23, Steven Schveighoffer wrote:
>>>>> On Fri, 25 May 2012 11:03:33 -0400, Alex Rønne Petersen
>>>>> <alex@lycus..org> wrote:
>>>>>
>>>>>> On 25-05-2012 16:56, Steven Schveighoffer wrote:
>>>>>>>
>>>>>>> Wow, you're right, it's not documented. That should be fixed!
>>>>>>
>>>>>> Before we do, we should deprecate clear and rename it to finalize,
>>>>>> though.
>>>>>
>>>>> I don't like finalize because it's not a finalizer.
>>>>>
>>>>> I think we should mimic other languages that have a finalizer and a
>>>>> deterministic dispose function.
>>>>>
>>>>> -Steve
>>>>
>>>> But it calls rt_finalize...?
>>>
>>> Yeah, because non-deterministic destruction is part of deterministic
>>> destruction.
>>>
>>> finalize -> destroy non-gc resources
>>> dispose -> 1. do deterministic destruction involving possible GC
>>> resources 2. call finalize.
>>>
>>> e.g. a buffered file:
>>>
>>> finalize -> close the file handle
>>> dispose -> flush the GC allocated buffer into the handle, then close the
>>> handle
>>>
>>> -Steve
>>
>> But if clear() *does* run the finalizer *now*, then finalize would be
>> a better name, no?
>>
>> I'm all for the dispose model, but then we need a way to suppress
>> finalizers too.
>
> This is what I think clear (or function to be named later) should do:
>
> if(obj.dispose())
> rt_finalize(obj);
> else
> rt_suppressFinalize(obj);
>
> That way you can write code like this:
>
> class File
> {
> bool dispose()
> {
> flush();
> return true;
> }
>
> ~this()
> {
> close(handle);
> }
> }
>
> and you don't have to repeat the finalize code inside the dispose
> routine if it's a normal part of deterministic destruction.
>
> -Steve

Sounds good to me.

-- 
Alex Rønne Petersen
alex@lycus.org
http://lycus.org
May 25, 2012
Am 25.05.2012 15:04, schrieb Alex Rønne Petersen:
> So I was writing a container class and in some test code, I called
> container.clear(). Reasonable enough, right? Hell, it even compiled!
>
> Turns out, my program completely broke at runtime. Apparently, I'd
> forgotten to implement clear() on my container class, and
> *object.clear() was being called instead*.
>
> I don't blame UFCS for this. It just happened to be the reason this
> compiled at all. But, what I do think is: clear is the *ABSOLUTELY MOST
> HORRIBLE NAME EVER* for a function that actually finalizes and zeroes an
> object. Did it not seem obvious to call it, I don't know, *finalize*?
> And even ignoring the naming, having a symbol called clear in the
> 'global' namespace is absolute insanity.
>
> Am I the only person with this opinion?
>

I completely agree! Had the same situation before...

Also I hate that UFCS is doing the same thing that properties did in the beginning and have no way to enforce a specific usage. I strongly believe that it is a (often important) decision of the library architect if a function is to be called normally or as member function style.
May 25, 2012
On 05/25/12 18:11, Sönke Ludwig wrote:
> Am 25.05.2012 15:04, schrieb Alex Rønne Petersen:
>> So I was writing a container class and in some test code, I called container.clear(). Reasonable enough, right? Hell, it even compiled!
>>
>> Turns out, my program completely broke at runtime. Apparently, I'd
>> forgotten to implement clear() on my container class, and
>> *object.clear() was being called instead*.
>>
>> I don't blame UFCS for this. It just happened to be the reason this compiled at all. But, what I do think is: clear is the *ABSOLUTELY MOST HORRIBLE NAME EVER* for a function that actually finalizes and zeroes an object. Did it not seem obvious to call it, I don't know, *finalize*? And even ignoring the naming, having a symbol called clear in the 'global' namespace is absolute insanity.
>>
>> Am I the only person with this opinion?
>>
> 
> I completely agree! Had the same situation before...
> 
> Also I hate that UFCS is doing the same thing that properties did in the beginning and have no way to enforce a specific usage. I strongly believe that it is a (often important) decision of the library architect if a function is to be called normally or as member function style.
> 

@method ?

artur