try/catch idiom in std.datetime

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Mon Nov 18 00:14:24 PST 2013


On 11/17/13 11:28 PM, Jonathan M Davis wrote:
> On Sunday, November 17, 2013 22:32:46 Andrei Alexandrescu wrote:
>> (It may seem I chose this example to discuss the "let's insert one empty
>> line every other line" idiom. I didn't.)
>
> That code's like that just because I like to put empty lines before and after
> if statements and before return statements, as I think that that improves
> legibility. Short functions like that suffer as a result, because they end up
> with a larger proportion of the lines being empty than is normal. I'm always a
> bit torn on that, because I don't like having quite that many empty lines in
> so few lines, but I also don't like not having space around if statements and
> return statements. I never feel like I can find a nice, legible balance with
> short functions like that.

"Too much of a good thing" comes to mind (as does with the massive and 
repetitive unittests in std.datetime). If code looks and feels meh, it 
probably is. Just apply good judgment instead of rote adherence to rules.

>> 0. Do nothing. This is as good as it gets.
>
> Well, it works just fine as-is, but it would be kind of nice to be able to
> solve the problem in a less verbose manner (though you're talking about saving
> only a few lines of code).

I'm also concerned about generated code size and overall efficiency. It 
looks like the assert(0) insertions are there simply to validate the 
design (they only fail if Phobos has an internal error), so there should 
be some means to remove them in release builds. We don't have such a 
possibility at the moment.

>> 2. Relax the nothrow guarantees. After all, nothrow is opt-in.
>
> I'm not quite sure what you're suggesting here.

What I meant is, not everything that is nothrow needs to be annotated as 
such.

>       @property FracSec fracSec() const nothrow
>       {
>           trusted-nothrow
>           {
>               auto hnsecs = removeUnitsFromHNSecs!"days"(adjTime);
>
>               if(hnsecs < 0)
>                   hnsecs += convert!("hours", "hnsecs")(24);
>
>               hnsecs = removeUnitsFromHNSecs!"seconds"(hnsecs);
>
>               return FracSec.from!"hnsecs"(cast(int)hnsecs);
>           }
>       }

That can be done at library level.

>> 4. ...?
>
> We now have std.exception.assumeWontThrow, which works reasonably well when
> you need to wrap a single call as opposed to several, but it has the same
> problem as enforce in that it uses lazy, which is definite performance hit. So,
> in most cases, I'd be more inclined to just use a try-catch, and if it's more
> than one expression, you pretty much need to use try-catch or scope(failure)
> instead anyway, since you wouldn't want to wrap whole function bodies in a
> call to assumeWontThrow (assuming that you even could).

Again, one problem here (in addition to the blowup in code size and 
decay of readability) is we're talking about an internal design 
validation, not meaningful runtime semantics. There should be a way to 
remove the baggage.


Andrei



More information about the Digitalmars-d mailing list