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.
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())
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.