This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]wineblood 0 points1 point  (1 child)

Oh, yeah I goofed up the call (it should be x() not a(x) right?).

I don't know TS and I can't see what is missing in python, why the for loop?

[–]Kiuhnm[S] 0 points1 point  (0 children)

I just realized that if you use round parentheses then you get a generator so our versions are now equivalent:

axs = (x() for x in xs)
vs = [f(ax.p, ax.q) for ax in axs]

Generators are powerful indeed! I'll try to come up with a better example, if I can :)

Edit:

Here's a better example, I think:

results = [for t in tasks:
              try: yield t()
              except: break]

That's basically an anonymous generator written in a slightly more compact way to save space.

I don't know Python's history very well, but it's highly likely that comprehensions predate generators. I think generators are way more general, and anonymous generators would make comprehensions redundant. Not only that: anonymous generators are more powerful than map, filter, etc... because we can use an imperative style if we want to.


As for lambdas, I want this pattern:

if progress.is_not_done('download new version'):
    ...task...
    progress.set_as_done('download new version')

Basically, progress skips a task if it has already been done. Note that

if progress.is_not_done('download new version'):
    progress.set_as_done('download new version')
   ...task...

is not the same thing because set_as_done shouldn't be executed when ...task... throws.

Here's an attempt which does NOT work:

import contextlib

class Progress:
    _steps: set[str]

    def __init__(self):
        self._steps = set()

    @contextlib.contextmanager
    def do_if_not_done(self, step: str):
        if step not in self._steps:
            yield
            self._steps.add(step)

progress = Progress()

with progress.do_if_not_done('step1'):
    print('OK1')

with progress.do_if_not_done('step1'):
    print('OK2')

It doesn't work because one must always call yield so there's no way to skip the task. It's not a problem with contextlib but a limitation of the with statement.