September 03, 2012
On 9/3/12 1:24 PM, David Nadlinger wrote:
> On Monday, 3 September 2012 at 11:20:27 UTC, Sven Torvinger wrote:
>> if (a.among("struct", "class", "union")) { ... }
>
> Wouldn't that rather be a.among!("struct", "class", "union")?

I'd rather have a regular function (more generally applicable) that the inliner takes care of.

Andrei

September 03, 2012
On Monday, 3 September 2012 at 12:58:05 UTC, Andrei Alexandrescu wrote:
> On 9/3/12 1:24 PM, David Nadlinger wrote:
>> On Monday, 3 September 2012 at 11:20:27 UTC, Sven Torvinger wrote:
>>> if (a.among("struct", "class", "union")) { ... }
>>
>> Wouldn't that rather be a.among!("struct", "class", "union")?
>
> I'd rather have a regular function (more generally applicable) that the inliner takes care of.

Where would the real difference to ["struct", "class", "union"].canFind(a) then? A sufficiently smart compiler (tm) could optimize this to a efficient string "prefix switch statement" just as well…

David
September 03, 2012
On 9/3/12 3:53 PM, David Nadlinger wrote:
> On Monday, 3 September 2012 at 12:58:05 UTC, Andrei Alexandrescu wrote:
>> On 9/3/12 1:24 PM, David Nadlinger wrote:
>>> On Monday, 3 September 2012 at 11:20:27 UTC, Sven Torvinger wrote:
>>>> if (a.among("struct", "class", "union")) { ... }
>>>
>>> Wouldn't that rather be a.among!("struct", "class", "union")?
>>
>> I'd rather have a regular function (more generally applicable) that
>> the inliner takes care of.
>
> Where would the real difference to ["struct", "class",
> "union"].canFind(a) then?

Convenience. I find the other easier to write and read.

> A sufficiently smart compiler (tm) could
> optimize this to a efficient string "prefix switch statement" just as well…

I agree. But then http://c2.com/cgi/wiki?SufficientlySmartCompiler.


Andrei


September 03, 2012
On 09/03/2012 01:37 AM, Andrei Alexandrescu wrote:
> On 9/2/12 7:31 PM, Timon Gehr wrote:
>> On 09/02/2012 06:45 PM, Andrei Alexandrescu wrote:
>>> On 9/2/12 6:44 PM, Andrei Alexandrescu wrote:
>>> [snip]
>>>
>>> The remaining question is where to put among and between.
>>> std.functional?
>>>
>>> Andrei
>>
>> They are not combinators. std.algorithm.
>
> I'd argue they aren't quite algorithms either...
>
> Andrei

Interesting. What is the Phobos definition of algorithm?
September 03, 2012
David Nadlinger:

> Where would the real difference to ["struct", "class", "union"].canFind(a) then? A sufficiently smart compiler (tm) could optimize this to a efficient string "prefix switch statement" just as well…

I think a smart compiler is not needed.

Maybe a general solution is to introduce a way to define overloaded templates callable as functions, that get called if the input is a literal (or statically known, but D design requires you to asks explicitly for a CT evaluation):

void foo(static int[] a) {}
void foo(int[] a) {}
void main(string[] args) {
    foo([1, 2]); // calls first foo
    int[] a = [1, 2] ~ args.length;
    foo(a); // calls second foo
}


Bye,
bearophile
September 03, 2012
>if (a in handful("struct", "class", "union"))
>
>How is this different from
>
>if(canFind(["struct", "class", "union"], a) {...}

It's a lot cleaner without the mess of brackets. You missed a ) on the second one, which, without intending snarkiness, perhaps demonstrates the greater elegance of the former? Though being able to use in on a simple array would be very nice.

if(a in ["struct", "class", "union"])

Wouldn't you expect to search an array at O(n) while an associative array would be O(1), making the difference not unintuitive?
September 03, 2012
>>>> if (a.among("struct", "class", "union")) { ... }
>>>> if (b.between(1, 100)) { ... }
>>>
>>> Is between inclusive or not of the endpoints?
>>
>> After quite a bit of thought, I think inclusive is the right way.
>
> Then there's no way to specify an empty interval. I suppose with "between" that would not be relevant.

Perhaps b.between(1, 0) would always return false.

However I'd use different names: among=>isOneOf, between=>isInRange. I would also define another function inRange that ensures, rather than tests, that a value is in range:

string userInput = "-7";
int cleanInput = inRange(parse!int(userInput), 1, 100);
September 03, 2012
> However I'd use different names: among=>isOneOf, between=>isInRange.
I forgot to state the reason, namely, I think boolean functions should be named so that you can tell they return bool, as "between" could easily be a function that places a value into a range rather than tests whether it is in range.
September 03, 2012
On Monday, 3 September 2012 at 15:10:46 UTC, ixid wrote:
>>if (a in handful("struct", "class", "union"))
>>
>>How is this different from
>>
>>if(canFind(["struct", "class", "union"], a) {...}
>
> It's a lot cleaner without the mess of brackets.

I find the difference between »a in handful("struct", "class", "union")« and »["struct", "class", "union"].canFind(a)« to be largely a matter of taste – to me, the former introduces too much of a special case just to for a slightly nicer-looking syntax, whereas the other doesn't look bad either and reuses existing constructs.

David
September 03, 2012
On Monday, 3 September 2012 at 14:04:18 UTC, Andrei Alexandrescu wrote:
>> A sufficiently smart compiler (tm) could
>> optimize this to a efficient string "prefix switch statement" just as well…
>
> I agree. But then http://c2.com/cgi/wiki?SufficientlySmartCompiler.

This is exactly my point: My feeling is that the increased complexity by introducing a second syntax resp. a new special case (i.e. among) for such a simple operation is only worth it if it leaves no reason to revert to a hand-written replacement for performance reason, and I'm not sure if the signature taking runtime parameters is enough for that (without assuming such a sufficiently smart compiler).

David