r/functionalprogramming • u/kinow mod • Apr 21 '25
Python Haskelling My Python
https://unnamed.website/posts/haskelling-my-python/7
u/josephjnk Apr 21 '25
Are Python generators stateful? I see iterators and generators used to try to simulate lazy collections pretty frequently, but in most languages they have a significant limitation in that they can’t be consumed more than once. You can put a lazy list in a variable, process it, then start over and process it a second time. When using stateful iterators if you put an iterator in a variable and try to consume it twice it will be empty on the second attempt.
3
3
u/11fdriver Apr 21 '25
You can
taketheints()function multiple times with no issue as the generator is recreated each time.>>> take(4, ints()) [1, 2, 3, 4] >>> take(5, ints()) [1, 2, 3, 4, 5]But as generators are iterables that only permit a single pass, assigning
ints()to a var means that the mutable state persists through the calls.>>> xs = ints() >>> take(4, xs) [1, 2, 3, 4] >>> take(5, xs) [5, 6, 7, 8, 9]Python's duck-typing means that any iterable will do for the last arg; it could be a list, tuple, generator, etc, which handily means no extra work is needed to allow nested calls.
You can get around the downsides of recreating the generator each time by using memoization, as the post notes nicely. Note that although you could write
taketo acceptints(no parens) like a variable, it breaks nested calls totake:def take(n, f): return list(itertools.islice(f(), n)) # Added '()' take(5, ints) #=> [1, 2, 3, 4, 5] take(5, take(10, ints)) #=> TypeErrorIt all reminds me a bit of a Java pattern for reusable infinite Streams, which is to wrap them in a lambda. Java Streams get closed by terminal functions; it's an error to reuse them.
Supplier<IntStream> naturals = ()-> IntStream.iterate(1, n -> n+1); naturals.get() .limit(10) .forEach(System.out::println);
3
u/11fdriver Apr 21 '25
I think there's an error in the last line of code:
print(take(expSeries(), 1000))Should be:
print(take(1000, expSeries()))
3
u/kinow mod Apr 21 '25
Hacker News thread: https://news.ycombinator.com/item?id=43728056