May 14, 2015
I wonder if enforce should throw an Error instead, if it exists at all. Because it's designed to throw an exception you shouldn't catch. If you are going to have it throw an Exception subclass, then it should take the exception type, like enforce!WhateverException(...), or something.
May 14, 2015
On Thursday, 14 May 2015 at 10:08:36 UTC, Jacob Carlborg wrote:
> It was a while since I looked at that DIP, but I'm mostly interested in the hierarchy.

I think hierarchies will get better too if there were more incentive to use them - data members instead of string concat encourages new classes and you want to inherit from something... then if there's not a million lines of boilerplate for a new class, it gets to be a lot easier to do.
May 14, 2015
On Thursday, 14 May 2015 at 10:24:45 UTC, Ola Fosheim Grøstad wrote:
> Using alias like this makes code hard to read. Error types should be humanly deducible at the failure site.

Perhaps, I don't hate it too much here though because the alias is fairly local.  Without it, you'd probably write enforce!(BaseClass, fopen)("file", "rb") to get the thing I was going for.

> You'd be better off having non-ignorable result types (e.g. tagged union/variant/algebraic) and a typed way to turn those into exceptions.

The only place where I'd be interested in using something like this is calling F functions and you can't change their signature too much...
May 14, 2015
On Thursday, 14 May 2015 at 10:29:57 UTC, Kagamin wrote:
> Maybe also replace file name with ModuleInfo similar to how assert works?

Those bug me because all it really wants from it is the name and then you need all the moduleinfo even in bare metal.

Exception support requires some RTTI anyway so maybe it doesn't matter, but my playing with bare metal has made me really prefer the filename versions over the moduleinfo versions...
May 14, 2015
On Thursday, 14 May 2015 at 12:26:45 UTC, w0rp wrote:
> I wonder if enforce should throw an Error instead, if it exists at all. Because it's designed to throw an exception you shouldn't catch.

Is it really? My thought of enforce was it iwas just a lazy way to throw on cases like file not found...
May 14, 2015
On Thursday, 14 May 2015 at 12:39:59 UTC, Adam D. Ruppe wrote:
> On Thursday, 14 May 2015 at 10:29:57 UTC, Kagamin wrote:
>> Maybe also replace file name with ModuleInfo similar to how assert works?
>
> Those bug me because all it really wants from it is the name and then you need all the moduleinfo even in bare metal.

AFAIK, ModuleInfo is only 8 bytes + module name.

> Exception support requires some RTTI anyway so maybe it doesn't matter, but my playing with bare metal has made me really prefer the filename versions over the moduleinfo versions...

ModuleInfo is primarily to extract module name and use it instead of file name, you can use module name directly if you don't like full ModuleInfo.
May 14, 2015
On 5/14/15 6:12 AM, Jacob Carlborg wrote:
> On 2015-05-14 00:55, Steven Schveighoffer wrote:
>
>> enforce is one of the most needless pieces of phobos:
>>
>> enforce(cond, message);
>> vs.
>> if(!cond) throw new Exception(message);
>>
>> And the second doesn't mess up inlining.
>>
>> I think enforce could be boiler-plated better. The only verbose part of
>> the if version is the throwing and newing.
>>
>> template throe(Etype = Exception)
>> {
>>     void throe(Args...)(Args args, string file = __FILE__, size_t line =
>> __LINE__)
>>     {
>>         throw new Etype(args, file, line);
>>     }
>> }
>>
>> if(!cond) throe(message);
>
> Now you're back to the same problem as "enforce" has. That it throws
> Exception by default. It shouldn't have a default value for the
> exception type.

Sure, but I wasn't arguing about that. I just don't like the utility of enforce completely -- it provides very little value, and kills inlining.

> BTW, it could be called "raise" as it's called in some other languages.

My symbol wasn't intended as a proposal, just something that sounds like "throw" but without using the keyword :) raise would be fine.

>> Wait, you're in an io package, and you want to always throw IO
>> exceptions?
>>
>> alias except = throe!IOException;
>>
>> if(!cond) except(args, to, ioexception);
>
> That is a bit better but I still think that IOException is too generic.
> Streaming something over the network and trying to open a file is quite
> different.

It was just an example, you can use whatever exception you want.

-Steve
May 15, 2015
On 2015-05-14 14:33, Adam D. Ruppe wrote:

> I think hierarchies will get better too if there were more incentive to
> use them - data members instead of string concat encourages new classes
> and you want to inherit from something

So why isn't data members used more, because of the boilerplate to create a new subcalss?

-- 
/Jacob Carlborg
May 15, 2015
On 2015-05-14 14:41, Adam D. Ruppe wrote:

> Is it really? My thought of enforce was it iwas just a lazy way to throw
> on cases like file not found...

Yeah, that's what I thought too. The documentation doesn't mention anything about this.

-- 
/Jacob Carlborg
May 15, 2015
On Friday, 15 May 2015 at 09:23:12 UTC, Jacob Carlborg wrote:
> So why isn't data members used more, because of the boilerplate to create a new subcalss?

Yeah, I think so. A new exception subclass has to write out the long constructor signature, forward it, add the data members, write code to set them, and at least write code to add them to the toString (which itself has a long signature and needs a lot of string formatting tedium).

That's a fair amount of code to write, especially compared to new Exception("foo " ~ to!string(value)) right there inline when it comes up.


But with reflection we can really simplify it to the point where writing class Foo : Exception { int value; mixin ExtendException; } becomes less of a hassle, or we could even extend a hierarchy right inline like raise!SomeException(variadic, arguments).