March 26, 2015
On 3/26/15 11:41 AM, Vladimir Panteleev wrote:
> On Sunday, 15 March 2015 at 01:48:53 UTC, Andrei Alexandrescu wrote:
>> On 12/16/13 12:38 PM, Andrei Alexandrescu wrote:
>>> bool between(T, U1, U2)(T v, U1 lo, U2 hi)
>>> {
>>>     return v >= lo && v <= hi;
>>> }
>>>
>>> Add?
>>
>> Looks like among() has proven its worth since we introduced it. Now I
>> somehow forgot between() didn't make it, and reviewed some code at
>> work assuming it exists!
>
> I don't know if it's been mentioned yet, but there exists an
> optimization for between with integer arguments:
>
> bool between(T, U1, U2)(T v, U1 lo, U2 hi)
>      if (is(T:long) && is(U1:long) && is(U2:long))
> {
>      return cast(Unsigned!T )v  - cast(Unsigned!U1)lo
>          <= cast(Unsigned!U2)hi - cast(Unsigned!U1)lo;
> }
>
> For this reason, I think this makes "between" non-trivial, so it is
> worth adding.

Wait, that doesn't work. 5.between(4, 3) returns true, should return false. -- Andrei
March 26, 2015
On Thursday, 26 March 2015 at 21:09:16 UTC, Andrei Alexandrescu wrote:
> On 3/26/15 11:41 AM, Vladimir Panteleev wrote:
>> I don't know if it's been mentioned yet, but there exists an
>> optimization for between with integer arguments:
>>
>> bool between(T, U1, U2)(T v, U1 lo, U2 hi)
>>     if (is(T:long) && is(U1:long) && is(U2:long))
>> {
>>     return cast(Unsigned!T )v  - cast(Unsigned!U1)lo
>>         <= cast(Unsigned!U2)hi - cast(Unsigned!U1)lo;
>> }
>>
>> For this reason, I think this makes "between" non-trivial, so it is
>> worth adding.
>
> Wait, that doesn't work. 5.between(4, 3) returns true, should return false. -- Andrei

Oh yeah, this assumes hi <= lo. I thought this was part of the function contract.
March 26, 2015
On Thursday, 26 March 2015 at 21:51:54 UTC, Vladimir Panteleev
wrote:
> Oh yeah, this assumes hi <= lo. I thought this was part of the function contract.

I meant lo <= hi
March 26, 2015
On 3/26/15 2:52 PM, Vladimir Panteleev wrote:
> On Thursday, 26 March 2015 at 21:51:54 UTC, Vladimir Panteleev
> wrote:
>> Oh yeah, this assumes hi <= lo. I thought this was part of the
>> function contract.
>
> I meant lo <= hi

New idea:

bool ordered(pred = "a < b")(T...)(T values)
{
    foreach (i, _; T[1 .. $])
    {
        if (binaryFun!pred(values[i], values[i - 1]) return false;
    }
    return true;
}

Instead of x.between(a, b) one would write ordered(a, x, b).

Cons: can't use the UFCS nicely. Doesn't generalize to all combinations of < and <=.

Pros: Consistent with isSorted so easy to grasp. Does generalize to testing multiple values.

Destroy!


Andrei

March 26, 2015
On Thu, Mar 26, 2015 at 03:23:12PM -0700, Andrei Alexandrescu via Digitalmars-d wrote:
> On 3/26/15 2:52 PM, Vladimir Panteleev wrote:
> >On Thursday, 26 March 2015 at 21:51:54 UTC, Vladimir Panteleev wrote:
> >>Oh yeah, this assumes hi <= lo. I thought this was part of the function contract.
> >
> >I meant lo <= hi
> 
> New idea:
> 
> bool ordered(pred = "a < b")(T...)(T values)
> {
>     foreach (i, _; T[1 .. $])
>     {
>         if (binaryFun!pred(values[i], values[i - 1]) return false;
>     }
>     return true;
> }
> 
> Instead of x.between(a, b) one would write ordered(a, x, b).
> 
> Cons: can't use the UFCS nicely. Doesn't generalize to all combinations of < and <=.
> 
> Pros: Consistent with isSorted so easy to grasp. Does generalize to testing multiple values.
> 
> Destroy!
[...]

Neat idea! This would let us translate mathematical statements of the form "1 < x < 2 < y < 3" to ordered(1, x, 2, y, 3), and various other combinations.

Don't like the name, though. Prefer 'isOrdered', otherwise it sounds like some kind of sorting algorithm (as in, returns an ordered sequence of its arguments).

As for combinations of < and <=, what about taking multiple template arguments? E.g.:

	if (isOrdered!("<", "<=")(0, x, 10)) { ... }


T

-- 
If it tastes good, it's probably bad for you.
March 26, 2015
On Thursday, 26 March 2015 at 22:30:54 UTC, H. S. Teoh wrote:
> As for combinations of < and <=, what about taking multiple template
> arguments? E.g.:
>
> 	if (isOrdered!("<", "<=")(0, x, 10)) { ... }
>
>

In that case, wouldn't it be more readable to just do:

    if (0 < x <= 10) { ... }

?
March 26, 2015
On 3/26/15 3:28 PM, H. S. Teoh via Digitalmars-d wrote:
> Don't like the name, though. Prefer 'isOrdered', otherwise it sounds
> like some kind of sorting algorithm (as in, returns an ordered sequence
> of its arguments).

Must be single-word name or nothing per Andrei's Hierarchy Of Naming Abstractions (AHONA). From low-level to high-level abstractions:

* If a realization is too simple and frequent, no abstraction should replace it.

* If a realization has high frequency but low complexity, it can only be replaced by an abstraction that is one simple word with no change of case. E.g. "among" is okay, "isAmong" is not.

* If a realization has high frequency and high complexity, it may be replaced by an abstraction with a multi-word name, little or no nesting, and few or no type parameters.

* If a realization has low frequency and high complexity, it may be replaced by an abstraction with a multi-word name, nesting, and type parameters.


Andrei

March 26, 2015
On Thu, Mar 26, 2015 at 03:48:26PM -0700, Andrei Alexandrescu via Digitalmars-d wrote:
> On 3/26/15 3:28 PM, H. S. Teoh via Digitalmars-d wrote:
> >Don't like the name, though. Prefer 'isOrdered', otherwise it sounds like some kind of sorting algorithm (as in, returns an ordered sequence of its arguments).
> 
> Must be single-word name or nothing per Andrei's Hierarchy Of Naming Abstractions (AHONA). From low-level to high-level abstractions:
> 
> * If a realization is too simple and frequent, no abstraction should replace it.
> 
> * If a realization has high frequency but low complexity, it can only be replaced by an abstraction that is one simple word with no change of case.  E.g. "among" is okay, "isAmong" is not.
> 
> * If a realization has high frequency and high complexity, it may be replaced by an abstraction with a multi-word name, little or no nesting, and few or no type parameters.
> 
> * If a realization has low frequency and high complexity, it may be replaced by an abstraction with a multi-word name, nesting, and type parameters.
[...]

If the bar is this high, then I vote against adding this function.

Writing `if (0 <= x && x < 10)` is far easier and has a clear meaning, whereas hiding it behind a poorly-named one-word abstraction actually hurts readability and therefore maintainability. IMO this falls under the first rule you listed above.


T

-- 
There are 10 kinds of people in the world: those who can count in binary, and those who can't.
March 27, 2015
On 3/26/15 4:03 PM, H. S. Teoh via Digitalmars-d wrote:
> On Thu, Mar 26, 2015 at 03:48:26PM -0700, Andrei Alexandrescu via Digitalmars-d wrote:
>> On 3/26/15 3:28 PM, H. S. Teoh via Digitalmars-d wrote:
>>> Don't like the name, though. Prefer 'isOrdered', otherwise it sounds
>>> like some kind of sorting algorithm (as in, returns an ordered
>>> sequence of its arguments).
>>
>> Must be single-word name or nothing per Andrei's Hierarchy Of Naming
>> Abstractions (AHONA). From low-level to high-level abstractions:
>>
>> * If a realization is too simple and frequent, no abstraction should
>> replace it.
>>
>> * If a realization has high frequency but low complexity, it can only
>> be replaced by an abstraction that is one simple word with no change
>> of case.  E.g. "among" is okay, "isAmong" is not.
>>
>> * If a realization has high frequency and high complexity, it may be
>> replaced by an abstraction with a multi-word name, little or no
>> nesting, and few or no type parameters.
>>
>> * If a realization has low frequency and high complexity, it may be
>> replaced by an abstraction with a multi-word name, nesting, and type
>> parameters.
> [...]
>
> If the bar is this high, then I vote against adding this function.
>
> Writing `if (0 <= x && x < 10)` is far easier and has a clear meaning,
> whereas hiding it behind a poorly-named one-word abstraction actually
> hurts readability and therefore maintainability. IMO this falls under
> the first rule you listed above.

https://github.com/D-Programming-Language/phobos/pull/3112 -- Andrei


March 27, 2015
On Thursday, 26 March 2015 at 22:23:12 UTC, Andrei Alexandrescu wrote:
> New idea:
>
> bool ordered(pred = "a < b")(T...)(T values)

So... isSorted for tuples?