Re: between and among: worth Phobosization? (reprise)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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...