Comment #0 by bearophile_hugs — 2013-10-14T02:47:58Z
In Python sometimes I have code like this that I'd like to translate to D, it contains a pattern that was forbidden in D:
if (... and 1 < foo(2) < 10 and ...): ...
If the call to foo() is not pure or you don't want the risk of calling it two times, in D you have to split that if() in two and use an extra variable:
if (...) {
const temp = foo(2);
if (temp > 1 && temp < 10 && ...) { ...
}
}
To avoid some of such problems I suggest to add the support for the "in" operator to iota():
if (... && foo(2) in iota(1, 11) && ...) { ...
}
In another ehnancement request I've suggested to support the "[]" syntax in iota():
if (... && foo(2) in iota!"[]"(1, 10) && ...) { ...
}
This usage of iota is useful only for numerical intervals, so it doesn't cover all usages of the Python x<y<z syntax, but I think it covers most of my translations from Python.
Comment #1 by jack — 2015-08-22T19:00:59Z
This enhancement request makes no sense, as the "in" operator in Python and D do two completely different things.
To replicate the Python behavior, you can do the following:
import std.stdio, std.range, std.algorithm.searching;
void main() {
if (iota(1, 10).countUntil(foo(2)) > -1) {
"yes".writeln;
}
}
But I don't see why you would want to, as this is much faster:
void main() {
immutable int temp = foo(2);
if (temp >= 1 && temp <= 10) {
"yes".writeln;
}
}
Comment #2 by ag0aep6g — 2015-09-03T13:58:06Z
(In reply to Jack Stouffer from comment #1)
> This enhancement request makes no sense, as the "in" operator in Python and
> D do two completely different things.
>
> To replicate the Python behavior, you can do the following:
>
> import std.stdio, std.range, std.algorithm.searching;
>
> void main() {
> if (iota(1, 10).countUntil(foo(2)) > -1) {
> "yes".writeln;
> }
> }
>
> But I don't see why you would want to, as this is much faster:
>
> void main() {
> immutable int temp = foo(2);
> if (temp >= 1 && temp <= 10) {
> "yes".writeln;
> }
> }
The request is not for Python's `in`. The request is for a succinct way to do what Python's `1 < foo(2) < 10` does. The suggested solution with D's `in` would of course not do a linear search. Reopening.
Comment #3 by issues.dlang — 2015-09-04T19:50:18Z
in must be no worse than O(log n) or it is inappropriate to use it. And given how iota works, that can't possibly be done in anything better than O(n) in the general case, though it would be possible to implement it for integers specifically. Honestly though, this seems like an abuse of the in operator to me. in is really intended for lookup in containers. It's definitely not a range operation.
A better alternative would be to add find/canFind as a member function to iota in the cases where it would be more efficient than the std.algorithm implementation. Then any code which uses find/canFind with UFCS with iota and integral values would get a performance boost (including in generic code) rather than just this specific case where the code is specifically written for iota.
Comment #4 by bearophile_hugs — 2015-09-18T09:06:48Z
(In reply to Jonathan M Davis from comment #3)
> Honestly though, this seems like an abuse of the in
> operator to me. in is really intended for lookup in containers. It's
> definitely not a range operation.
There's a very nice "in" operator in D, that most other languages miss, and it's quite under-used, mostly for irrational reasons.
> in must be no worse than O(log n) or it is inappropriate to use it. And
> given how iota works, that can't possibly be done in anything better than
> O(n) in the general case, though it would be possible to implement it for
> integers specifically.
I agree. One solution is to not compile the "in" if the search is slower than O(log n), but it doesn't sound very nice.
> A better alternative would be to add find/canFind as a member function to iota
Using "in" for ranges like iota is more natural (here "natural" means that it requires the programmer to remember less things) than using find/canFind, but they seem acceptable.
Comment #5 by github-bugzilla — 2017-08-03T14:03:14Z