December 18, 2013
On 12/18/2013 09:06 PM, "Ola Fosheim Grøstad" <ola.fosheim.grostad+dlang@gmail.com>" wrote:
> On Wednesday, 18 December 2013 at 19:47:05 UTC, Andrei Alexandrescu wrote:
>> I don't think so. Algebraic properties have been derived from
>> desirable and useful properties and have long shown good returns.
>
> No, when you change the foundation/definitions some of the theorems will
> break. That always happens. I can't think of a single example where that
> does not happen.
>
> Some theorems are more important to uphold than others, it is a good
> thing to avoid breaking DeMorgans for instance.
> ...

Giving up Eg. ¬(A ∧ B) → ¬A ∨ ¬B is actually a sensible thing to do in constructive logic.
December 18, 2013
On Wednesday, 18 December 2013 at 20:45:44 UTC, Timon Gehr wrote:

> Giving up Eg. ¬(A ∧ B) → ¬A ∨ ¬B is actually a sensible thing to do in constructive logic.

It is common to give it up in fuzzy logic too, doesn't mean it is the first thing to throw out.

Anyway, the point in the discussion above is that of having a third value "uncertain"/"indeterminate" mapped to false and the consequences of that.

You don't want:
a<b == a>b, so ordering overlapping intervals is indeterminate

It is sensible to allow explicit:
bool(indeterminate)==false

If you then have:
[a,b]<[c,d] => indeterminate

And define == by < then it follows that:
[a,b]==[a,b] => indeterminate for a!=b

and:
bool([a,b]==[a,b]) => false

and therefore you would want:
bool([a,b]!=[a,b]) => true

Which is kind of tricky to achieve unless you have two types of indeterminate when I come to think of it, maybe you need indeterminate and not_indeterminate if you allow casts to bool… E.g. !indeterminate=> not_indeterminate and !not_indeterminate => indeterminate ?

Hm…
December 19, 2013
On 12/17/13, 4:38, Andrei Alexandrescu wrote:
> bool between(T, U1, U2)(T v, U1 lo, U2 hi)
> {
>      return v >= lo && v <= hi;
> }

The expression a<b<c is not ambiguous in D. We could make it do what people expect.


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

"in"?

assert("a" in ["a":1, "b":1]);

Again, with little compiler magic we could allow that to be written as

assert("a" in ["a", "b"]);

Note that I'm not advocating for O(n) "in" for regular arrays, but merely for the compiler to recognize the "in []" pattern and Do The Right Thing.

L.

December 19, 2013
Finally able to update the posts from the newsserver and saw both got mentioned before.

I agree with the "Don't change semantics of C code", so that rules out a<b<c.

L.
December 19, 2013
On Monday, 16 December 2013 at 20:38:52 UTC, Andrei Alexandrescu wrote:
> Add?

I've posted a PR[1] for an implementation of `among` that attempts to incorporate all the suggestions from this thread.

[1] https://github.com/D-Programming-Language/phobos/pull/1787
March 15, 2015
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

March 26, 2015
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));
    }
March 26, 2015
>
> 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
March 26, 2015
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.
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.

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