static try catch construct would be helpful

Robert Fraser fraserofthenight at gmail.com
Tue Feb 26 16:40:44 PST 2008


Bill Baxter wrote:
> Robert Fraser wrote:
>> Bill Baxter wrote:
>>> When plugging types together sometimes you find this one is missing a 
>>> member or that one defines it in a different way than you expect or 
>>> maybe a function with some signature isn't supported.
>>>
>>> What you'd like to do is say "compile this block if you can -- 
>>> otherwise leave it out"  It's like try-catch, but compile-time.
>>> Except you don't really want a 'catch'.  It's more like an 'else'.  
>>> So I propose a new form of static:
>>>
>>>    static if {
>>>       // some code
>>>    } else static if {
>>>       // other code
>>>    } else {
>>>       // last resort code
>>>    }
>>>
>>> The idea is: if "some code" compiles, then use that, otherwise try 
>>> "other code", and finally if none of the other code blocks compiles, 
>>> use the else block.
>>>
>>> And of course it could be mix-n-matched with regular static if()'s.
>>>
>>>
>>> ------
>>> Here's a motivating example taken from real code where I was wrapping 
>>> one struct with another.  The Inner type may or may not support a 
>>> particular signature of the "doSomething" function.
>>>
>>> struct Outer(Inner)
>>> {
>>>    void doSomething(int a, int b, int c, int d)
>>>    {
>>>       _inner.doSomething(a,b,c,d);
>>>       // do something else here
>>>    }
>>>
>>>     ...
>>>
>>>    Inner _inner;
>>> }
>>>
>>> Currently, the best way I've found to conditionalize that is:
>>>
>>>    static if(is(typeof(_inner.doSomething(1,1,1,1)))) {
>>>    void doSomething(int a, int b, int c, int d)
>>>    {
>>>       _inner.doSomething(a,b,c,d);
>>>       // do something else here
>>>    }
>>>    }
>>>
>>> Maybe there's a better way to write that one.. I'm not sure.  But the 
>>> signature of the thing that may or may not exist can be arbitrarily 
>>> complex.  It becomes difficult to think of an is-expression that can 
>>> test for what you want.   You can probably break out the test into a 
>>> separate template and make it so you can do
>>>     static if(is(DoSomeCheck!(....))
>>> but writing that DoSomeCheck is annoying too and starts to clutter 
>>> your source with lots of one-off gobbledy gook templates.
>>>
>>> I think "argument-less static if blocks" would handle such cases nicely.
>>>
>>>
>>> There's a slight issue in that it could be pretty hard to debug with 
>>> compiler errors being silently ignored, but that happens currently 
>>> with the expressions inside "static if(is(...))" already.
>>>
>>> --bb
>>
>> I like it, although I'm not sure how difficult that'd be to implement 
>> in the DMDFE's current model. votes++, under the stipulation that all 
>> code in question must be syntactically correct, even if it's not 
>> semantically correct. Personally, I like "static try { } else static 
>> try { } else { }", which I think conveys the meaning better than 
>> static if. Also, I think there should definitely be a strong caution 
>> on the specs page that other methods should be tried first, since, as 
>> you mentioned, it can spuriously compile the wrong thing if you 
>> accidentally have an error there.
> 
> And those could be combined with static ifs, too right?
> 
>    static try { ... } else static if (is(T==blah)) { ... } else static 
> try { ... }.
> 
> --bb

Well, because of the way the parser words, I'd assume they could be 
combined with any compile-time construct:

static try { } else static if(...) { } else version(...) { } else 
debug(...) { } else { }



More information about the Digitalmars-d mailing list