On Thu, Jul 29, 2010 at 11:11 PM, Antoine Pitrou email@example.com wrote:
On Thu, 29 Jul 2010 22:51:11 +1000 Nick Coghlan firstname.lastname@example.org wrote:
Each individual time this question comes up people tend to react with "oh, that's too complicated and overkill, but magic methods are simple, so let's just define another magic method". The sum total of all those magic methods starts to accumulate into a lot of complexity of its own though :P
I don't agree. __json__ only matters to people who do JSON encoding/decoding. Other people can safely ignore it.
Which is exactly the attitude I was talking about: for each individual case, people go "oh, I understand magic methods, those are easy". It's the overall process of identifying the need for and gathering consensus on magic methods that is unwieldy (and ultimately fails to scale, leading to non-extensible interfaces by default, with pretty printing being the classic example, and JSON serialisation the latest).
And I don't see how generic functions bring less cognitive overhead. (they actually bring more of it, since most implementations are more complicated to begin with)
Mostly because the fully fledged generic implementations like PEAK-rules tend to get brought into discussions when they aren't needed. Single-type generic dispatch is actually so common they gave it a name: object-oriented programming. All single-type generic dispatch is about is having a registry for a particular operation that says "to perform this operation, with objects of this type, use this function". Instead of having a protocol that says "look up this magic method in the object's own namespace" (which requires a) agreement on the magic name to use and b) that the original author of the type in question both knew and cared about the operation the application developer is interested in) you instead have a protocol that says "here is a standard mechanism for declaring a type registry for a function, so you only have to learn how to register a function once".
Is it really harder for people to learn how to write things like:
json.dumps.overload(mytype, mytype.to_json) json.dumps.overload(third_party_type, my_third_party_type_serialiser)
than it is for them to figure out that implementing a __json__ method will allow them to change how their object is serialised? (Not to mention that a __json__ method can only be used via monkey-patching if the type you want to serialise differently came from a library module rather than your own code).
The generic function registration approach is incidentally discoverable via dir(json.dumps) to see that a function provides the relevant generic function registration methods. Magic method protocols can *only* be discovered by reading documentation.
Function registration is a solved problem, with much better solutions than the ad hoc YAMM (yet-another-magic-method) approach we currently use. We just keep getting scared away from the right answer by the crazily complex overloading schemes that libraries like PEAK-rules allow.