> Which case are you considering? In case 1, __hash__ of the parent object > is not idempotent because it depends on whether __hash__ of the child > object has a cached value or not.
I don't see why you should say that; it's certainly not my intent. What did I say that makes you think that that dependency exists? > In case 2, __hash__ either returns > a value or raises an exception (or perhaps blocks forever if poorly > written) depending on the behavior of the human being. Neither is > idempotent. Perhaps we are using "idempotent" to mean different things. I think of a function f as being idempotent if f(x) == x for all x in dom(f). If __hash__ fails to return a value, you've made a mistake by calling it on an object outside its domain. But if it does return a value, I intend for it always to return that same value on subsequent calls. > Hash values should only be cached if they will never change. Agreed. > Furthermore, hash values are formally required to be consistant > (not change). The "value" of the component may never change but| > it's __hash__ may. I should certainly hope not. > Consider the following series of calls: > x1 = hash(x) > y1 = hash(y) > x2 = hash(x) > y2 = hash(y) > After this series of calls, x1 != x2 and y1 != y2. That breaks the > contract for __hash__ which I would call perverse. If you think my examples make that possible, then I've stated them poorly, and would appreciate knowing where the error lies. That was not my intent. > I don't doubt that some properties like the behavior of __call__ or > __iter__ may trigger side effects, and it would nice to be able to test > for the property without triggering the side effects. Your argument is > bolstered if you add __hash__ to the list because hashability is something > that *must* be tested for (by dict at least!). But I object... __hash__ > cannot trigger side effects (well, it must be idempotent anyhow) thus you > are limited to __call__ and __iter__ as examples, of which the best we > can say is that it would *nice* to be able to test for them. I don't know why you think that __call__ and __iter__ are the only similar properties that any object might ever have. > This is all moot anyway, because I think everyone agrees to make > hasattr(x, '__call__') and hasattr(x, '__iter__') be the tests and to > ensure in Python3000 that (unlike older CPythons) those work for all > objects. It's OK with me, but I still think it strikes me as strange, because it makes a commitment about the implementation that I think would be better concealed behind an abstraction layer. I freely admit that I'm not as steeped in Python culture as many on this list--which may or may not be a good thing as far as this discussion goes. I guess I've just seen enough cases where people have exposed implementations and then regretted it later that little alarm bells go off in my head when I see designs such as these. Sometimes, of course, they are false alarms. _______________________________________________ Python-3000 mailing list Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com