Jump to page: 1 2
Thread overview
Choosing arity of a template function
Feb 26, 2016
Era Scarecrow
Feb 26, 2016
cym13
Feb 26, 2016
Chris Wright
Feb 27, 2016
Era Scarecrow
Feb 27, 2016
Chris Wright
Feb 27, 2016
Jonathan M Davis
Feb 27, 2016
Meta
Feb 27, 2016
Timon Gehr
Feb 27, 2016
Marc Schütz
Feb 27, 2016
Walter Bright
Feb 29, 2016
Dicebot
Mar 03, 2016
Meta
Mar 03, 2016
Meta
Mar 04, 2016
Meta
February 26, 2016
A generic function receives an argument called "partition" by alias. That may work in one of the following ways:

partition(range);

partition!less(range);

partition!less(range, n); // n is a number

I tried this:

static if (is(partition == function) || is(partition == delegate))
  partition(r);
else if (__traits(compiles, partition!less(r, n)))
  partition!less(r, n);
else
  partition!less(r);

The first test works very nice. The second does not; the compiler attempts to instantiate the template wrongly and spits a bunch of errors before giving up, in spite of the whole "let me know silently whether this compiles" thing.

So, what's an elegant solution to this? I looked up std.traits but nothing seems to help. (Tried arity, no avail.)


Thanks,

Andrei
February 26, 2016
On 02/26/2016 06:09 PM, Andrei Alexandrescu wrote:
> A generic function receives an argument called "partition" by alias.
> That may work in one of the following ways:
>
> partition(range);
>
> partition!less(range);
>
> partition!less(range, n); // n is a number
>
> I tried this:
>
> static if (is(partition == function) || is(partition == delegate))
>    partition(r);
> else if (__traits(compiles, partition!less(r, n)))
>    partition!less(r, n);
> else
>    partition!less(r);
>
> The first test works very nice. The second does not; the compiler
> attempts to instantiate the template wrongly and spits a bunch of errors
> before giving up, in spite of the whole "let me know silently whether
> this compiles" thing.
>
> So, what's an elegant solution to this? I looked up std.traits but
> nothing seems to help. (Tried arity, no avail.)

Urgh, forgot the "static" in front of the second "if". It does work now. Nevertheless, I'm still on lookout for a more elegant solution! I have this mindset that using __traits(compiles) is some sort of cheating.


Andrei

February 26, 2016
On Friday, 26 February 2016 at 23:11:32 UTC, Andrei Alexandrescu wrote:
> Urgh, forgot the "static" in front of the second "if". It does work now.

 Perhaps that should be an error instead; Going from a static if to an else if... seems easy enough to spot and insist a fix (much like assignment inside an if statement is illegal).
February 26, 2016
On Friday, 26 February 2016 at 23:18:30 UTC, Era Scarecrow wrote:
> On Friday, 26 February 2016 at 23:11:32 UTC, Andrei Alexandrescu wrote:
>> Urgh, forgot the "static" in front of the second "if". It does work now.
>
>  Perhaps that should be an error instead; Going from a static if to an else if... seems easy enough to spot and insist a fix (much like assignment inside an if statement is illegal).

What about automatically inferring it? It sounds reasonnable, much like saying that "static" actually is for the whole if/elseif block.
February 26, 2016
On Fri, 26 Feb 2016 23:46:11 +0000, cym13 wrote:

> On Friday, 26 February 2016 at 23:18:30 UTC, Era Scarecrow wrote:
>> On Friday, 26 February 2016 at 23:11:32 UTC, Andrei Alexandrescu wrote:
>>> Urgh, forgot the "static" in front of the second "if". It does work now.
>>
>>  Perhaps that should be an error instead; Going from a static
>> if to an else if... seems easy enough to spot and insist a fix (much
>> like assignment inside an if statement is illegal).
> 
> What about automatically inferring it? It sounds reasonnable, much like saying that "static" actually is for the whole if/elseif block.

  static if (oggSupportEnabled)
    playOggFile();
  else
    if (config.loggingEnabled)
      info("ogg support not enabled; skipping playback");

So, no, unless you want to make curly braces mandatory for conditional bodies.
February 27, 2016
On Friday, 26 February 2016 at 23:11:32 UTC, Andrei Alexandrescu wrote:
> Urgh, forgot the "static" in front of the second "if". It does work now. Nevertheless, I'm still on lookout for a more elegant solution! I have this mindset that using __traits(compiles) is some sort of cheating.

There's nothing cheating about using __traits(compiles). It's basically the same as using is(typeof(foo)) and is(typeof({statement;})), albeit arguably a bit more explicit about the fact that it's testing what compiles. And there are plenty of cases where one of those is exactly what code should be doing.

Now, if it's a test that needs to be done frequently, then it makes sense to create a wrapper for it that makes using it cleaner, so I think that you're right in the sense that we should be looking to have reusable traits to test with rather than using __traits(compiles) or is(typeof(blah)) heavily, but they're still fine to use when the occasion calls for it - especially if the test in question isn't something that's going to need to be done in much code. So, to a great extent, the question is whether what you're trying to do here is something that very many folks are going to want to do, and if it is, then we should find a way to do it without __traits(compiles), but if not, then I'm not sure that I'd worry much about it.

- Jonathan M Davis
February 27, 2016
On Friday, 26 February 2016 at 23:53:06 UTC, Chris Wright wrote:
> On Fri, 26 Feb 2016 23:46:11 +0000, cym13 wrote:
>> On Friday, 26 February 2016 at 23:18:30 UTC, Era Scarecrow wrote:
>>> On Friday, 26 February 2016 at 23:11:32 UTC, Andrei Alexandrescu wrote:
>>>> Urgh, forgot the "static" in front of the second "if". It does work now.
>>>
>>>  Perhaps that should be an error instead; Going from a static if to an else if... seems easy enough to spot and insist a fix (much like assignment inside an if statement is illegal).
>> 
>> What about automatically inferring it? It sounds reasonnable, much like saying that "static" actually is for the whole if/elseif block.
>
>   static if (oggSupportEnabled)
>     playOggFile();
>   else
>     if (config.loggingEnabled)
>       info("ogg support not enabled; skipping playback");
>
> So, no, unless you want to make curly braces mandatory for conditional bodies.

 Only for switching between static and non-static code. Besides with the static if's, 1 level of bracing doesn't make a new scope anyways (if i remember correctly).
February 27, 2016
On Sat, 27 Feb 2016 01:25:31 +0000, Era Scarecrow wrote:

> On Friday, 26 February 2016 at 23:53:06 UTC, Chris Wright wrote:
>> On Fri, 26 Feb 2016 23:46:11 +0000, cym13 wrote:
>>> On Friday, 26 February 2016 at 23:18:30 UTC, Era Scarecrow wrote:
>>>> On Friday, 26 February 2016 at 23:11:32 UTC, Andrei Alexandrescu wrote:
>>>>> Urgh, forgot the "static" in front of the second "if". It does work now.
>>>>
>>>>  Perhaps that should be an error instead; Going from a static
>>>> if to an else if... seems easy enough to spot and insist a fix (much
>>>> like assignment inside an if statement is illegal).
>>> 
>>> What about automatically inferring it? It sounds reasonnable, much like saying that "static" actually is for the whole if/elseif block.
>>
>>   static if (oggSupportEnabled)
>>     playOggFile();
>>   else
>>     if (config.loggingEnabled)
>>       info("ogg support not enabled; skipping playback");
>>
>> So, no, unless you want to make curly braces mandatory for conditional bodies.
> 
>   Only for switching between static and non-static code. Besides
> with the static if's, 1 level of bracing doesn't make a new scope
> anyways (if i remember correctly).

This would be a great thing for a lint tool to check, but for a language change, it's breaking, and the justification is a bit short.
February 27, 2016
It isn't cheating but IMO it's bad form. If you can do it without __traits(compiles) (or is(typeof()), etc.) you should, because there are many reasons why something will not compile, and only one of those reasons is the one you want to know. If there's no way around using it, you should still try to limit what is passed to __traits(compiles).

enum hasFront(T) = __traits(compiles, { auto _ = T.init.font; });

It's fairly easy to spot such a typo when it's only one line, but the risk of having some other compiler error being the reason your static if branch isn't taken grows very quickly with each additional line or bit of complexity.
February 27, 2016
On 2/26/2016 3:09 PM, Andrei Alexandrescu wrote:
> (Tried arity, no avail.)

Get the type of the function, the tuple of its parameter types, and the .length of that tuple.

« First   ‹ Prev
1 2