Python-based monads essay part 2

Marko Rauhamaa marko at pacujo.net
Wed Oct 19 14:26:09 EDT 2016


Chris Angelico <rosuav at gmail.com>:

> On Thu, Oct 20, 2016 at 3:51 AM, Marko Rauhamaa <marko at pacujo.net> wrote:
>>
>>     def print(world, text, cont):
>>         return cont(World(past=world, offset=text))
>>
>>     def print_x_then_y(world, x, y, cont):
>>         return print(world, x, lambda world2: print(world2, y, cont))
>>
> [...]
>>
>> The end result is an ordered sequence of events. The topological order
>> is a causal order (you need the past world to construct the future
>> world), and causal order generates a temporal order.
>
> Yeah, nice. You just made a mutable object with significant order of
> evaluation and then added enough external information to it that you
> can pretend it's immutable and can be evaluated in any order.

Please point out what is mutable in my code above. It doesn't have a
single mutable object. The world is recreated with each interaction.

(Parenthetically, that's how quantum mechanics explains life, universe
and everything. Nothing ever changes. Immutable particles/systems simply
get destroyed and created with every interaction. In fact, particles can
be abstracted out as figments of imagination -- the existence is a
network of interactions.)

> I could make that same transformation with literally any function,
> simply by taking "the world" as an input and an output. It makes the
> entire concept utterly meaningless.

Whether this mental gymnastics is useful, everybody can form their own
opinion.

A funny, semirelated anecdote about Scheme. Scheme does not have a
try/finally construct. It can't -- Scheme is too powerful. That's
because in Scheme, nothing is [guaranteed to be] final. After you leave
an execution context, a continuation may leak out that enables a
system-wide jump in the middle of the context.

Python could have similar continuations if it added a "resume" keyword:

    def work(f):
        ...
        message_from_grave = raise ValueError()
        if message_from_grave == "CarryOn!":
            ...

    def guard_it():
        f = open(...)
        try:
            work(f)
        finally:
            f.close()

    def main():
        try:
            guard_it()
        except ValueError:
            # I'm having none of it!
            resume "CarryOn!"

The problem is, how can the file f unclose itself when work resumes?
Well, maybe we'd need another keyword:

    def guard_it():
        f = open(...)
        try:
            work(f)
        finally:
            f.close()
        nevermind:
            f.reopen()


Marko



More information about the Python-list mailing list