September 02, 2012
On 9/2/2012 7:45 AM, Andrei Alexandrescu wrote:
> On 9/2/12 4:22 PM, Andrei Alexandrescu wrote:
> [snip]
>
> The alternative would be to simply define these as functions:
>
> if (a.among("struct", "class", "union")) { ... }
> if (b.between(1, 100)) { ... }

Is between inclusive or not of the endpoints?
September 02, 2012
On Sunday, 2 September 2012 at 15:09:50 UTC, deadalnix wrote:
> Le 02/09/2012 16:51, Jacob Carlborg a écrit :
>> I really don't like the name "handful". What would be the difference
>> compared to a regular set container? To me it sounds like we should have
>> a standard set container in Phobos, std.container.set.
>>
>
> +1, and we are back to the allocator design.

+2 on the basis of typical "real world" (if I may says so) usage. It calls for a set container, both mutable and immutable.

For a "handful" of values (say 5 or less), I'm not even sure the O(1) method is faster than the O(n) one.

As for the intervals, I suppose one would have to define open intervals, because I think they would be much more useful than closed ones when the intervals are contiguous (in particular with floats/doubles).
One must be able to translate x0 <= x < x1 in intervals else they are practically useless for anything else than integers and other discrete values.
September 02, 2012
On Sunday, 2 September 2012 at 16:44:40 UTC, 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

Without second thought, I'd say std.container.set for the first, std.functional for the second (not too sure about it).

September 02, 2012
string a = "class";
if (a in tuple("struct", "class", "union"))
{
    ...
}
September 02, 2012
On Sun, 02 Sep 2012 22:24:17 +0200, Walter Bright <newshound2@digitalmars.com> wrote:

> On 9/2/2012 7:45 AM, Andrei Alexandrescu wrote:
>> On 9/2/12 4:22 PM, Andrei Alexandrescu wrote:
>> [snip]
>>
>> The alternative would be to simply define these as functions:
>>
>> if (a.among("struct", "class", "union")) { ... }
>> if (b.between(1, 100)) { ... }
>
> Is between inclusive or not of the endpoints?

struct Between(string boundaries = "[]", T) {
    ...
}

?

-- 
Simen
September 02, 2012
On Sunday, September 02, 2012 16:22:20 Andrei Alexandrescu wrote:
> I'd like to add a simple function to std called "handful". It would return a small, read-only set of which main facility is membership test:
> 
> string a = "class";
> if (a in handful("struct", "class", "union"))
> {
>      ...
> }
> 
> Would it be generally useful, and if so what module does it belong to?

How is this different from

if(canFind(["struct", "class", "union"], a) {...}

Is it because it can be made more efficient? From a usage standpoint, they're essentially the same.

> Same question about "interval", which is a fair amount more interesting if done right. An interval is a pair of values from a type that supports inequality comparison. It would have a variety of interval-specific operations, of which this would probably be quite popular:
> 
> int x;
> ...
> if (x in interval(1, 2))
> {
>      ...
> }

I take it that that's a closed interval (opened vs closed would potentially complicate this a bit)? If so, then that's the same as

if(x >= 1 && x <= 2) {...}

right? That's kind of nice and kind of pointless. It's slightly less verbose, but unless the optimizer does a lot better than it's probably going to do, you're gonig to take a performance hit. The only real advantage there that I see is that it's a bit more idomatic.

Though, on thinking about it, it _would_ have the advantage of allowing you to pass around an interval, which doesn't work anywhere near as well with separate values. And if the interval is doing a lot more than in, then that could make it valuable as well.

But the example doesn't really do much to show interval's value IMHO.

- Jonathan M Davis
September 02, 2012
On Sunday, September 02, 2012 19:12:30 bearophile wrote:
> Is interval() for time intervals too? :-)

We already have those:

std.dateteme.Interval
std.datetime.PosInfInterval
std.datetime.NegInfInterval

But if all interval needs to work is the comparison operators, then it would work with the various time point types in std.datetime.

- Jonathan M Davis
September 02, 2012
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
September 02, 2012
On 9/2/12 10:24 PM, Walter Bright wrote:
> On 9/2/2012 7:45 AM, Andrei Alexandrescu wrote:
>> On 9/2/12 4:22 PM, Andrei Alexandrescu wrote:
>> [snip]
>>
>> The alternative would be to simply define these as functions:
>>
>> 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. There are two reasons:

1. Ranges that end in e.g. float.max or int.max would not be expressible if bounds were not included.

2. SQL defines between to include the limits, which sets a precedent.

Ranges are open to the right but I think intervals are quite different.


Andrei
September 02, 2012
On Monday, September 03, 2012 01:37:19 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...

Well, from the looks of it, handful (or among or whatever you want to call it) is basically a functor for canFind (just with in instead of parens). So, it's an algorithm that's been thrown into a struct rather than kept as a separate function - kind of like map or other lazy, range-based functions except that it's using in instead of the range API. So, I think that it fits in std.algorithm reasonably well, but it _is_ also a bit of an odd fit. I think that the problem is that you're essentially introducing a new idiom, and it doesn't quite fit anywhere in what we have.

- Jonathan M Davis