June 06, 2012
On Wednesday, 6 June 2012 at 18:11:42 UTC, Jonathan M Davis wrote:
> On Wednesday, June 06, 2012 19:22:13 Lars T. Kyllingstad wrote:
>> On Wednesday, 6 June 2012 at 09:38:35 UTC, Jonathan M Davis wrote:
>> > On Wednesday, June 06, 2012 11:13:39 Lars T. Kyllingstad wrote:
>> >> On Friday, 1 June 2012 at 12:29:27 UTC, Steven Schveighoffer
>> >> 
>> >> wrote:
>> >> > On Fri, 01 Jun 2012 04:48:27 -0400, Dmitry Olshansky
>> >> > 
>> >> > <dmitry.olsh@gmail.com> wrote:
>> >> >> I don't agree that OutOfMemory is critical:
>> >> >> --> make it an exception ?
>> >> > 
>> >> > No. What we need is a non-throwing version of malloc that
>> >> > returns NULL. (throwing version can wrap this). If you want
>> >> > to throw an exception, then throw it there (or use enforce).
>> >> 
>> >> With some sugar:
>> >> auto a = nothrow new Foo; // Returns null on OOM
>> >> 
>> >> Then, ordinary new can be disallowed in nothrow code.
>> > 
>> > But then instead of getting a nice, clear, OutOfMemoryError,
>> > you get a
>> > segfault - and that's assuming that it gets dereferenced
>> > anywhere near where
>> > it's allocated. [...]
>> 
>> I agree; it would make nothrow an "advanced feature", which kind
>> of sucks.
>
> Which makes the suggestion DOA IMHO.

I'm not so sure it's worse than the current situation.

  Newbie: "This nothrow thing looks kinda cool.  So, if I use it, I can be sure nothing gets thrown from this function, right?"

  Community: "Right.  Unless you run out of memory, or an assertion fails, or something like that.  Then you get an Error, and nothrow doesn't prevent those."

  Newbie: "Ok, I guess that makes sense.  Luckily, it looks like Error is just another kind of exception, so at least I know that all my destructors are run and my program terminates gracefully.  Right?"

  Community: "Yeah, about that..."

June 06, 2012
On Wednesday, 6 June 2012 at 19:27:31 UTC, Timon Gehr wrote:
> On 06/06/2012 07:18 PM, Lars T. Kyllingstad wrote:
>> Besides OutOfMemoryError, I can only think of two other Errors that
>> would make this a hassle: AssertError and RangeError. However, both of
>> these signify problems with the program logic, and unwinding the stack
>> is probably a bad idea anyway, so why not simply make these abort()?
>>
>> -Lars
>>
>
> In the current implementation, in contract checking may catch AssertErrors and resume the program normally.

I'm not sure I understand what you mean.  Are you suggesting catching AssertErrors thrown by in contracts, thereby using contracts as a means of checking input?  If so, I would say you are using contracts in the wrong way.

-Lars

June 06, 2012
On Wednesday, June 06, 2012 22:47:55 Lars T. Kyllingstad wrote:
> On Wednesday, 6 June 2012 at 18:11:36 UTC, Jonathan M Davis wrote:
> > On Wednesday, June 06, 2012 19:40:03 Lars T. Kyllingstad wrote:
> >> On Wednesday, 6 June 2012 at 09:38:35 UTC, Jonathan M Davis
> >> 
> >> wrote:
> >> > On Wednesday, June 06, 2012 11:13:39 Lars T. Kyllingstad
> >> > 
> >> > wrote:
> >> >> On Friday, 1 June 2012 at 12:29:27 UTC, Steven Schveighoffer
> >> >> 
> >> >> wrote:
> >> >> > On Fri, 01 Jun 2012 04:48:27 -0400, Dmitry Olshansky
> >> >> > 
> >> >> > <dmitry.olsh@gmail.com> wrote:
> >> >> >> I don't agree that OutOfMemory is critical:
> >> >> >> --> make it an exception ?
> >> >> > 
> >> >> > No. What we need is a non-throwing version of malloc that
> >> >> > returns NULL. (throwing version can wrap this). If you
> >> >> > want
> >> >> > to throw an exception, then throw it there (or use
> >> >> > enforce).
> >> >> 
> >> >> With some sugar:
> >> >> auto a = nothrow new Foo; // Returns null on OOM
> >> >> 
> >> >> Then, ordinary new can be disallowed in nothrow code.
> >> > 
> >> > But then instead of getting a nice, clear, OutOfMemoryError,
> >> > you get a
> >> > segfault - and that's assuming that it gets dereferenced
> >> > anywhere near where
> >> > it's allocated.
> >> 
> >> "nothrow new" is easily greppable, though. That would be the first course of action upon getting a segfault.
> > 
> > But unless you got a core dump, you have _no_ idea where in the
> > program the
> > segfault occurred. So, that really isn't helpful.
> 
> Of course it's helpful. If you were using nothrow new (or malloc, for that matter), you should *always* check its return value. If you get a segfault, you simply locate all uses of nothrow new in your program and ensure you have checked the return value of each and every one of them. If it turns out they are all checked, well, then the problem isn't OOM.

But I do _not_ want to have to care about OOM. Having the program throw an Error and kill the program when it occurs is _perfect_ IMHO. So, if it were changed so that you could only allocate memory in a nothrow function through a mechanism which did not throw OutOfMemoryError when you tried to allocate and failed due to a lack of free memory, then nothrow would _suck_. It would be extremely annoying to use, and completely cripple it IMHO.

Having a mechanism which allows you to allocate without throwing OOM is great for the cases where someone actually needs, it but I'm _completely_ against requiring it anywhere.

- Jonathan M Davis
June 06, 2012
On 06/06/2012 11:04 PM, Lars T. Kyllingstad wrote:
> On Wednesday, 6 June 2012 at 19:27:31 UTC, Timon Gehr wrote:
>> On 06/06/2012 07:18 PM, Lars T. Kyllingstad wrote:
>>> Besides OutOfMemoryError, I can only think of two other Errors that
>>> would make this a hassle: AssertError and RangeError. However, both of
>>> these signify problems with the program logic, and unwinding the stack
>>> is probably a bad idea anyway, so why not simply make these abort()?
>>>
>>> -Lars
>>>
>>
>> In the current implementation, in contract checking may catch
>> AssertErrors and resume the program normally.
>
> I'm not sure I understand what you mean. Are you suggesting catching
> AssertErrors thrown by in contracts, thereby using contracts as a means
> of checking input? If so, I would say you are using contracts in the
> wrong way.
>
> -Lars
>

I was not describing an usage pattern. This is built-in behaviour.

int throwAssertError(){
    writeln("now throwing an AssertError");
    throw new AssertError("!");
}

class C{
    void foo()in{throwAssertError();}body{}
}
class D: C{
    override void foo()in{}body{}
}

void main(){
    C c = new D;
    c.foo(); // assert error thrown and caught
}
June 06, 2012
On Wednesday, 6 June 2012 at 21:35:15 UTC, Timon Gehr wrote:
> On 06/06/2012 11:04 PM, Lars T. Kyllingstad wrote:
>> On Wednesday, 6 June 2012 at 19:27:31 UTC, Timon Gehr wrote:
>>> On 06/06/2012 07:18 PM, Lars T. Kyllingstad wrote:
>>>> Besides OutOfMemoryError, I can only think of two other Errors that
>>>> would make this a hassle: AssertError and RangeError. However, both of
>>>> these signify problems with the program logic, and unwinding the stack
>>>> is probably a bad idea anyway, so why not simply make these abort()?
>>>>
>>>> -Lars
>>>>
>>>
>>> In the current implementation, in contract checking may catch
>>> AssertErrors and resume the program normally.
>>
>> I'm not sure I understand what you mean. Are you suggesting catching
>> AssertErrors thrown by in contracts, thereby using contracts as a means
>> of checking input? If so, I would say you are using contracts in the
>> wrong way.
>>
>> -Lars
>>
>
> I was not describing an usage pattern. This is built-in behaviour.
>
> int throwAssertError(){
>     writeln("now throwing an AssertError");
>     throw new AssertError("!");
> }
>
> class C{
>     void foo()in{throwAssertError();}body{}
> }
> class D: C{
>     override void foo()in{}body{}
> }
>
> void main(){
>     C c = new D;
>     c.foo(); // assert error thrown and caught
> }

Ah, now I see what you mean.  I didn't know that.

-Lars
June 06, 2012
On Wednesday, 6 June 2012 at 21:05:51 UTC, Jonathan M Davis wrote:
> On Wednesday, June 06, 2012 22:47:55 Lars T. Kyllingstad wrote:
>> On Wednesday, 6 June 2012 at 18:11:36 UTC, Jonathan M Davis wrote:
>> > On Wednesday, June 06, 2012 19:40:03 Lars T. Kyllingstad wrote:
>> >> On Wednesday, 6 June 2012 at 09:38:35 UTC, Jonathan M Davis
>> >> 
>> >> wrote:
>> >> > On Wednesday, June 06, 2012 11:13:39 Lars T. Kyllingstad
>> >> > 
>> >> > wrote:
>> >> >> On Friday, 1 June 2012 at 12:29:27 UTC, Steven Schveighoffer
>> >> >> 
>> >> >> wrote:
>> >> >> > On Fri, 01 Jun 2012 04:48:27 -0400, Dmitry Olshansky
>> >> >> > 
>> >> >> > <dmitry.olsh@gmail.com> wrote:
>> >> >> >> I don't agree that OutOfMemory is critical:
>> >> >> >> --> make it an exception ?
>> >> >> > 
>> >> >> > No. What we need is a non-throwing version of malloc that
>> >> >> > returns NULL. (throwing version can wrap this). If you
>> >> >> > want
>> >> >> > to throw an exception, then throw it there (or use
>> >> >> > enforce).
>> >> >> 
>> >> >> With some sugar:
>> >> >> auto a = nothrow new Foo; // Returns null on OOM
>> >> >> 
>> >> >> Then, ordinary new can be disallowed in nothrow code.
>> >> > 
>> >> > But then instead of getting a nice, clear, OutOfMemoryError,
>> >> > you get a
>> >> > segfault - and that's assuming that it gets dereferenced
>> >> > anywhere near where
>> >> > it's allocated.
>> >> 
>> >> "nothrow new" is easily greppable, though. That would be the
>> >> first course of action upon getting a segfault.
>> > 
>> > But unless you got a core dump, you have _no_ idea where in the
>> > program the
>> > segfault occurred. So, that really isn't helpful.
>> 
>> Of course it's helpful. If you were using nothrow new (or
>> malloc, for that matter), you should *always* check its return
>> value. If you get a segfault, you simply locate all uses of
>> nothrow new in your program and ensure you have checked the
>> return value of each and every one of them. If it turns out they
>> are all checked, well, then the problem isn't OOM.
>
> But I do _not_ want to have to care about OOM. Having the program throw an
> Error and kill the program when it occurs is _perfect_ IMHO. So, if it were
> changed so that you could only allocate memory in a nothrow function through a
> mechanism which did not throw OutOfMemoryError when you tried to allocate and
> failed due to a lack of free memory, then nothrow would _suck_. It would be
> extremely annoying to use, and completely cripple it IMHO.
>
> Having a mechanism which allows you to allocate without throwing OOM is great
> for the cases where someone actually needs, it but I'm _completely_ against
> requiring it anywhere.

You're probably right.  Besides, I just browsed through core/exception.d, and it seems that my list of Errors was far from exhaustive.  In addition to OutOfMemoryError, AssertError and RangeError, there is FinalizeError, HiddenFuncError, InvalidMemoryOperationError and SwitchError.  Working around nothrow for all of those would be painful.

SwitchError should probably be deprecated, by the way.

-Lars
June 07, 2012
On 06/07/2012 12:11 AM, Lars T. Kyllingstad wrote:
> On Wednesday, 6 June 2012 at 21:05:51 UTC, Jonathan M Davis wrote:
>> ...
>> Having a mechanism which allows you to allocate without throwing OOM
>> is great
>> for the cases where someone actually needs, it but I'm _completely_
>> against
>> requiring it anywhere.
>
> You're probably right. Besides, I just browsed through core/exception.d,
> and it seems that my list of Errors was far from exhaustive. In addition
> to OutOfMemoryError, AssertError and RangeError, there is FinalizeError,
> HiddenFuncError, InvalidMemoryOperationError and SwitchError. Working
> around nothrow for all of those would be painful.
>
> SwitchError should probably be deprecated, by the way.
>
> -Lars

HiddenFuncError should be deprecated as well.
3 4 5 6 7 8 9 10 11 12 13
Next ›   Last »