digitalmars.dip.ideas - `is in` expression
- Quirin Schroll (54/54) Sep 05 A new kind of binary expression that tests whether the left-hand
- ltdk (3/26) Sep 05 My stupid question: why not just 'in' ?
- monkyyy (2/6) Sep 05 thats like 5 new ideas or not generic in the slightest
- Nick Treleaven (10/39) Sep 07 I thought there might be something for this in Phobos (e.g.
- Atila Neves (3/7) Sep 09 The party line until now has been to not support this because of
- Quirin Schroll (4/13) Sep 09 It depends on how you count. Since the list is a compile-time
- Clouudy (20/29) Sep 23 As far as I know, this isn't true. Or at least not universally
- Clouudy (3/4) Sep 24 Oh apparently it already is an operator. Well anyways most of my
- Atila Neves (7/27) Sep 25 *Some* ranges will have good performance, yes.
- Paul Backus (20/30) Sep 10 ```d
A new kind of binary expression that tests whether the left-hand side equals one of the right-hand values, or a range of values. It allows expressing intent in a very concise manner, on par with other modern languages. **Example:** ```d if (age is in 13 .. 20) // teenager ``` **Grammar:** ```d ShiftExpression is in ShiftExpression .. ShiftExpression ``` The first `ShiftExpression` is the *left-hand side*, the other two are called *lower* and *upper bound.* **Semantics:** It evaluates the left-hand side only once. Equivalent to ```d ((auto ref lhs) => lowerBound <= lhs && lhs < upperBound)(lhsExpr) ``` **Examples:** ```d if (color is in (red, green, blue)) { } alias basicColors = AliasSeq!(red, green, blue); if (color is in basicColors) { } if (color is in (basicColors, yellow)) { } ``` **Grammar:** ```d ShiftExpression is in ( Expression ) ShiftExpression is in ShiftExpression ``` **Semantics:** If the right-hand side starts with a parenthesis, it’s a comma-separated list of options. Those options can be compile-time sequences which are expanded. Otherwise, the right-hand side must be a compile-time sequence. Equivalent to: ```d (auto ref lhs) { switch (lhs) { static foreach (enum option; AliasSeq!(options)) { case option: } return true; default: return false; } }(lhsExpression) ```
Sep 05
On Friday, 5 September 2025 at 12:12:22 UTC, Quirin Schroll wrote:A new kind of binary expression that tests whether the left-hand side equals one of the right-hand values, or a range of values. It allows expressing intent in a very concise manner, on par with other modern languages. **Example:** ```d if (age is in 13 .. 20) // teenager ``` **Grammar:** ```d ShiftExpression is in ShiftExpression .. ShiftExpression ``` The first `ShiftExpression` is the *left-hand side*, the other two are called *lower* and *upper bound.* **Semantics:** It evaluates the left-hand side only once. Equivalent to ```d ((auto ref lhs) => lowerBound <= lhs && lhs < upperBound)(lhsExpr) ```My stupid question: why not just 'in' ? Julia has 'in' operator working with ranges
Sep 05
On Friday, 5 September 2025 at 12:12:22 UTC, Quirin Schroll wrote:A new kind of binary expression that tests whether the left-hand side equals one of the right-hand values, or a range of values. [...]thats like 5 new ideas or not generic in the slightest
Sep 05
On Friday, 5 September 2025 at 12:12:22 UTC, Quirin Schroll wrote:A new kind of binary expression that tests whether the left-hand side equals one of the right-hand values, or a range of values. It allows expressing intent in a very concise manner, on par with other modern languages. Range of values Example:if (age is in 13 .. 20) // teenagerI thought there might be something for this in Phobos (e.g. std.comparison), but I couldn't find it. E.g.: `age.between(13, 20)`List of valuesIs it significantly better than: https://dlang.org/phobos/std_algorithm_comparison.html#among ? `among` with runtime arguments also supports a predicate, so it's more flexible. ...**Semantics:** If the right-hand side starts with a parenthesis, it’s a comma-separated list of options. Those options can be compile-time sequences which are expanded.Can the options be runtime values?Otherwise, the right-hand side must be a compile-time sequence. Equivalent to: ```d (auto ref lhs) { switch (lhs) { static foreach (enum option; AliasSeq!(options)) { case option: } return true; default: return false; } }(lhsExpression) ```
Sep 07
On Friday, 5 September 2025 at 12:12:22 UTC, Quirin Schroll wrote:A new kind of binary expression that tests whether the left-hand side equals one of the right-hand values, or a range of values. [...]The party line until now has been to not support this because of performance, namely the fact that it would usually be O(N).
Sep 09
On Tuesday, 9 September 2025 at 11:07:42 UTC, Atila Neves wrote:On Friday, 5 September 2025 at 12:12:22 UTC, Quirin Schroll wrote:It depends on how you count. Since the list is a compile-time sequence, one could argue it’s O(1). The compiler could optimize it.A new kind of binary expression that tests whether the left-hand side equals one of the right-hand values, or a range of values. [...]The party line until now has been to not support this because of performance, namely the fact that it would usually be O(N).
Sep 09
On Tuesday, 9 September 2025 at 11:07:42 UTC, Atila Neves wrote:On Friday, 5 September 2025 at 12:12:22 UTC, Quirin Schroll wrote:As far as I know, this isn't true. Or at least not universally true. If you implement it as a set then it's possible to do some Bitmask magic, and it results in checks that are faster than if statements. At least that's how it's done in Pascal. And if you're doing groups of non-contiguous values like `if i in [0..3, 7, 9, 12..15] then`, it saves a lot of reading space, too. Of course this would only be constant-speed if it was a pre-defined set. I've actually had a similar use case for this within an emulator, where I had to combine a range and a nearby values within a switch statement, which could have been a lot more concise with sets. Even if there's a performance cost when using it for dynamic sets, I don't necessarily see the reason why it shouldn't be included. People are going to search the data structures in an O(N) manner regardless, and as long as it's not used within containers where the expectation is that everything is constant time, I don't see why the option shouldn't be present. You could just add it as an operator if you wanted to.A new kind of binary expression that tests whether the left-hand side equals one of the right-hand values, or a range of values. [...]The party line until now has been to not support this because of performance, namely the fact that it would usually be O(N).
Sep 23
On Wednesday, 24 September 2025 at 01:34:06 UTC, Clouudy wrote:You could just add it as an operator if you wanted to.Oh apparently it already is an operator. Well anyways most of my points still stand, I believe.
Sep 24
On Wednesday, 24 September 2025 at 01:34:06 UTC, Clouudy wrote:On Tuesday, 9 September 2025 at 11:07:42 UTC, Atila Neves wrote:Hence "usually".On Friday, 5 September 2025 at 12:12:22 UTC, Quirin Schroll wrote:As far as I know, this isn't true. Or at least not universally true.A new kind of binary expression that tests whether the left-hand side equals one of the right-hand values, or a range of values. [...]The party line until now has been to not support this because of performance, namely the fact that it would usually be O(N).If you implement it as a set then it's possible to do some Bitmask magic, and it results in checks that are faster than if statements.*Some* ranges will have good performance, yes.Even if there's a performance cost when using it for dynamic sets, I don't necessarily see the reason why it shouldn't be included. People are going to search the data structures in an O(N) manner regardless,Right, and the party line was that something like `countUntil` made that explicit. I'm not even arguing for what was said before, just explaining what the consensus was.
Sep 25
On Friday, 5 September 2025 at 12:12:22 UTC, Quirin Schroll wrote:A new kind of binary expression that tests whether the left-hand side equals one of the right-hand values, or a range of values. It allows expressing intent in a very concise manner, on par with other modern languages. **Example:** ```d if (age is in 13 .. 20) // teenager ``````d void checkAge(int age) { import std.range: interval = iota; import std.stdio: writeln; if (age in interval(1, 13)) writeln("child"); else if (age in interval(13, 20)) writeln("teenager"); else writeln("adult"); } void main() { checkAge(7); checkAge(16); checkAge(42); } ```
Sep 10