But in Haskell, the `where` keyword also considers scoping. That is, outside the statement/expression with the `where`, you can't access the variables introduced by the where.
Yes, but I wanted it to be simple and powerful, not necessarily right in every context.
Even though the `where` looks kind-of-nice, it (at least to me) is also
a bit confusing with respect to evaluation order. Consider
[ stripped for idx, line in enumerate(lines) if idx >= 5 or stripped
where stripped=line.strip() ]
(intended semantics: give me all lines (stripped), but ignore any lines that are whitespace-only in the first 5 lines)
retval =  for idx, line in enumerate(lines): stripped = line.strip() if idx >= 5 or stripped: retval.append(stripped)
now I'm not very sure, but I expect what actually happens is:
retval =  for idx, line in enumerate(lines): if idx < 5: stripped = line.strip() if idx >= 5 or stripped: retval.append(stripped)
that is, should I read it as (if idx >= 5 or stripped) where stripped=line.strip() or if idx >= 5 or (stripped where stripped=line.strip())
I've implemented it as "or_test [where_expr]" so the default order is the same as in: (if idx >= 5 or stripped) where stripped=line.strip()
I wanted it to always "scope" left as much as possible - in precedence order between "lambda" and "... if ... else ..." - but left recursion forced me to place it after "... if ... else ..." which can't be used without brackets in list comprehension "if" filtering. But one can always control order with brackets, and make it work like in second example.
For comprehensions, I'd think the 'let' statement might make more sense.
Abusing Haskell's notation:
[ stripped | (idx, line) <- zip [0..] lines, let stripped = strip
line, idx >= 5 || length stripped > 0 ]
Porting this to something Python-ish, it'd be
[ stripped for idx, line in enumerate(lines) let stripped =
line.strip() if idx >= 5 or stripped ]
where `let` is a keyword (possibly only applicable in a compexpr). In Haskell it's a keyword everywhere, but it has somewhat different semantics.
I was thinking about "let", but as I said, I think that new keyword should be more powerful than just filtering in list comprehensions, and in regular expresions it would look like this: if let x=foo() in x: print(x)
Which does not look great, and there is problem with "in" keyword that make this expresion ambiguous.