On Jan 26, 2008 11:14 PM, Raymond Hettinger <[EMAIL PROTECTED]> wrote: > >. You may disagree, but that doesn't make it nuts. > > Too many thoughts compressed into one adjective ;-) [snip]
> > I don't think that Excel should be held up as a shining example for > > Python. > > It is simply a datapoint. [snip] You're beginning to repeat your argument; none of that was new. > One other thought: In Python, it has been nice that we have simple type > coercions using the type name: > * set(p)-->q can accept a list, tuple, string, or any iterable and make a > set > * int(p)-->q can accept an int, long, float, or string and make an int > * float(p)-->q can accept an int, long, float, or string and make an int > * list(p)-->q can accept a list, tuple, string, or any iterable and make a > list > * unicode(p)--> can accept a str, buffer, or unicode object and make a > unicode object > It's a bit weird to decide that int() needs to lose that capability so we get > generalized Integrals as output. What's wrong with > coercion to a concrete type? Let me get back to you on that. I first want to point out that you snipped the core of my argument in the post you otherwise quoted. I will repeat it here because I would like your explicit reaction: [Guido] > There is actually quite an important signal to the reader that is > present when you see trunc(x) but absent when you see int(x): with > trunc(x), the implication is that x is a (Real) number. With int(x), > you can make no such assumption -- x could be a string, or it could be > a totally different type that happens to define __int__, perhaps a > custom date/time type (I believe mxDateTime supports this). Can I assume that you agree with this? That would be progress. Coming back to your argument that other types have a constructor that takes all kinds of arguments, I'd like to point out that they all have restrictions too (except for str()): list() and tuple() only accept iterables, float() only accepts strings and certain numbers (not complex), and so on. Taking the latter as an example: >>> float(0j) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't convert complex to float; use abs(z) >>> I think that (eventually) int(0.0) could do something similar: >>> int(0.0) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't convert float to int; use round(x) or trunc(x) >>> But see below. Yet another (minor) argument that has always made me uncomfortable with int() == trunc(): the % operator. I think it's a big improvement over C that Python's % operator is defined as x%y == x - y*floor(x/y) # where / is real division rather than C's division, which uses trunc() instead of floor(). In C this nicely meshes with the definition of int(): you can define x%y as x - y*(int)(x/y); but not so in Python. I don't want to use this as an argument for defining int(x) as floor(x), but I do want to point out that it has always given me a twinge of discomfort. FInally, there's the "one way" argument. That's a nice slogan, but doesn't really hold anyways in practice. To copy a list, we can write either L[:] or list(L). To get the keys of a dict, we can write either D.keys() or list(D). To convert a number to a string we can write either "%g" % X or str(X). For octal we can write "%#o" % X or oct(X). To convert a unicode string to UTF-8, we can write either U.encode("utf8") or str(U, "utf8"). And so on. In many cases, these notations aren't exactly the same in semantics (e.g. list(X) always returns a list, X[:] returns whatever sequence type X is), but nevertheless they have large areas of overlap. This is how I see trunc() and int() live together. After all that, here's my current proposal: - Deprecating int(<float>) is pretty radical, I think it would have to happen in the distant future. OR not at all. I'm at best +0 on this, more like exactly 0. I realize that in practice this kills the idea. The "purist" argument for it would have worked better if it was made 18 years ago. - trunc(), round(), floor() and ceil() should all be built-ins, corresponding to __trunc__, __round__, __floor__ and __ceil__. Then we have the four standard ways to go from Reals to Integers, which are properly extensible for folks who write their own number types. (We can't control how folks implement __round__, but we can document expected behavior -- that's how we treat __add__ and all other operators too, after all.) - In the docs (especially for beginners) we recommend that users write trunc() instead of int(), emphasizing that trunc() ensures the argument is a number, while suggesting int(x) for conversion from strings. But the implementation won't chastise users by issuing annoying warnings. -- --Guido van Rossum (home page: http://www.python.org/~guido/) _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com