Why iterator is considered functional-style in the Python documentation?

Viewed 1163

I am trying to understand iterator. I notice Python documentation considers iterator to be a functional-style construct. I don't really understand it.

Isn't it true that iterator has a state inside it. So when you call it.__next__(), you mutate the state of the iterator. As far as I know, mutating state of an object is not considered functional, since functional programming emphasize on immutability and compose-ability of object/closure.

Actually, the problem comes up because I want to write a Scheme procedure/function which takes tokens and return a iterator.

(define tokens->iterator
  (lambda ls
    (lambda ()
      (if (null? ls)
          '*eoi*
          (let ((tok (car ls)))
            (set! ls (cdr ls))
            tok)))))

Notice I have to use set! to mutate ls, this is how I comes up with this question.

To use it,

(define it (tokens->iterator 1 '+ 2))

To test it,

scheme@(guile-user)> (it)
$2 = 1
scheme@(guile-user)> (it)
$3 = +
scheme@(guile-user)> (it)
$4 = 2
scheme@(guile-user)> (it)
$5 = *eoi*
scheme@(guile-user)> (it)
$6 = *eoi*

Just for fun, I also translate this to Python:

def tokens_to_iterator(*tup):
    ls = list(tup)
    def iterator():
        if not ls:
            return "*eoi*"
        else:
            tok = ls.pop(0)
            return tok
    return iterator

Similarly, the pop() method removes and return the first element by mutating the list.

To use it,

it = tokens_to_iterator(1, "+", 2)

To test it,

>>> it()
1
>>> it()
'+'
>>> it()
2
>>> it()
'*eoi*'
>>> it()
'*eoi*'

Can anyone clarify on this? By the way, I am using Python 3 and Guile Scheme in case anyone is interested in trying the examples.

2 Answers
Related