Threads for softwaredoug

  1. 8

    Python’s approach may require fewer concepts / abstractions and may be one of the reasons of it’s success, even if lately with the latest releases they seem be quickly increase in number (I’m thinking about async/await, typing, walrus and pattern matching). The real enpowerer of Ruby mental model seems to be the code block, which is something at same time more powerful and expressive than Python’s lambdas.

    The Python’s for enabled class is complete fiction:

    class Stuff:
        def __init__(self):
            self.a_list = [1,2,3,4]
            self.position = 0
        def __next__(self):
            try:
                value = self.a_list[self.position]
                self.position += 1
                return value
            except IndexError:
                self.position = 0
                raise StopIteration
        def __iter__(self):
            return self
    

    A shared position? What’s for? You would instead code or see something like:

    class Stuff:
        def __init__(self):
            self.a_list = [1,2,3,4]
        def __iter__(self):
            for item in self.a_list:
                yield item
    

    which is way more similar to the Ruby’s one. Or:

    class Stuff:
        def __init__(self):
            self.a_list = [1,2,3,4]
        def __iter__(self):
            return iter(self.a_list)
    
    1. 3

      I wouldn’t say the number of required elements really increased that significantly: async/await - it’s optional and trivial if you were doing twisted/green before; typing - completely optional; walrus and pattern matching - those are new elements, but only the patterns go beyond syntax sugar. Python continues to be fairly conservative with regards to actually required changes.

      But yeah, the python iteration from the post is super contrived and basically wrong.

      1. 1

        Shared position is not correct but you’re kinda missing the point. They could’ve omitted the body entirely, what matters is the interface: def __iter__(self) does not take a code block. It is a generator producing values for the outer code that’s driving the outer loop.

        1. 1

          I’ve not missed that, I was just stating that where the Python source may seem more complex, no one would code an iteration enabled class like that.

        2. 1

          Python’s approach may require fewer concepts / abstractions

          Why do you say that? From working in Ruby some time back, and working with Python now, it seems to me that the amount of abstractions ruby uses at the language level seems to be much smaller than Python. (e.g. No with, no separate concept of iterators, no comprehensions etc. – everything is blocks).

          1. 1

            The Python’s for enabled class is complete fiction:

            Author here, thanks, I kinda knew this when I wrote it and wanted to avoid teaching the user half-a-dozen contepts to get to the more concise version. In the end, nobody would iterate a list of consecutive numbers this way anyway, they’d use range :)

            There’s a similar issue in Ruby, you would use Enumerable mixin, not define a select, map etc. But the effect and point is the same.

            But perhaps I should put a note to these better practices so nobody is copy-pasting code