Re: between and among: worth Phobosization? (reprise)

2015-03-14 Thread Andrei Alexandrescu via Digitalmars-d

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;
}

uint among(T, Us...)(T v, Us vals)
{
 foreach (i, U; Us)
 {
 if (v == vals[i]) return i + 1;
 }
 return 0;
}

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! Here's the original and proposed in a couple of 
snippets:


return (path.asPath.logicalLength() <= asPathLengths_[1] &&
path.asPath.logicalLength() >= asPathLengths_[0]);

=>

return path.asPath.logicalLength.between(asPathLengths_[0], 
asPathLengths_[1]);




if (prefix.prefixLen > prefixLenRange_[1] ||
prefix.prefixLen < prefixLenRange_[0]) {

=>

if (!prefix.prefixLen.between(prefixLenRange_[0], prefixLenRange_[1])) {



Well?


Andrei



Re: between and among: worth Phobosization? (reprise)

2015-03-26 Thread Jesse Phillips via Digitalmars-d
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;
}

uint among(T, Us...)(T v, Us vals)
{
foreach (i, U; Us)
{
if (v == vals[i]) return i + 1;
}
return 0;
}

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! Here's the original and 
proposed in a couple of snippets:


return (path.asPath.logicalLength() <= asPathLengths_[1] &&
path.asPath.logicalLength() >= asPathLengths_[0]);

=>

return path.asPath.logicalLength.between(asPathLengths_[0], 
asPathLengths_[1]);




if (prefix.prefixLen > prefixLenRange_[1] ||
prefix.prefixLen < prefixLenRange_[0]) {

=>

if (!prefix.prefixLen.between(prefixLenRange_[0], 
prefixLenRange_[1])) {




Well?


Andrei


I think it would be a good addition. Would we want to allow 
specifying the inclusion like below:


auto between(string inclusion = "[]")(int v, int a, int b) {
static if(inclusion == "(]")
return (v <= b && v > a);
else static if(inclusion == "[)")
return (v < b && v >= a);
else static if(inclusion == "()")
return (v < b && v > a);
else static if(inclusion == "[]")
return (v <= b && v >= a);
else
static assert(false, "unknown inclusion parameter");
} unittest {
static assert(4.between(3,5));
static assert(4.between(4,5));
static assert(4.between(3,4));

static assert(!4.between!"(]"(4,5));
static assert(!4.between!"[)"(3,4));
}


Re: between and among: worth Phobosization? (reprise)

2015-03-26 Thread Tobias Pankrath via Digitalmars-d




I think it would be a good addition. Would we want to allow 
specifying the inclusion like below:


auto between(string inclusion = "[]")(int v, int a, int b) {


+1


Re: between and among: worth Phobosization? (reprise)

2015-03-26 Thread Vladimir Panteleev via Digitalmars-d
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.


Re: between and among: worth Phobosization? (reprise)

2015-03-26 Thread Andrei Alexandrescu via Digitalmars-d

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.


Hmmm... so we have two subtractions and one comparisons vs. two 
comparisons and a jump in between. I think you're right! -- Andrei


Re: between and among: worth Phobosization? (reprise)

2015-03-26 Thread Andrei Alexandrescu via Digitalmars-d

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


Re: between and among: worth Phobosization? (reprise)

2015-03-26 Thread Vladimir Panteleev via Digitalmars-d

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


Re: between and among: worth Phobosization? (reprise)

2015-03-26 Thread Vladimir Panteleev via Digitalmars-d
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.


Re: between and among: worth Phobosization? (reprise)

2015-03-26 Thread Andrei Alexandrescu via Digitalmars-d

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



Re: between and among: worth Phobosization? (reprise)

2015-03-26 Thread H. S. Teoh via Digitalmars-d
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.


Re: between and among: worth Phobosization? (reprise)

2015-03-26 Thread Jakob Ovrum via Digitalmars-d

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) { ... }

?


Re: between and among: worth Phobosization? (reprise)

2015-03-26 Thread Andrei Alexandrescu via Digitalmars-d

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



Re: between and among: worth Phobosization? (reprise)

2015-03-26 Thread H. S. Teoh via Digitalmars-d
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.


Re: between and among: worth Phobosization? (reprise)

2015-03-26 Thread Andrei Alexandrescu via Digitalmars-d

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




Re: between and among: worth Phobosization? (reprise)

2015-03-26 Thread Vladimir Panteleev via Digitalmars-d
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?


Re: between and among: worth Phobosization? (reprise)

2015-03-26 Thread H. S. Teoh via Digitalmars-d
On Fri, Mar 27, 2015 at 01:37:45AM +, Vladimir Panteleev via Digitalmars-d 
wrote:
> 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?

That's pretty much what it is, and I'm wondering why use a completely
different name rather than overload isSorted.


T

-- 
Не дорог подарок, дорога любовь.


Re: between and among: worth Phobosization? (reprise)

2015-03-27 Thread John Colvin via Digitalmars-d

On Friday, 27 March 2015 at 01:53:22 UTC, H. S. Teoh wrote:
On Fri, Mar 27, 2015 at 01:37:45AM +, Vladimir Panteleev 
via Digitalmars-d wrote:
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?


That's pretty much what it is, and I'm wondering why use a 
completely

different name rather than overload isSorted.


T


import std.typecons : ∑ = tuple;

∑(a, x, b).isSorted;

Or maybe not, haha! It's kinda tempting for personal projects, as 
∑ is just alt-w on my macbook...