Guido asked me to move it here. anyway, i might as well state my case better.<br><br>in the formal definitions of object oriented programming, objects <br>are said to encapsulate state and behavior. behavior is largely dependent
<br>on the type of the object, but the state is important nonetheless.<br><br>for example, file objects are stateful: they can be opened for reading-only,<br>writing-only, both, or be closed altogether. still, they are all instances
<br>of the file type.<br><br>since generic functions/multi-dispatch come to help the programmer<br>by reducing boilerplate early type-checking code and providing a<br>more capable dispatch mechanism -- we can't overlook the state of the 
<br>object.<br><br>this early type-checking goes against the spirit of pure duck typing (which<br>i'm fond of), but is crucial when the code has side effects. in this case,<br>you can't just start executing the code and "hope it works", as the 
<br>resources (i.e., files) involved are modified. in this kind of code, you<br>want to check everything is alright *instead* of suddenly having <br>an AttributeError/TypeError somewhere.<br><br>here's an example:<br>
<br>@dispatch<br>def copy(src: file, dst: file):<br>    while True:<br>        buf = src.read(1000)<br>        if not buf: break<br>        dst.write(buf)<br><br>suppose now that dst is mistakenly opened for reading.<br>this means src would have already been modified, while
<br>dst.write is bound to fail. if src is a socket, for instance, <br>this would be destructive.<br><br>so if we already go as far as having multiple dispatch, which imposes<br>constraints on the arguments a function accepts, we might as well 
<br>base it on the type and state of the object, rather than only on it's type.<br><br>we could say, for example:<br><br>@dispatch<br>
def copy(src: file_for_reading, dst: file_for_writing):<br><br>file_for_reading is not a type -- it's a checker. it may be defined as <br><br>def file_for_reading(obj: file):<br>    return file.mode == "r" and not 
file.closed<br><br>types, by default, would check using isinstance(), but costume<br>checkers could check for stateful requirements too.<br><br>and a note about performance: this check is required whether<br>it's done explicitly or by the dispatch mechanism, and since
<br>most functions don't require so many overloads, i don't think<br>it's an issue.<br><br>besides, we can have a different decorator for dispatching<br>by type or by checkers, i.e., @dispatch vs @stateful_dispatch,
<br>or something. the simple @dispatch would use a dictionary,<br>while the stateful version would use a loop.<br><br><br>-tomer<br><br>---------- Forwarded message ----------<br><span class="gmail_quote">From: <b class="gmail_sendername">
tomer filiba</b> <<a href="mailto:tomerfiliba@gmail.com">tomerfiliba@gmail.com</a>><br>Date: Jan 14, 2007 2:28 PM<br>Subject: multi-dispatch again<br>To: <a href="mailto:Python-3000@python.org">Python-3000@python.org
</a><br><br></span>i just thought of a so-to-speak counter-example for ABCs... it's not really<br>a counter-example, but i believe it shows a deficiency in the concept.<br><br>theoretically speaking, objects are a made of type and state. ABCs, isinstance() 
<br>and interfaces at general only check the type part. for example:<br><br>@dispatch<br>def log_to_file(text: str, device: file):<br>    file.write(text)<br><br>this will constrain the *type* of the device, but not its *state*.
<br>practically speaking, i can pass a closed file, or a file open for reading-only,<br>and it would pass silently.<br><br>basing multi-dispatch on types is of course a leap forward, but if we<br>already plan to take this leap, why not make it general enough to support
<br>more complex use-cases?<br><br>this way we could rewrite the snippet above as<br><br>@dispatch<br>
def log_to_file(text: str, device: open_file):<br>
    file.write(text)<br>
<br>where open_file isn't a type, but rather a "checker" that may also examine the<br>state. by default, type objects would check for inheritance (via a special method), <br>but checkers could extend this behavior.
<br><br>for efficiency purposes, we can have two decorators: <br>@type_dispatch - dispatches based on type only<br>@full_dispatch - dispatches based on type and state<br><br>bottom line -- we can't just look at the type of the object for dispatching, 
<br>overlooking its state. the state is meaningful, and we'd want the function<br>not to be called at all if the state of the object is wrong.<br><span class="sg"><br><br>-tomer

</span>