[Python-Dev] trunc() (original) (raw)
Guido van Rossum guido at python.org
Sun Jan 27 17:43:14 CET 2008
- Previous message: [Python-Dev] trunc()
- Next message: [Python-Dev] trunc()
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Jan 26, 2008 11:14 PM, Raymond Hettinger <python at rcn.com> 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 "", line 1, in 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 "", line 1, in 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() 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/)
- Previous message: [Python-Dev] trunc()
- Next message: [Python-Dev] trunc()
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]