Thread overview
"in" operator gives a pointer result from a test against an Associative Array?
May 10
Meta
May 10
tst7.d(6): Error: cannot implicitly convert expression `e in this.members` of type `bool*` to `bool`
tst7.d(15): Error: template instance `tst7.Foo!uint` error instantiating

I'm getting this for this bit of source (trimmed from the bigger code).  I switched to this.members.get(e, false) and that works fine, but I'm still curious:

struct Foo(T) {
    bool[T] members;

    bool
    has(T e) {
        return (e in this.members);
    }
}

void
main()
{
    import std.stdio : writeln;

    auto t = Foo!uint();
    writeln(t.has(123));
}
May 10

On Friday, 10 May 2024 at 00:18:16 UTC, Andy Valencia wrote:

>

tst7.d(6): Error: cannot implicitly convert expression e in this.members of type bool* to bool
tst7.d(15): Error: template instance tst7.Foo!uint error instantiating

I'm getting this for this bit of source (trimmed from the bigger code). I switched to this.members.get(e, false) and that works fine, but I'm still curious:

struct Foo(T) {
bool[T] members;

bool
has(T e) {
    return (e in this.members);
}

}

void
main()
{
import std.stdio : writeln;

auto t = Foo!uint();
writeln(t.has(123));

}

Yes. The reason for this is that it avoids having to essentially do the same check twice. If in returned a bool instead of a pointer, after checking for whether the element exists (which requires searching for the element in the associative array), you'd then have to actually get it from the array, which would require searching again. Returning a pointer to the element if it exists (or null if it doesn't) cuts this down to 1 operation.

May 10

On Friday, 10 May 2024 at 00:40:01 UTC, Meta wrote:

>

Yes. The reason for this is that it avoids having to essentially do the same check twice. If in returned a bool instead of a pointer, after checking for whether the element exists (which requires searching for the element in the associative array), you'd then have to actually get it from the array, which would require searching again. Returning a pointer to the element if it exists (or null if it doesn't) cuts this down to 1 operation.

Looking at Programming in D section 28.5, I'm guessing that pointer versus null is treated as the appropriate boolean value when consumed by an "if" test. So that example is getting a pointer to a string, or null, but the example looks exactly as the same as if it had directly gotten a bool.

Thank you!
Andy

May 10

On Friday, 10 May 2024 at 01:00:09 UTC, Andy Valencia wrote:

>

On Friday, 10 May 2024 at 00:40:01 UTC, Meta wrote:

>

Yes. The reason for this is that it avoids having to essentially do the same check twice. If in returned a bool instead of a pointer, after checking for whether the element exists (which requires searching for the element in the associative array), you'd then have to actually get it from the array, which would require searching again. Returning a pointer to the element if it exists (or null if it doesn't) cuts this down to 1 operation.

Looking at Programming in D section 28.5, I'm guessing that pointer versus null is treated as the appropriate boolean value when consumed by an "if" test. So that example is getting a pointer to a string, or null, but the example looks exactly as the same as if it had directly gotten a bool.

Yes, we say that a type has "truthiness" if it can be used in a condition (while, if, assert, etc).

For a pointer, null is considered "false", whereas any other value is considered "true". So you can use statements like if(key in aa) to test for membership. A very nice idiom is to check if a key is in an associative array, and if so, use the value that it maps to:

if(auto v = key in aa) {
   // use *v as the value here
}

You can change your code to return (e in this.members) !is null;

-Steve

May 10

On Friday, 10 May 2024 at 03:07:43 UTC, Steven Schveighoffer wrote:

>

Yes, we say that a type has "truthiness" if it can be used in a condition (while, if, assert, etc).

So if I may ask for one more small clarification... WRT "truthiness", I've observed that empty arrays are treated as false, non-empty as true. However, although I thought a string was basically an immutable array of characters, "" is treated as true, not false?

Thanks again,
Andy

May 10

On Friday, 10 May 2024 at 15:23:39 UTC, Andy Valencia wrote:

>

On Friday, 10 May 2024 at 03:07:43 UTC, Steven Schveighoffer wrote:

>

Yes, we say that a type has "truthiness" if it can be used in a condition (while, if, assert, etc).

So if I may ask for one more small clarification... WRT "truthiness", I've observed that empty arrays are treated as false, non-empty as true.

Arrays evaluate to true in boolean conditions if their .ptr field is non-null. This is bug-prone and I hope we can remove this in the next edition.

>

However, although I thought a string was basically an immutable array of characters, "" is treated as true, not false?

A string literal's .ptr field is always non-null, because it is null-terminated.

May 10

On Friday, 10 May 2024 at 16:33:53 UTC, Nick Treleaven wrote:

>

Arrays evaluate to true in boolean conditions if their .ptr field is non-null. This is bug-prone and I hope we can remove this in the next edition.
...
A string literal's .ptr field is always non-null, because it is null-terminated.

Thank you!

Andy