I often see code written like this:
if (value == somevalue ||
value == someothervalue ||
value == yetanothervalue);
You could use the switch statement. But that introduces indentation,
and is rarely used for a couple of values.
I really like the "in" keyword, and I also like hashes since they can
potentially speed up look-ups compared to conventional arrays. So I
thought it would be cool to have a Hash template that constructs an
associative array which you can use especially in if statements when
you just want to know if a runtime value matches some predetermined
value.
Here's my attempt at writing it:
http://codepad.org/c4sYDSyR
Whaddya think?

I really like the "in" keyword, and I also like hashes since they can
potentially speed up look-ups compared to conventional arrays.

The problem is, "potentially" means "for [relatively] large sets", as hashing
overhead will kill the benefits for smaller sets.
For 3, 5, 10 values chained if-then-else (or switch) will be *much* faster,
especially for basic types (and strings), especially when values are compared
according to frequency of usage.
Just run a benchmark - you will be surprised :)
For more than 10 values - I doubt that inline Hash! will be really readable,
I would rather define an array somewhere else.
OTOH, I like the idea of providing list of values "inline" for 'in' operator,
this, obviously, improves readability.
/Alexander

You seem to be right. It looks like DMD is pretty good at optimizing
if statements. The Hash version is quite a bit slower actually.
Well, that's what happens when I assume things. :)
Here's a little benchmark of searching an array and hash of randomly
generated strings:
http://pastebin.com/GddUn3e3
On my system (in milliseconds):
Length: 128
Hash Foreach: 334
Array Foreach: 61
Hash Lookup: 6
Array Lookup: 31
I guess what I was really looking for is syntax sugar that expands this:
if (variable in value1, value2, value3, value4)
into this:
if (variable == value1 || variable == value2...)
or something of that sort. Otherwise my Hash/hash functions are pretty
useless. Sorry for not researching before opening the topic.

Here's a little benchmark of searching an array and hash of randomly
generated strings:

Make it 16 values and run again :) Sure, the more elements we have, the
better hash performs.
But in case of ints/floats, for instance, for small sets especially, the
difference will be even more significant.
Chained ifs are better than array search (for fixed and known sets of values,
of course).

I guess what I was really looking for is syntax sugar that expands this:
if (variable in value1, value2, value3, value4)

Exactly - *that* would be very nice :) I believe this is easily doable using
templates & mixins, though, not using 'in' operator, but something like
InSet!(var, values...).
/Alexander

"InSet!(var, values...)."
That wouldn't work because var is known only at runtime. Ideally I'd
like to write something like:
string needle = "foo";
if (needle.InSet!("bar", "barfoo", "doo", "foo")) { }
And InSet would mixin and call a function such as:
bool inSet(string needle)
{
if (needle = "bar" || needle = "barfoo" || needle == "doo"
|| needle == "foo") return true;
return false;
}
However I don't think this is possible. I want the string literals to
be binded at compile time, and needle to be binded at runtime with the
UFC syntax. However in this case the compiler tries to pass needle as
a compile-time argument, which fails.

"InSet!(var, values...)."
That wouldn't work because var is known only at runtime. Ideally I'd
like to write something like:
string needle = "foo";
if (needle.InSet!("bar", "barfoo", "doo", "foo")) { }
And InSet would mixin and call a function such as:
bool inSet(string needle)
{
if (needle = "bar" || needle = "barfoo" || needle == "doo"
|| needle == "foo") return true;
return false;
}
However I don't think this is possible. I want the string literals to
be binded at compile time, and needle to be binded at runtime with the
UFC syntax. However in this case the compiler tries to pass needle as
a compile-time argument, which fails.

Well, just a bit - still much better than (var == "..." || var = "..." || var
== "..." ...), don't you think so? ;)
If compiler would support special "in" usage, automatically expanding values
on the right to series of comparisons (like "var in [1,2,3,4,5]"), it would be
really nice, of course :)
/Alexander

Well, just a bit - still much better than (var == "..." || var = "..." ||
var == "..." ...), don't you think so? ;)
If compiler would support special "in" usage, automatically expanding
values on the right to series of comparisons (like "var in [1,2,3,4,5]"), it
would be really nice, of course :)

That was discussed, too. Walter and I support that although it's a
special case. We didn't get around to talk the purist police into
accepting it.
Andrei

If compiler would support special "in" usage, automatically expanding
values on the right to series of comparisons (like "var in [1,2,3,4,5]"), >>it

would be really nice, of course :)

That was discussed, too. Walter and I support that although it's a
special case. We didn't get around to talk the purist police into
accepting it.
Andrei

Why is this a special case? The 'in' could be extended operator to generally
work
on arrays (using a simple linear search). The compiler could then optimize the
given expression the way suggested (actually even to 1<=var&&var<=5).
Why is 'in' not currently defined on arrays? To me it seems like a left-out that
should be fixed, because it has quite obvious and useful semantics.
Timon

Well, just a bit - still much better than (var == "..." || var = "...">||

var == "..." ...), don't you think so? ;)

If compiler would support special "in" usage, automatically expanding
values on the right to series of comparisons (like "var in [1,2,3,4,5]"),>>it

would be really nice, of course :)

That was discussed, too. Walter and I support that although it's a
special case. We didn't get around to talk the purist police into
accepting it.
Andrei

Why is this a special case? The 'in' could be extended operator to generally
work
on arrays (using a simple linear search). The compiler could then optimize the
given expression the way suggested (actually even to 1<=var&&var<=5).
Why is 'in' not currently defined on arrays? To me it seems like a left-out
that
should be fixed, because it has quite obvious and useful semantics.
Timon

This has been discussed many times before and the general argument
against it is that "in" is available for associative arrays and it tests
for keys. With arrays it would test for values.
--
/Jacob Carlborg

Well, just a bit - still much better than (var == "..." || var =
"...">||

var == "..." ...), don't you think so? ;)

If compiler would support special "in" usage, automatically expanding
values on the right to series of comparisons (like "var in
[1,2,3,4,5]"),>>it

would be really nice, of course :)

That was discussed, too. Walter and I support that although it's a
special case. We didn't get around to talk the purist police into
accepting it.
Andrei

Why is this a special case? The 'in' could be extended operator to
generally work
on arrays (using a simple linear search). The compiler could then
optimize the
given expression the way suggested (actually even to 1<=var&&var<=5).
Why is 'in' not currently defined on arrays? To me it seems like a
left-out that
should be fixed, because it has quite obvious and useful semantics.
Timon

This has been discussed many times before and the general argument
against it is that "in" is available for associative arrays and it tests
for keys. With arrays it would test for values.

The only thing I can compare this with is python's 'in' operator. It's
purpose is different though. In python, 'in' returns a boolean, and the
operator works for any sequence. Associative arrays can return a set of
keys (hashed), or a list (array) of values, and the 'in' operator can be
used on either, but defaults to keys.
Not only have I missed a 'set' data structure, but I have missed the
'in' for arrays as well. It's value is suspect when we consider that
currently the 'in' operator returns a pointer to the value in the
associative array. What would we do for an array? You don't need the
pointer to the value, because you have the value already that you're
looking for. I see the value in returning the pointer in the associative
array, so you don't have to do the look-up again.
My argument is that all sequences and containers should support some
flavor of the "Do I contain this?" question. How many times are we asked
to build a collection bucket, and then asked to retrieve something put
in there? In the case of the OP, he has a static compile-time bucket
that he wants to go poking around in.
If we had a built-in "set" data structure (you know, just the key
portion of the Associative array), we would solve the OP's problem, and
make some of my dreams come true.

Well, DMD accepts this kind of syntax already:
if (value == val1, val2, val3) { }
I think this turns the expression value==val1 into a bool, and then
turns val2 and val3 into bools and compares against each of them. Or
something like that. It's odd and I've never seen it used anywhere.
Maybe we could put that syntax into good use.

Well, DMD accepts this kind of syntax already:
if (value == val1, val2, val3) { }
I think this turns the expression value==val1 into a bool, and then
turns val2 and val3 into bools and compares against each of them. Or
something like that. It's odd and I've never seen it used anywhere.
Maybe we could put that syntax into good use.

Wouldn't it be nice if you could do something like this:
if (value == (3 || 4)) {}
And the compiler turns that into:
if (value == 3 || value == 4) {}
--
/Jacob Carlborg

Well, DMD accepts this kind of syntax already:
if (value == val1, val2, val3) { }
I think this turns the expression value==val1 into a bool, and then
turns val2 and val3 into bools and compares against each of them. Or
something like that. It's odd and I've never seen it used anywhere.
Maybe we could put that syntax into good use.

Wouldn't it be nice if you could do something like this:
if (value == (3 || 4)) {}
And the compiler turns that into:
if (value == 3 || value == 4) {}

Well, DMD accepts this kind of syntax already:
if (value == val1, val2, val3) { }
I think this turns the expression value==val1 into a bool, and then
turns val2 and val3 into bools and compares against each of them. Or
something like that. It's odd and I've never seen it used anywhere.
Maybe we could put that syntax into good use.

Wouldn't it be nice if you could do something like this:
if (value == (3 || 4)) {}
And the compiler turns that into:
if (value == 3 || value == 4) {}

Sure, if you like ambiguous grammars that break a fundamental property
of expressions.
:-)

Well, DMD accepts this kind of syntax already:
if (value == val1, val2, val3) { }
I think this turns the expression value==val1 into a bool, and then
turns val2 and val3 into bools and compares against each of them. Or
something like that. It's odd and I've never seen it used anywhere.
Maybe we could put that syntax into good use.

Wouldn't it be nice if you could do something like this:
if (value == (3 || 4)) {}
And the compiler turns that into:
if (value == 3 || value == 4) {}

Sure, if you like ambiguous grammars that break a fundamental property
of expressions.
:-)

Well, I didn't think THAT far ahead :) . It just looks like a nice syntax.
--
/Jacob Carlborg

Well, DMD accepts this kind of syntax already:
if (value == val1, val2, val3) { }
I think this turns the expression value==val1 into a bool, and then
turns val2 and val3 into bools and compares against each of them. Or
something like that. It's odd and I've never seen it used anywhere.
Maybe we could put that syntax into good use.

That should evaluate each of the expressions in order and take the value of
the last one. So, ultimately, unless there are side effects to value == val1
or implicitly converting val2 to bool (which there shouldn't be), then the
result of the if condition will always be boolean equivalent of val3. That's
not doing what you're looking for at all. And making it do what you want would
alter the behavior of the comma operator, which wouldn't be good.
- Jonathan M Davis

I know it's not doing that, it was a hypothetical. What I'm saying is
I've never seen the comma used this way in code.

Well, it would almost certainly be bad practice to do so. The comma operator
can be very useful in some cases (such as for loops) but should generally be
avoided. Here, it's utterly pointless. However, changing what it did in this
particular case - as useful as that might be - would make the comma operator
inconsistent, which could have serious consequences.
- Jonathan M Davis

I often see code written like this:
if (value == somevalue ||
value == someothervalue ||
value == yetanothervalue);
You could use the switch statement. But that introduces indentation,
and is rarely used for a couple of values.
I really like the "in" keyword, and I also like hashes since they can
potentially speed up look-ups compared to conventional arrays. So I
thought it would be cool to have a Hash template that constructs an
associative array which you can use especially in if statements when
you just want to know if a runtime value matches some predetermined
value.
Here's my attempt at writing it:
http://codepad.org/c4sYDSyR
Whaddya think?

I often see code written like this:
if (value == somevalue ||
value == someothervalue ||
value == yetanothervalue);
You could use the switch statement. But that introduces indentation,
and is rarely used for a couple of values.
I really like the "in" keyword, and I also like hashes since they can
potentially speed up look-ups compared to conventional arrays. So I
thought it would be cool to have a Hash template that constructs an
associative array which you can use especially in if statements when
you just want to know if a runtime value matches some predetermined
value.
Here's my attempt at writing it:
http://codepad.org/c4sYDSyR
Whaddya think?

I often see code written like this:
if (value == somevalue ||
value == someothervalue ||
value == yetanothervalue);
You could use the switch statement. But that introduces indentation,
and is rarely used for a couple of values.
I really like the "in" keyword, and I also like hashes since they can
potentially speed up look-ups compared to conventional arrays. So I
thought it would be cool to have a Hash template that constructs an
associative array which you can use especially in if statements when
you just want to know if a runtime value matches some predetermined
value.
Here's my attempt at writing it:
http://codepad.org/c4sYDSyR
Whaddya think?

This is generally 2~3 times slower than a compile-time solution if the
keys are known in advance (and the former is 1~2 times slower than using
x == y || x == z || ... directly)
(Why do you still use opIn_r? ;) )

You need to replace the assert and compile with -O -release -inline. My
results:

[snip]
Still, straight comparison wins - 2x faster ;)
/Alexander

When understanding the CPU platform you are on, one of the benchmarks
you can do is to measure how many linear integer comparions you can do
vs a binary search of the same size, and graph it out.
There is a crossover point where the binary search will be faster, but
with modern CPUs the number of linear items you can search increases
every year.
The linear search also makes extremely good use of the cache and
hardware prefetching, and the branches (as well as the loop itself) will
be predicted correctly until the terminating condition is found, where
the binary search is mispredicted 50% of the time. The last time I
measured the crossover point around 60 integer values, and it wouldn't
surprise me at all that its over 100 on newer chipsets (Sandy Bridge,
Bulldozer etc).