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