Skip to content

Instantly share code, notes, and snippets.

@edcrypt
Created August 30, 2017 21:19
Show Gist options
  • Save edcrypt/f253822512c4e073fb5747695902fa5b to your computer and use it in GitHub Desktop.
Save edcrypt/f253822512c4e073fb5747695902fa5b to your computer and use it in GitHub Desktop.
Basic message sending using generators as corotines
def Account(balance):
ret = None
while True:
# receive message
selector, *args = yield ret
# dispatch
if selector == 'withdraw':
print('Got withdraw')
new_balance = balance - args[0]
if new_balance < 0:
ret = 'NO LIMIT'
else:
balance = new_balance
ret = balance
elif selector == 'deposit':
print('Got deposit')
balance += args[0]
ret = balance
account = Account(100)
# init...
next(account)
print(account.send(['withdraw', 7]))
print(account.send(['deposit', 8]))
@edcrypt
Copy link
Author

edcrypt commented Sep 1, 2017

A philosophical question: what is an object?

Before you answer that, another one: what "sending a message to an object" means?

Let's say that an object is a computer. Not the literal machine, but an abstraction representing an agent that performs computations.

How is that different from a kind of function? In some level, it actually isn't. If you assume the definition from a late-binding, dynamic language like Smalltalk, you can imagine an object as a special kind of function: one that receives some parameters, the first one (let's call it a selector) used by the routine internally to switch between multiple ways that it could answer such a message.

Our function, of course, isn't just any kind of function*, but a kind of coroutine that wraps a loop with a "reusable switch/case".

While we can model object-oriented programming as this kind of routines, the result is something just as powerful and general.

This example is specially neat because it maps quite nicely to Smalltalk, with balance standing as an "instance variable", perfectly encapsulated inside our object. Also sending messages with .send() helps driving the point :P

See also: Funk.

* - In the semi-mathematical meaning, i.e. a kind of routine that takes arguments and returns a value, not literally the Python type function...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment