Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

proposed language change to int/int==float (was: PEP0238 lament)

233 views
Skip to first unread message

Skip Montanaro

unread,
Jul 23, 2001, 10:46:20 AM7/23/01
to Tim Peters, pytho...@python.org

(I changed the subject to make sure that people reading c.l.py are aware of
the ramifications of PEP 238 in case they haven't read it or this thread.)

>> but float is just ugly. It is turning exact values (integers) into
>> approximate ones (float) when I didn't tell it to.

Tim> If the language defines "/" as returning a float, then you told it
Tim> to.

The problem is all those places in my existing code I already told it to
divide two integers and return another integer. It's like George Bush
changing personal translators and starting to get subtly different meanings
from the statements Vladimir Putin makes. At first blush they may seem the
same, but every once in awhile the message comes out wrong.

I really don't understand the problem with teaching people new to Python
right from the get-go that when you divide two ints it works like grade
school long division. Unless my kids' educations were aberrant in some way
(they weren't raised on Mars), I think long division is still taught to
everyone in school somewhere along the way. It's not like it's a concept
completely foreign to people. After years of bit rot in their brains due to
calculator crutches they may need a minute to refresh, that should be all.

If Python had int/int==float from day one, nobody would be bitching about
it. It's just that there's all this code out there that already assumes
int/int==int that will have to be picked over if people are to upgrade to a
Python that says int/int==float. Probably nobody new to the language will
bitch about it, because they haven't got a lot of code to maintain that
makes the int/int==int assumption. To those of us who have to go back and
fiddle all our code, the proposed change seems very much like gratuitous
breakage. It's a bird-in-the-hand sort of thing. You're pissing off a
fairly significant fraction of the language's existing constituency in hopes
of attracting some non-programmers to the language who may not come anyway
for various other reasons.

Moshe, please make sure that when you update PEP 238 it includes this
problem and that it seems to be shared by many opponents to this change.

Skip

Steve Horne

unread,
Jul 23, 2001, 2:15:34 PM7/23/01
to
On Mon, 23 Jul 2001 09:46:20 -0500, Skip Montanaro <sk...@pobox.com>
wrote:

>completely foreign to people. After years of bit rot in their brains due to
>calculator crutches they may need a minute to refresh, that should be all.

My calculator supports integers - and not with a second integer
button, I just set the mode and it all works happy. I think it has
separate modulo and remainder functions as well - but the battery died
five years ago and I don't really remember.

At school, I once took a calculators test despite having forgot my
calculator that day. I finished in half the time anyone else did, and
was the only person to get a perfect result.

Intellectual decline is not what it used to be ;-) - apparently the
avarage childs IQ these days (I forget the exact age range) is around
120. Must it's all the TV and video games ;-)

--
Steve Horne
Home : st...@lurking.demon.co.uk
Work : s...@ttsoftware.co.uk

Grant Edwards

unread,
Jul 23, 2001, 2:53:28 PM7/23/01
to
In article <tclolt053o18f8q0n...@4ax.com>, Steve Horne wrote:

>On Mon, 23 Jul 2001 09:46:20 -0500, Skip Montanaro
><sk...@pobox.com> wrote:
>
>>completely foreign to people. After years of bit rot in their
>>brains due to calculator crutches they may need a minute to
>>refresh, that should be all.
>
>My calculator supports integers - and not with a second integer
>button, I just set the mode and it all works happy.

And I'll bet cash money that the "integer divide" key and the
"float divide" key are one-in-the-same button. The operation
is determined by the type of the operands (the "mode").

What I don't understand is why polymorphism is all of a sudden
an evil, nasty thing in the Python world -- something that must
be banished at all costs (even if we have to change one of the
basic mathematical operators and break existing programs).

Are the rulers of the Python Kingdom going to ban all
polymorphism? I thought it was one of the _stregnths_ of
Python, and here we are trying to stamp it out!

--
Grant Edwards grante Yow! LBJ, LBJ, how many
at JOKES did you tell today??!
visi.com

Stephen Horne

unread,
Jul 23, 2001, 4:47:47 PM7/23/01
to
On Mon, 23 Jul 2001 18:53:28 GMT, gra...@visi.com (Grant Edwards)
wrote:

>In article <tclolt053o18f8q0n...@4ax.com>, Steve Horne wrote:
>
>>On Mon, 23 Jul 2001 09:46:20 -0500, Skip Montanaro
>><sk...@pobox.com> wrote:
>>
>>>completely foreign to people. After years of bit rot in their
>>>brains due to calculator crutches they may need a minute to
>>>refresh, that should be all.
>>
>>My calculator supports integers - and not with a second integer
>>button, I just set the mode and it all works happy.
>
>And I'll bet cash money that the "integer divide" key and the
>"float divide" key are one-in-the-same button. The operation
>is determined by the type of the operands (the "mode").

Oops - I meant "and not with a second divide button".

Been getting pissed off today, and my typing suffers under those
conditions.

Gareth McCaughan

unread,
Jul 23, 2001, 4:36:21 PM7/23/01
to
Grant Edwards wrote:

> What I don't understand is why polymorphism is all of a sudden
> an evil, nasty thing in the Python world -- something that must
> be banished at all costs (even if we have to change one of the
> basic mathematical operators and break existing programs).
>
> Are the rulers of the Python Kingdom going to ban all

> polymorphism? I thought it was one of the _strengths_ of


> Python, and here we are trying to stamp it out!

The different behaviour of "/" on floats and ints isn't
polymorphism, it's overloading. Two different operations.
Closely related, of course, but different. Generally
"polymorphism" is reserved for when what's being done
is "the same thing" in both cases.

Python doesn't generally object much to overloading either,
of course (def __div__(self, x): ...); and I find the
proposed change scary (what I wish is that Python had
made 1/2 give a rational from day 1, but it's too late
for that to happen unless Guido gets the time machine out
again). So I'm just quibbling.

--
Gareth McCaughan Gareth.M...@pobox.com
.sig under construc

Stephen Horne

unread,
Jul 23, 2001, 6:23:31 PM7/23/01
to
On Mon, 23 Jul 2001 21:36:21 +0100, Gareth.M...@pobox.com (Gareth
McCaughan) wrote:

>Grant Edwards wrote:
>
>> What I don't understand is why polymorphism is all of a sudden
>> an evil, nasty thing in the Python world -- something that must
>> be banished at all costs (even if we have to change one of the
>> basic mathematical operators and break existing programs).
>>
>> Are the rulers of the Python Kingdom going to ban all
>> polymorphism? I thought it was one of the _strengths_ of
>> Python, and here we are trying to stamp it out!
>
>The different behaviour of "/" on floats and ints isn't
>polymorphism, it's overloading. Two different operations.
>Closely related, of course, but different. Generally
>"polymorphism" is reserved for when what's being done
>is "the same thing" in both cases.

It *is* the same thing in both cases - float division is nothing more
than a logical extension of integer division. Even mathematicians know
that ;-)

Tim Peters

unread,
Jul 23, 2001, 10:51:03 PM7/23/01
to pytho...@python.org
[Skip Montanaro]
> ...

> I really don't understand the problem with teaching people new to
> Python right from the get-go that when you divide two ints it works
> like grade school long division.

I'm burned out on the repetition here. It's not a question of being hard to
teach. It's largely that it's never sensible for

x = y / z

buried in the middle of some routine to do truncating division if y and z
happen to be ints but best-possible division if they happen not to be ints.
It's this damage to polymorphism that hurts people in real life, and we've
had years of testimony about that on c.l.py (even in this incarnation of the
debate, although it's hard to find unless you read every msg).

This isn't a question of teaching the rules, it's that the specific rule
here is essentially braindead in a language without static type
declarations. If you read nothing else, read Guido's few messages on the
topic. He covers it all succinctly and accurately (and generally declines
to get sucked into endless repetition -- but why a point needs to be made
500 times on Usenet is beyond me).

> ...


> You're pissing off a fairly significant fraction of the language's
> existing constituency in hopes of attracting some non-programmers
> to the language who may not come anyway for various other reasons.

I don't detect any trace of that hypothesized motive in Guido. He wants to
repair what he has come to believe is a serious design error, and is
wrestling with ways to get that done. What a remarkably different world it
would be if people tried to help <wink>.


Chris Gonnerman

unread,
Jul 24, 2001, 12:48:33 AM7/24/01
to Tim Peters, pytho...@python.org
----- Original Message -----
From: "Tim Peters" <tim...@home.com>


> It's largely that it's never sensible for
>
> x = y / z
>
> buried in the middle of some routine to do truncating division if y and z
> happen to be ints but best-possible division if they happen not to be
ints.

I can grant that.

<hack hack hack>

> I don't detect any trace of that hypothesized motive in Guido. He wants
to
> repair what he has come to believe is a serious design error, and is
> wrestling with ways to get that done. What a remarkably different world
it
> would be if people tried to help <wink>.

Some of us have tried. Besides my alternative, I have seen two others which
allow case-by-case preservation of the old semantics where they may have
been
intended.

I have seen very few comments on them though (except from Stephen Horne).

ASSERTIONS:
1. Best-effort handling of division is desirable.
2. An explicit operator for truncating division is desirable
(as in, explicit is better than implicit).
3. Code breakage is bad, and difficult-to-detect code breakage
is worse.
4. Difficulty in writing backwards-compatible code is bad (thus,
code to implement partitioning of a dataset would naturally use
the // operator in 2.2+ but would not be able to in pre-2.2,
so the div() function would have to be religiously used, hurting
readability).

Assertion 1 and 2 conflict with 3 and 4; #4 in particular bothers me. Many
have said that #3 is irrelevant as we have from 2.2 to 2.4 to fix it, but
I have upgraded several systems directly from 1.5.2 to 2.1 without
substantial
problems; going direct to 2.4 from 2.1 would not be so painless.

SOME way is needed to specify, in module scope, which set of mathematics
rules
should be enforced. Whatever method is used should (IMHO) be uniform from
2.2
to 2.4; my method, as given, is the only one where the code reads the same
from
2.2 on:

from __numerics__ import original # or standard, etc...

Just thinking about the implementation gives me headaches, but Guido and Co.
have readily implemented fancy things like the software-time-machine

from __future__ import phasers, warp_drive # or whatever

and so my proposal (or a mutation thereof) should be no biggie.

As I said, you can't honestly say we ALL haven't been trying. It's not that
I
object directly to the change, it's the overall plan/effect/semantics etc.
that
I don't like.

Stephen seems not to want to have to admit to his boss that Python has
changed
the basic rules for division of integers. I can grasp this... a proposal
like
mine, which allows for other numeric types to be dynamically added to the
language, would be an easier sell:

Boss: I heard Python was changing the rules for division of integers.
Are you sure we should be using such a stupid language?
SH: No, boss, you've got it all wrong. We have a new method for adding
numeric types, like rationals, fixedpoint, decimals, etcetera, and
is just happens that the default division mode changed as a
consequence. I can easily add a single line of code to any old
module
and Python will run it under the old rule. No fault, no foul.
Boss: Oh. Well, carry on.

Skip Montanaro

unread,
Jul 24, 2001, 12:45:05 AM7/24/01
to Tim Peters, pytho...@python.org

>> You're pissing off a fairly significant fraction of the language's
>> existing constituency in hopes of attracting some non-programmers to
>> the language who may not come anyway for various other reasons.

Tim> I don't detect any trace of that hypothesized motive in Guido. He
Tim> wants to repair what he has come to believe is a serious design
Tim> error, and is wrestling with ways to get that done. What a
Tim> remarkably different world it would be if people tried to help
Tim> <wink>.

And I did send a summary to Moshe of the objections to the current proposal
as I saw them, just not on the list where they'd get buried in the slew of
messages on the subject.

I think a lot of people feel that unlike most changes considered for Python,
scant attention is being paid to whether or not the proposed change will
break existing code. There's ample anecdotal evidence to suggest that this
will break a lot of code and require a fair amount of effort just to check
code that is probably correct.

Skip


Stephen Horne

unread,
Jul 24, 2001, 3:42:26 AM7/24/01
to
On Mon, 23 Jul 2001 23:48:33 -0500, "Chris Gonnerman"
<chris.g...@newcenturycomputers.net> wrote:

>Stephen seems not to want to have to admit to his boss that Python has
>changed
>the basic rules for division of integers. I can grasp this... a proposal
>like
>mine, which allows for other numeric types to be dynamically added to the
>language, would be an easier sell:
>
> Boss: I heard Python was changing the rules for division of integers.
> Are you sure we should be using such a stupid language?
> SH: No, boss, you've got it all wrong. We have a new method for adding
> numeric types, like rationals, fixedpoint, decimals, etcetera, and
> is just happens that the default division mode changed as a
> consequence. I can easily add a single line of code to any old
>module
> and Python will run it under the old rule. No fault, no foul.
> Boss: Oh. Well, carry on.

And *this* storyline would leave me 98% of the way to seeing the
change as no different to the (IMO) less scary case insensitivity
change - I've already expressed my reservations on the religious
aspects ad nauseum, but in the practical sense this would leave only
one minor problem.

The minor problem is finding the code - the only way I can trace all
these programs written over the last three years which have been
passed from person to person, and which have been modified by others
or which I just plain forgot I wrote etc is by sending out an email to
the whole company. If the change is as simple as above, I can find a
way to do this that saves face - there is no chance of an avalanche of
bugs, only that some people won't want to do the change themselves
giving me an excuse for an occasional half hours wandering about,
getting coffee, doing a no-brainer task and having a chat ;-)

Still not happy with the principle, and I still forsee problems for
people who's code is no longer neatly located in their actual company
, but in the case of my personal pratical issues - well, my blood
pressures down a bit anyway ;-)

Paul Boddie

unread,
Jul 24, 2001, 5:09:37 AM7/24/01
to
"Tim Peters" <tim...@home.com> wrote in message news:<mailman.995943227...@python.org>...

>
> I'm burned out on the repetition here. It's not a question of being hard to
> teach. It's largely that it's never sensible for
>
> x = y / z
>
> buried in the middle of some routine to do truncating division if y and z
> happen to be ints but best-possible division if they happen not to be ints.

Indeed. But given that many people know what / is going to do, and
have managed to reassure themselves that y and z are going to be
integers at the relevant parts of their own code, do you think it's
fair to make their code give an "unexpected" result (for them) just
because one could get an "unexpected" result in the general case?

> It's this damage to polymorphism that hurts people in real life, and we've
> had years of testimony about that on c.l.py (even in this incarnation of the
> debate, although it's hard to find unless you read every msg).

I agree with what you say about the dangers of the / operator, and it
is important to at least try to remove the ambiguity (indeed, why not
start raising exceptions), but I don't see why this has to be done by
breaking untold amounts of code that came before just because a group
of people want to reclaim the / operator as their instrument for the
"one true kind of division".

If someone had suggested using // for the int/int->float operation, I
bet that hardly anyone would have complained, apart from some people
who might consider it "language bloat". But instead, it seems that for
the sake of some aesthetic principle the rug is being pulled out from
under everyone whether they want to lie down or not.

Paul

Christopher A. Craig

unread,
Jul 24, 2001, 8:35:51 AM7/24/01
to pytho...@python.org
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

"Tim Peters" <tim...@home.com> writes:

> I'm burned out on the repetition here. It's not a question of being hard to
> teach. It's largely that it's never sensible for
>
> x = y / z
>
> buried in the middle of some routine to do truncating division if y
> and z happen to be ints but best-possible division if they happen

> not to be ints. It's this damage to polymorphism that hurts people


> in real life, and we've had years of testimony about that on c.l.py
> (even in this incarnation of the debate, although it's hard to find
> unless you read every msg).

I haven't spoken out on this yet, but now I'm going to. I don't like
PEP238, but I am not going to repeat what everyone else has said.

What I don't like about it is that in every case I can think of right
now if you apply an operator to two operands of the same type, you get
a result of the same type. <int>/<int> = <float> would change this,
and I don't like it. (yes, you can argue that math.something(<int>)
returns a float, but that's a library module, not a builtin, so I
don't count it.)

Many people have argued that they would like to see the behavior from
the PEP if Python were a new language. I disagree. I would prefer to
see '/' defined as "exact division" and '//' defined as "truncated
division" and have types that don't support either raise a TypeError
if the types don't support the operation in question. I think this
parallels existing operations better.

As examples:

<list>*<list> raises a TypeError
<int>**<negative int> raises a ValueError
<rational>**<rational> would presumably raise a TypeError


- --
Christopher A. Craig <com-n...@ccraig.org>
"Software hoarding is not a victimless crime." Richard Stallman
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: Processed by Mailcrypt

iEYEARECAAYFAjtda6cACgkQjVztv3T8pztiwACg2bnc0YssqlmsHx0B6zrcE/Bx
RtkAoI0pA4Q3O5ogY3NErL1Y77PtaBMO
=mfMO
-----END PGP SIGNATURE-----

Greg Landrum

unread,
Jul 24, 2001, 9:49:34 AM7/24/01
to

"Tim Peters" <tim...@home.com> wrote in message
news:mailman.995943227...@python.org...
>
> I'm burned out on the repetition here. It's not a question of being hard
to
> teach. It's largely that it's never sensible for
>
> x = y / z
>
> buried in the middle of some routine to do truncating division if y and z
> happen to be ints but best-possible division if they happen not to be
ints.
[snip]

> This isn't a question of teaching the rules, it's that the specific rule
> here is essentially braindead in a language without static type
> declarations.

When I read these arguments and think about them, I'm unsurprised to find
myself agreeing with Tim and Guido here -- I usually end up agreeing with
those guys. It *is* odd to have to do something like:
x = float(y)/z
to get best-possible division in Python. It would be *nice* to never have
to explain integer division behavior again (well, not quite, it'll have to
be explained to programmers who are used to the old way of doing things).

And then I start thinking about all the code I've written for myself, my
former employer and my consulting clients. I *know* I've used '/' to do
integer (truncating) division in that code intentionally. Of course I have,
it's the way things were done. Once PEP 238 is implemented and the change
in place (v2.3?), a lot of that code is going to start producing warnings.
The warnings can be used to track down the problems before code actually
breaks and there will be 2 years in which to do so... that's acceptable.

I do have a question. The PEP says:

If "from __future__ import non_integer_division" is present in the
module, until the IntType nb_divide is changed, the "/" operator
is compiled to FUTURE_DIV.

This is not yet implemented in the Python 2.2 release.

Okay, it's "not yet" implemented for 2.2. It's going to be though, right?
If the change is going to happen, it is going to break some of my code and I
would like to start tracking down these problems and changing my programming
habits ASAP.

[I started this message intending to make a very different argument because
of the code breakage. Then I re-read the PEP and realized that we are being
promised at least 2 years to fix things before code breaks. I'm much more
comfortable with the PEP now.]

-greg

Klaus-G. Meyer

unread,
Jul 24, 2001, 10:20:44 AM7/24/01
to
> those guys. It *is* odd to have to do something like:
> x = float(y)/z
> to get best-possible division in Python.

But what is with the "best possible" multiplication?

99999*99999 -> integer overflow

Why not an long integer result? (or maybe float)

You must explicit type:
99999*99999L or 99999*99999.

Is that not the same thing as type 1./3 ???

Klaus


Marcin 'Qrczak' Kowalczyk

unread,
Jul 24, 2001, 10:32:06 AM7/24/01
to
Tue, 24 Jul 2001 16:20:44 +0200, Klaus-G. Meyer <klaus-ge...@de.bosch.com> pisze:

> But what is with the "best possible" multiplication?
>
> 99999*99999 -> integer overflow

That's why I want int and long unified.

--
__("< Marcin Kowalczyk * qrc...@knm.org.pl http://qrczak.ids.net.pl/
\__/
^^ SYGNATURA ZASTĘPCZA
QRCZAK

Steve Horne

unread,
Jul 24, 2001, 11:19:49 AM7/24/01
to
I hate countering arguments from someone who supports my opinion,
but...

On 24 Jul 2001 08:35:51 -0400, com-n...@ccraig.org (Christopher A.
Craig) wrote:

>As examples:
>
><list>*<list> raises a TypeError

Given that other arithmetic operations have been hijacked for other
jobs (concat etc) with lists, there *is* no sensible meaning for this.
In another universe, interpreting lists as vectors might have been
handy I suppose - but not really an everyday case I'd have thought.


><int>**<negative int> raises a ValueError

I believe Guido is already changing this.


><rational>**<rational> would presumably raise a TypeError

Or give a symbolic result ;-)

Just van Rossum

unread,
Jul 24, 2001, 11:55:37 AM7/24/01
to
Marcin 'Qrczak' Kowalczyk wrote:
>
> Tue, 24 Jul 2001 16:20:44 +0200, Klaus-G. Meyer <klaus-ge...@de.bosch.com> pisze:
>
> > But what is with the "best possible" multiplication?
> >
> > 99999*99999 -> integer overflow
>
> That's why I want int and long unified.

And that's in fact being discussed as well.

Just

Bjorn Pettersen

unread,
Jul 24, 2001, 11:44:57 AM7/24/01
to Klaus-G. Meyer, pytho...@python.org
> From: Klaus-G. Meyer [mailto:klaus-ge...@de.bosch.com]

>
> > those guys. It *is* odd to have to do something like:
> > x = float(y)/z
> > to get best-possible division in Python.
>
> But what is with the "best possible" multiplication?
>
> 99999*99999 -> integer overflow
>
> Why not an long integer result? (or maybe float)
>
> You must explicit type:
> 99999*99999L or 99999*99999.
>
> Is that not the same thing as type 1./3 ???

I think perhaps an equally interesting example is something like:

2L**128/2

which currently gives an exact result, but under the proposed new
semantics would give an approximation...

This is only one of the reasons why I think it's a mistake to look at
integer division by itself. If we're going to change basic behaviors it
would be better if we had a consistent semantic model first.

-- bjorn

Marcin 'Qrczak' Kowalczyk

unread,
Jul 24, 2001, 1:50:46 PM7/24/01
to
Tue, 24 Jul 2001 09:44:57 -0600, Bjorn Pettersen <BPett...@NAREX.com> pisze:

> I think perhaps an equally interesting example is something like:
>
> 2L**128/2
>
> which currently gives an exact result, but under the proposed new
> semantics would give an approximation...

That's why I propose rationals.

> If we're going to change basic behaviors it would be better if we
> had a consistent semantic model first.

In my model there are four builtin numeric types: int, rational,
float, and complex. The intent is that floats approximate real numbers.

There are explicit conversions from any to any among int, rational and
float. Conversion of rational and float to int truncates as currently.

+, -, * work for arguments of any two types from these and return
the result in the broader type wrt. the order above.

div, mod, divmod similarly, except that complex arguments are
disallowed.

/ similarly, except that ints are changed to rationals first.

sqrt, sin, cos, exp etc. similarly, except that ints and rationals
are changed to float first.

The behavior of ** depends on the exponent which determines the
narrowest type to which base is converted first. If it's a nonnegative
int, the result has the same type as the base. If it's a negative
int, the base is converted from int to rational. If it's a rational
or float, the base is converted from int or rational to float. If
it's a complex, the base is converted to complex.

Michael Abbott

unread,
Jul 24, 2001, 1:55:14 PM7/24/01
to
Marcin 'Qrczak' Kowalczyk <qrc...@knm.org.pl> wrote in
news:slrn.pl.9lrd...@qrnik.zagroda:

> Tue, 24 Jul 2001 09:44:57 -0600, Bjorn Pettersen <BPett...@NAREX.com>
> pisze:
>
>> I think perhaps an equally interesting example is something like:
>>
>> 2L**128/2
>>
>> which currently gives an exact result, but under the proposed new
>> semantics would give an approximation...
>
> That's why I propose rationals.
>
>> If we're going to change basic behaviors it would be better if we had
>> a consistent semantic model first.
>
> In my model there are four builtin numeric types: int, rational,
> float, and complex. The intent is that floats approximate real numbers.

Unfortunately, this isn't really all that consistent. Consider the
calculation

sqrt(2)**2 == 2

By pretty much the same arguments as have been used elsewhere in this
discussion, I'm sure that you would expect this to evaluate to true.

Hmm. Think about it.

Skip Montanaro

unread,
Jul 24, 2001, 1:08:30 PM7/24/01
to Klaus-G. Meyer, pytho...@python.org

Klaus> But what is with the "best possible" multiplication?

Klaus> 99999*99999 -> integer overflow

Klaus> Why not an long integer result? (or maybe float)

Read (and comment, if you like) on PEP 237, which proposes to unify Python's
ints and longs:

http://python.sourceforge.net/peps/pep-0237.html

I believe this PEP is still in need of a patch to the CVS repository to
support it as well.

--
Skip Montanaro (sk...@pobox.com)
http://www.mojam.com/
http://www.musi-cal.com/

Terry Reedy

unread,
Jul 24, 2001, 2:01:27 PM7/24/01
to

"Steve Horne" <s...@ttsoftware.co.uk> wrote in message
news:su3rltc8d88jrjdv9...@4ax.com...

> > <list>*<list> raises a TypeError
>
> Given that other arithmetic operations have been hijacked for other
> jobs (concat etc) with lists, there *is* no sensible meaning for
this.

Actually there *is*: cross concatenation, (somewhat similar to set
cross products)

L1*L2 := [i1+i2 for i1 in Li for i2 in L2]

This is very handy for succinctly expressing many list-producing
functions and their corresponding algorithms. Example: combinations,
n things, k at a time
C(n,0) = ()
C(n,k>0) = [(n,)]*C(n-1,k-1) + C(n-1,k)

I have thought of submitting a PEP, after working out more details,
proposing this as a sequence operation that would make Python even
more like executable pseudocode.

Terry J. Reedy

Marcin 'Qrczak' Kowalczyk

unread,
Jul 24, 2001, 2:15:53 PM7/24/01
to
Tue, 24 Jul 2001 17:55:14 GMT, Michael Abbott <michael....@ntlworld.com> pisze:

> sqrt(2)**2 == 2
>
> By pretty much the same arguments as have been used elsewhere in this
> discussion, I'm sure that you would expect this to evaluate to true.

Why?

Skip Montanaro

unread,
Jul 24, 2001, 2:15:05 PM7/24/01
to Marcin 'Qrczak' Kowalczyk, pytho...@python.org

Marcin> The behavior of ** depends on the exponent which determines the
Marcin> narrowest type to which base is converted first.... If it's a
Marcin> rational or float, the base is converted from int or rational to
Marcin> float.

Hmm... PEP 240 proposes that numbers matching the regular expression
'\d*.\d*' be interpreted as rationals. Thus "0.5" would be interpreted as
the rational "5/10" (or perhaps reduced to "1/2"). Using this definition of
rational literal and your coercion semantics, "4**0.5" would yield a float
instead of an integer or rational. Why shouldn't an integer or rational
base be converted to a rational if the exponent is a rational?

Christopher A. Craig

unread,
Jul 24, 2001, 2:35:12 PM7/24/01
to pytho...@python.org
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Skip Montanaro <sk...@pobox.com> writes:

> Hmm... PEP 240 proposes that numbers matching the regular expression
> '\d*.\d*' be interpreted as rationals. Thus "0.5" would be interpreted as
> the rational "5/10" (or perhaps reduced to "1/2"). Using this definition of
> rational literal and your coercion semantics, "4**0.5" would yield a float
> instead of an integer or rational. Why shouldn't an integer or rational
> base be converted to a rational if the exponent is a rational?

Because 5**0.5 cannot be expressed as a rational.

- --
Christopher A. Craig <com-n...@ccraig.org>

When you say "I wrote a program that crashed Windows", people just stare at
you blankly and say "Hey, I got those with the system, *for free*". - Linus


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: Processed by Mailcrypt

iEYEARECAAYFAjtdv+AACgkQjVztv3T8pztNbwCgtgNlOwyvT3YUQj1xo/Wxbvtd
PP4An3JzQGhNWRlsk0SWOTKSXRDNdM2w
=2qB9
-----END PGP SIGNATURE-----

Terry Reedy

unread,
Jul 24, 2001, 3:18:06 PM7/24/01
to

> > In my model there are four builtin numeric types: int, rational,
> > float, and complex. The intent is that floats approximate real
numbers.

Note: *approximate*

> Unfortunately, this isn't really all that consistent. Consider the
> calculation
>
> sqrt(2)**2 == 2
>
> By pretty much the same arguments as have been used elsewhere in
this
> discussion, I'm sure that you would expect this to evaluate to true.

No, approximate is not equal. For float 'equality', one should always
test near equality.

abs(sqrt(2)**2 - 2) <= delta

and yes, choosing delta is sometimes an art.


Gareth McCaughan

unread,
Jul 24, 2001, 8:05:34 PM7/24/01
to
Stephen Horne wrote:

[I said:]


>> The different behaviour of "/" on floats and ints isn't
>> polymorphism, it's overloading. Two different operations.
>> Closely related, of course, but different. Generally
>> "polymorphism" is reserved for when what's being done
>> is "the same thing" in both cases.
>
> It *is* the same thing in both cases - float division is nothing more
> than a logical extension of integer division. Even mathematicians know
> that ;-)

I am a mathematician, and I do not know, or even believe,
that "float division is nothing more than a logical extension
of integer division" if "integer division" means what
Python presently does.

To any mathematician on the planet, 1/2 is, well, 1/2.
A rational number quite different from 0.

This isn't necessarily an argument for making division
return rationals when handed integers -- well, it is, but
it's not necessarily a very *strong* argument for that.
(It would involve a non-trivial amount of work, the
results would be amazingly frustrating in practice
unless the numerator and denominator had the sematics
of longs rather than ints, and simple programs could
become mysteriously inefficient. Some people would find
that worse than them just doing the wrong thing.)

If I were re-designing Python from scratch and didn't
care about backwards compatibility, then I'd give it
unified ints and longs, and rationals, and I'd make
division of integers produce rationals. But I'm not,
and since Guido is a better language designer than me
it's probably just as well.

Guido van Rossum

unread,
Jul 25, 2001, 12:18:35 AM7/25/01
to
Gareth.M...@pobox.com (Gareth McCaughan) writes:

> I am a mathematician, and I do not know, or even believe,
> that "float division is nothing more than a logical extension
> of integer division" if "integer division" means what
> Python presently does.

Thanks. I am baffled by the many claims that for mathematicians 1/2
equals zero; I've never met such a mathematicians.

> To any mathematician on the planet, 1/2 is, well, 1/2.
> A rational number quite different from 0.

Right.

> This isn't necessarily an argument for making division
> return rationals when handed integers -- well, it is, but
> it's not necessarily a very *strong* argument for that.
> (It would involve a non-trivial amount of work, the
> results would be amazingly frustrating in practice
> unless the numerator and denominator had the sematics
> of longs rather than ints, and simple programs could
> become mysteriously inefficient. Some people would find
> that worse than them just doing the wrong thing.)

Certainly any suggestion of rationals presumes the use of long ints.
The mysterious inefficiency is also my experience with ABC.

> If I were re-designing Python from scratch and didn't
> care about backwards compatibility, then I'd give it
> unified ints and longs, and rationals, and I'd make
> division of integers produce rationals. But I'm not,
> and since Guido is a better language designer than me
> it's probably just as well.

Right! In fact, the goal of PEP 238 is to make such a redesign of
Python's numeric system possible. This is hinted at by PEP 228
(Reworking Python's Numeric Model). Unfortunately, the motivational
sections in both PEPs are weak -- we never expected so much
opposition.

The interesting thing is that the one thing that has to change in
order to get a unified numeric model, whether we introduce rationals
in the numeric tower or not, is integer division! A numeric tower
with rationals could look like this:

int < long < rational < float < complex

(Note that float stands in for real -- I should have called it that,
in the grand tradition of Algol and Pascal. But this design bug is
not worth fixing, since it doesn't lead to programming errors.)

Without rationals, it would look like this:

int < long < float < complex

Either is acceptable to me; both have their share of problems. A
later transition from a numeric tower without rationals to a tower
with rationals doesn't have to create much backwards compatibility:
the mathematical value of 1/2 is the same of that as 0.5, so an
algorithm that works when 1/2 returns 0.5 will still work (and perhaps
even more accurately!) when 1/2 returns, well, the rational number
1/2.

But PEP 238 can stand on its own. If it is rejected, PEP 228 has no
chance; but PEP 238 can be accepted and PEP 228 rejected and the world
would still be a better place.

--Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum

unread,
Jul 25, 2001, 12:25:49 AM7/25/01
to
"Greg Landrum" <gReGl...@earthlink.net> writes:

> And then I start thinking about all the code I've written for
> myself, my former employer and my consulting clients. I *know* I've
> used '/' to do integer (truncating) division in that code
> intentionally. Of course I have, it's the way things were done.
> Once PEP 238 is implemented and the change in place (v2.3?), a lot
> of that code is going to start producing warnings.

The PEP needs an update. Here's what I am thinking of now.

- In 2.2, the future division statement and the // operator are
available, and there's a command line option to turn on warnings for
int/int and another to make the default for / be a float (i.e. an
implied future division statement everywhere). The standard library
is reworked to make it work with all option values.

- In later versions (timing not yet decided), first the default
changes to enable warnings on int/int, and then (after at least 2
years) to enable float division by default, but the command line
options remain available to reverse the situation.

> The warnings can be used to track down the problems before code actually
> breaks and there will be 2 years in which to do so... that's acceptable.
>
> I do have a question. The PEP says:
>
> If "from __future__ import non_integer_division" is present in the
> module, until the IntType nb_divide is changed, the "/" operator
> is compiled to FUTURE_DIV.
>
> This is not yet implemented in the Python 2.2 release.
>
> Okay, it's "not yet" implemented for 2.2. It's going to be though, right?

Yes; I have a preliminary patch in the SF patch manager (referenced
from the PEP).

> If the change is going to happen, it is going to break some of my
> code and I would like to start tracking down these problems and
> changing my programming habits ASAP.

Yes, you will be able to start changing your habits as soon as 2.2 is
released.

> [I started this message intending to make a very different argument because
> of the code breakage. Then I re-read the PEP and realized that we are being
> promised at least 2 years to fix things before code breaks. I'm much more
> comfortable with the PEP now.]

Thanks!

Courageous

unread,
Jul 25, 2001, 12:05:07 AM7/25/01
to
On 24 Jul 2001 08:35:51 -0400, com-n...@ccraig.org (Christopher A. Craig) wrote:

>any people have argued that they would like to see the behavior from
>the PEP if Python were a new language. I disagree. I would prefer to
>see '/' defined as "exact division" and '//' defined as "truncated
>division" and have types that don't support either raise a TypeError
>if the types don't support the operation in question. I think this
>parallels existing operations better.

I'd go further: '/' should be exact division, and "div" should be
truncated division, analagous to the way divmod works, except
without the mod.

C//

Guido van Rossum

unread,
Jul 25, 2001, 12:31:00 AM7/25/01
to
pa...@boddie.net (Paul Boddie) writes:

> If someone had suggested using // for the int/int->float operation, I
> bet that hardly anyone would have complained, apart from some people
> who might consider it "language bloat". But instead, it seems that for
> the sake of some aesthetic principle the rug is being pulled out from
> under everyone whether they want to lie down or not.

It's not just an aesthetic principle. The currently / behavior is a
design mistake that needs to be eventually eradicated, because it
makes writing reliable cood too hard and it makes writing subtly
broken code too easy. The only way to do that is to bite the bullet
-- otherwise Python will still have this problem in 10 years.

I can live with a temporary language wart that we're committed to
removing. I don't want to live with the wart forever, which the other
solution would do.

(Another argument for PEP 238, which I made in another message, is
that it opens to way to a unified numeric model, hinted at by PEP
228. I will update both PEPs to greatly improve the motivational
sections.)

Guido van Rossum

unread,
Jul 25, 2001, 12:54:45 AM7/25/01
to
"Chris Gonnerman" <chris.g...@newcenturycomputers.net> writes:

> Some of us have tried. Besides my alternative, I have seen two
> others which allow case-by-case preservation of the old semantics
> where they may have been intended.
>
> I have seen very few comments on them though (except from Stephen Horne).

It's not easy to find the light among the heat.

> ASSERTIONS:
> 1. Best-effort handling of division is desirable.
> 2. An explicit operator for truncating division is desirable
> (as in, explicit is better than implicit).
> 3. Code breakage is bad, and difficult-to-detect code breakage
> is worse.
> 4. Difficulty in writing backwards-compatible code is bad
> (thus, code to implement partitioning of a dataset would
> naturally use the // operator in 2.2+ but would not be able
> to in pre-2.2, so the div() function would have to be
> religiously used, hurting readability).
>
> Assertion 1 and 2 conflict with 3 and 4; #4 in particular bothers
> me.

Hm, #4 is relatively new in this discussion (for me, anyway). I will
have to adapt to this new requirement, which I find reasonable
(although I wish it didn't exist -- but I understand the motivation).

> Many have said that #3 is irrelevant as we have from 2.2 to 2.4 to
> fix it, but I have upgraded several systems directly from 1.5.2 to
> 2.1 without substantial problems; going direct to 2.4 from 2.1 would
> not be so painless.

You will have at least from 2.2 to 2.6 though (at least two years),
and in reality more because I propose to add a command line option to
revert to old division semantics for several releases after 2.6.

> SOME way is needed to specify, in module scope, which set of
> mathematics rules should be enforced. Whatever method is used
> should (IMHO) be uniform from 2.2 to 2.4; my method, as given, is
> the only one where the code reads the same from 2.2 on:
>
> from __numerics__ import original # or standard, etc...

Not bad. But I am still uncomfortable with making the old semantics a
*permanent* wart of the language. I'd much rather deal with a future
statement for 5 years than with a __past__ statement forever.

An alternative that would not need this would be to require

from __future__ import division

in order to use the new semantics, and use the proposed command line
option (say, "python -D old") to default to the old behavior as long
as you have to support unconverted code.

> Just thinking about the implementation gives me headaches, but Guido
> and Co. have readily implemented fancy things like the
> software-time-machine
>
> from __future__ import phasers, warp_drive # or whatever
>
> and so my proposal (or a mutation thereof) should be no biggie.

Indeed, this wouldn't be hard -- although maybe a friendlier syntax,
like "directive blah, blah, blah" might make sense *if* we decide to
do this. (Which I still don't think is the best solution, but I do
see your point.)

> As I said, you can't honestly say we ALL haven't been trying. It's
> not that I object directly to the change, it's the overall
> plan/effect/semantics etc. that I don't like.

Would it be more palatable to you if the new semantics didn't become
the default (or the law) until Python 3.0 was introduced?

That's how Perl dealt with a much larger incompatible language change:
Perl4 was left alone (I believe there are still plenty installations
that require it) and Perl5 was the future.

Guido van Rossum

unread,
Jul 25, 2001, 12:56:55 AM7/25/01
to
"Bjorn Pettersen" <BPett...@NAREX.com> writes:

> I think perhaps an equally interesting example is something like:
>
> 2L**128/2
>
> which currently gives an exact result, but under the proposed new
> semantics would give an approximation...

Have you read the PEP? The PEP only returns a float if the int result
would yield a remainder.

Andy Salnikov

unread,
Jul 25, 2001, 2:14:52 AM7/25/01
to

"Guido van Rossum" <gu...@python.org> wrote in message
news:cpitghb...@cj20424-a.reston1.va.home.com...

>
> Thanks. I am baffled by the many claims that for mathematicians 1/2
> equals zero; I've never met such a mathematicians.
>
To many of us, programmers, 1/2 is 0 with 1 as a reminder:) We are like
children, and any child will say _for sure_ that 1 cookie for two children
means one cookie for 1 child and 0 cookies for another:)

> The interesting thing is that the one thing that has to change in
> order to get a unified numeric model, whether we introduce rationals
> in the numeric tower or not, is integer division! A numeric tower
> with rationals could look like this:
>
> int < long < rational < float < complex
>

Just a comment: What bothers me is that floats in computers are not the
same as R continuum im math. This makes me think that rationals are "better"
than floats. Indeed, any float number can be exactly represented by
rational, but not vice virsa. So my tower would be like that:

int < long < float < rational < complex float < complex rational

but, in general, it does not fit good in the linear chain, because floats
are too imprecise and limited. The whole picture would be better without
floats:)

> But PEP 238 can stand on its own. If it is rejected, PEP 228 has no
> chance; but PEP 238 can be accepted and PEP 228 rejected and the world
> would still be a better place.
>

Would not it be better to have rationals first and than change meaning of
int/int->rational, than changing first to int/int->float and then to
int/int->rational?

Cheers,
Andy.


Tim Roberts

unread,
Jul 25, 2001, 2:40:21 AM7/25/01
to
Steve Horne <s...@ttsoftware.co.uk> wrote:
>
>Intellectual decline is not what it used to be ;-) - apparently the
>avarage childs IQ these days (I forget the exact age range) is around
>120. Must it's all the TV and video games ;-)

The average child's IQ these days is 100. That is the very definition of
IQ.
--
- Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

David Eppstein

unread,
Jul 25, 2001, 2:43:48 AM7/25/01
to
In article <9jlo4v$rhbl$1...@sky.inp.nsk.su>,
"Andy Salnikov" <saln...@inp.nsk.su> wrote:

> > int < long < rational < float < complex
> >
> Just a comment: What bothers me is that floats in computers are not the
> same as R continuum im math. This makes me think that rationals are "better"
> than floats. Indeed, any float number can be exactly represented by
> rational, but not vice virsa. So my tower would be like that:

The ordering is not by what is a "better" representation, or even by
information loss, but by what is the most appropriate direction for one-way
coercions. Although one could convert float->rational without information
loss, it would hardly ever be right to do so, because you are just making
things slower without anything to gain in return: you've already lost your
exactness and pretending you have it again won't make it so. On the other
hand int->long and long->rational are necessary to avoid overflow or
truncation, and any of these ->float are reasonable to speed up
computations where it is ok to be approximate.

So I completely agree with Guido's ordering.
--
David Eppstein UC Irvine Dept. of Information & Computer Science
epps...@ics.uci.edu http://www.ics.uci.edu/~eppstein/

Ben Wolfson

unread,
Jul 25, 2001, 3:07:18 AM7/25/01
to
On Tue, 24 Jul 2001 23:40:21 -0700, Tim Roberts <ti...@probo.com> wrote:

>Steve Horne <s...@ttsoftware.co.uk> wrote:
>>
>>Intellectual decline is not what it used to be ;-) - apparently the
>>avarage childs IQ these days (I forget the exact age range) is around
>>120. Must it's all the TV and video games ;-)
>
>The average child's IQ these days is 100. That is the very definition of
>IQ.

Except in Lake Woebegone, natch.

--
Barnabas T. Rumjuggler
No man can run so fast that he can escape his own past's projectile vomit.

Kirby Urner

unread,
Jul 25, 2001, 3:19:24 AM7/25/01
to
"Andy Salnikov" <saln...@inp.nsk.su> wrote:

> Would not it be better to have rationals first and than change meaning of
>int/int->rational, than changing first to int/int->float and then to
>int/int->rational?
>
>Cheers,
>Andy.
>

This echoes my sentiments over on edu...@python.org:

Were I in charge, I might have preferred that / remain the
way it is, until/unless a more Scheme-like inclusion of
the rational number type (different from float) came along,
which would happen when the "long" type melted away, and
became part of "int" (seamless i.e. no difference from the
user's point of view). This might have happened in 3.xx.
I think it's somewhat premature to fiddle with / in 2.x.

More context: http://mail.python.org/pipermail/edu-sig/2001-July/001543.html
where I admit it: I'm not in charge :-D

Kirby

Stephen Horne

unread,
Jul 25, 2001, 3:27:00 AM7/25/01
to
On Tue, 24 Jul 2001 18:01:27 GMT, "Terry Reedy" <tjr...@home.com>
wrote:

>
>"Steve Horne" <s...@ttsoftware.co.uk> wrote in message
>news:su3rltc8d88jrjdv9...@4ax.com...
>> > <list>*<list> raises a TypeError
>>
>> Given that other arithmetic operations have been hijacked for other
>> jobs (concat etc) with lists, there *is* no sensible meaning for
>this.
>
>Actually there *is*: cross concatenation, (somewhat similar to set
>cross products)
>
>L1*L2 := [i1+i2 for i1 in Li for i2 in L2]

Oops

Should have remembered that.

Toby Dickenson

unread,
Jul 25, 2001, 3:34:56 AM7/25/01
to
Guido van Rossum <gu...@python.org> wrote:

>"Bjorn Pettersen" <BPett...@NAREX.com> writes:
>
>> I think perhaps an equally interesting example is something like:
>>
>> 2L**128/2
>>
>> which currently gives an exact result, but under the proposed new
>> semantics would give an approximation...
>
>Have you read the PEP? The PEP only returns a float if the int result
>would yield a remainder.

That bit of the PEP didnt register on a first reading, and now I am
suprised at that rule.

As I understand it, this means long/long would sometimes give an exact
result and sometimes an approximation, depending on whether the
remainder is zero.

The problem isnt quite as simple as Bjorn was suggesting, but this is
definitely suprising:

>>> ((2L**1000)+0)/2
1071508607186267320948425.... <more digits snipped>

>>> ((2L**1000)+1)/2
1.07150860719e+301

>>> ((2L**2000)+0)/2
1148130695274254524232833.... <more digits snipped>

>>> ((2L**2000)+1)/2
inf

Toby Dickenson
tdick...@geminidataloggers.com

Tim Peters

unread,
Jul 25, 2001, 3:10:27 AM7/25/01
to pytho...@python.org
[Tim Roberts]

> The average child's IQ these days is 100. That is the very definition
> of IQ.

Except in Virginia. Jealous of the rumor that the Tennessee legislature had
defined pi to be 3 on the nose, the VA legislature defined *every* child's
IQ to be 120. The VA school system subsequently saved a lot of money on
now-useless tests, and by most accounts the kids didn't actually get any
dumber. It's also a great source of amusement that the Maryland legislature
sought to get even by mandating that all its childrens' IQs were 80.

suitable-changes-to-python's-numerics-will-follow-ly y'rs - tim


Mikael Olofsson

unread,
Jul 25, 2001, 3:41:02 AM7/25/01
to Andy Salnikov, pytho...@python.org

On 25-Jul-2001 Andy Salnikov wrote:
> To many of us, programmers, 1/2 is 0 with 1 as a reminder:) We are like
> children, and any child will say _for sure_ that 1 cookie for two children
> means one cookie for 1 child and 0 cookies for another:)

Sorry, that throws an exception (i.e. one of the children gets mad). One
cookie for two children means 0 cookies for both children, since mom or
dad did not serve that one cookie at all. After all that is the meaning
of 1/2 being 0 with 1 as a remainder.

Then-again-some-cookies-can-be-cut-in-pieces-ly y'rs

/Mikael

-----------------------------------------------------------------------
E-Mail: Mikael Olofsson <mik...@isy.liu.se>
WWW: http://www.dtr.isy.liu.se/dtr/staff/mikael
Phone: +46 - (0)13 - 28 1343
Telefax: +46 - (0)13 - 28 1339
Date: 25-Jul-2001
Time: 09:35:20

/"\
\ / ASCII Ribbon Campaign
X Against HTML Mail
/ \

This message was sent by XF-Mail.
-----------------------------------------------------------------------

Stephen Horne

unread,
Jul 25, 2001, 4:21:10 AM7/25/01
to
On Tue, 24 Jul 2001 23:40:21 -0700, Tim Roberts <ti...@probo.com>
wrote:

>Steve Horne <s...@ttsoftware.co.uk> wrote:


>>
>>Intellectual decline is not what it used to be ;-) - apparently the
>>avarage childs IQ these days (I forget the exact age range) is around
>>120. Must it's all the TV and video games ;-)
>
>The average child's IQ these days is 100. That is the very definition of
>IQ.

Not in the case where you compare current childrens performace against
past childrens performance on the same test and using the same
assessment criteria - which was the point.

Of course I was misusing a specialist statistic and I doubt I can even
find the source now, but it was just a joke.

Wiktor Sadowski

unread,
Jul 25, 2001, 2:18:52 AM7/25/01
to pytho...@python.org
[Andy Salnikov]

>To many of us, programmers, 1/2 is 0 with 1 as a reminder:) We are like
>children, and any child will say _for sure_ that 1 cookie for two children
>means one cookie for 1 child and 0 cookies for another:)

Your cookies are too old (tough) to slice or one of your children is too
clever (the fat one)

regards
Wiktor Sadowski

Paul Boddie

unread,
Jul 25, 2001, 5:10:22 AM7/25/01
to
Guido van Rossum <gu...@python.org> wrote in message news:<cpd76pb...@cj20424-a.reston1.va.home.com>...

> pa...@boddie.net (Paul Boddie) writes:
>
> > If someone had suggested using // for the int/int->float operation, I
> > bet that hardly anyone would have complained, apart from some people
> > who might consider it "language bloat". But instead, it seems that for
> > the sake of some aesthetic principle the rug is being pulled out from
> > under everyone whether they want to lie down or not.
>
> It's not just an aesthetic principle. The currently / behavior is a
> design mistake that needs to be eventually eradicated, because it
> makes writing reliable cood too hard and it makes writing subtly
> broken code too easy. The only way to do that is to bite the bullet
> -- otherwise Python will still have this problem in 10 years.

I don't disagree with your assertion that it's a bad thing. The
problem is that the / operator has a well-defined meaning in Python
which you're seeking to change. Whether or not it has a desirable
behaviour is almost irrelevant to the strongest argument to leave it
be: that changing its behaviour will potentially break lots of old
code.

I haven't seen any adequate response to the proposal that a different
operator (such as //, although I don't care so much) be used. And in
the PEP, whilst backward compatibility is mentioned, it isn't
addressed in any way which can be considered an acceptable treatment
of the subject.

> I can live with a temporary language wart that we're committed to
> removing. I don't want to live with the wart forever, which the other
> solution would do.

You have designed a language which I and many others really enjoy
using, and are really grateful for. Whilst programming languages tend
to differ from natural languages by resisting change in order to
promote robust, well-defined semantics, what you are doing here is
analogous to issuing a decree that a particular word in
English/Dutch/French (or your preferred natural language), where the
word isn't exactly an infrequently used noun, now means something
else.

What do you propose we do with all the novels ever written in that
language? Instigate a massive rewriting project? Burn them? Did Monty
Python ever do a sketch about the Cultural Revolution? <1/3 wink>

> (Another argument for PEP 238, which I made in another message, is
> that it opens to way to a unified numeric model, hinted at by PEP
> 228. I will update both PEPs to greatly improve the motivational
> sections.)

Your numerical aspirations are noble, but due to practical
considerations won't some of us end up speaking "Dutch" and some of us
speaking "Flemish"? ;-)

Paul

Marcin 'Qrczak' Kowalczyk

unread,
Jul 25, 2001, 8:47:30 AM7/25/01
to
26 Jul 2001 00:03:56 +1200, Paul Foley <see@below> pisze:

>> int < long < rational < float < complex
>

> Well, it could, I suppose, but that would be a good reason to avoid
> Python :-)
>
> What it *should* look like is this:
>
> int < long < rational
> \
> + < [real] < complex
> /
> float

There are no real reals in programming. And Python's complex is as
inexact as float.

I don't understand you. What practical difference do these diagrams
yield? What is wrong in *consequences* of Guido's and mine model
which your model puts differently?

What happens if you int to float in your model? Rational to float?

Frank Cookie Jar Lomax

unread,
Jul 25, 2001, 10:55:57 AM7/25/01
to pytho...@python.org

> To many of us, programmers, 1/2 is 0 with 1 as a reminder:)
> We are like children, and any child will say _for sure_ that 1
> cookie for two children means one cookie for 1 child and 0
> cookies for another:)

No, 1 cookie for 2 children always means no cookies for either child,
lots of crumbs for the dog to lick up, and years of therapy for the
entire family.

proof-that-integer-division-causes-thousands-of-disfunctional-families-
per-year-and-must-be-abolished-ly y'rs, - frank

Terry Reedy

unread,
Jul 25, 2001, 2:08:44 PM7/25/01
to
> Right! In fact, the goal of PEP 238 is to make such a redesign of
> Python's numeric system possible

Saying this explicitly makes explicitly obvious what to me was not,
before:-). Even though I do not currently care about such a redesign,
but you do, I consider the above a point in favor of 238.

(I am assuming that such a redesign would not break 'regular' floating
point code, such as Newton's method, that does not depend on every
last bit being just as it currently is to run correctly.)

I think another, currently less-well-articulated goal/result of 238 is
that it will make it possible for you to pursue your CP4E dream
project without forking Python and also without needing to make
further disruptive changes to the core. If you agree with the last
proviso, then I also consider this a point in 238's favor. I think
more could be said about the connection that would make what's obvious
to you clearer to others.

> The interesting thing is that the one thing that has to change in
> order to get a unified numeric model, whether we introduce rationals
> in the numeric tower or not, is integer division

(IMO -- and attempting to be helpful again) This (and similar
statements) is rhetorically wrong and counter-productive. In PEP238,
you are NOT proposing to delete integer division (and I hope/presume
you never will), you are NOT proposing to switch it to C's version
(ditto), nor are you proposing any other substantive change (ditto).
From a technical viewpoint, you are merely, in Tim's words, proposing
to change it's spelling, so that future i//j == current i/j, down to
the very last bit. (I am ignoring any possible effect of int/long
unification, which is a completely separate issue.) So to ask another
rhetorical question: why frighten people unnecessarily? or futilely
attempt to get them to accept something that you are not proposing
(and I hope/presume you never will)?

The *really* interesting thing is that the one thing that has to
change for you to pursue your further numeric goals is the current
overloading of integer and fractional division onto one symbol, which
is exactly what 238 undoes by adding a second symbol. The main
practical technical issue, to repeat from my essay of two weeks ago,
is code breakage, forwards and back, and the costs and benefits
thereof.

The important thing is that the one thing you need from people in
order to make 238 work without forking Python is their agreement (for
whatever personal reason) to do the respelling and absorb the cost in
return for the expected long-term individual and collective benefits.
You do not need, and will never get, general agreement on the
metaphysical relationships of abstract (count, integer, rational,
real) and concrete (int, long, float) number sets. Ditto for the
abstract virtue or esthetics of various combinations of type-dependent
division rules.

Terry J. Reedy

sburrious

unread,
Jul 25, 2001, 2:29:54 PM7/25/01
to
lo...@pumpichank.com (Frank "Cookie Jar" Lomax) wrote in message news:<mailman.996073073...@python.org>...

Unless you use the old trick of having one child divide the cookie and
the other choose which piece he or she wants.

would-there-were-such-a-solution-to-the-int-division-debate-ly y'rs,
sburrious

William Tanksley

unread,
Jul 25, 2001, 3:12:45 PM7/25/01
to
On Wed, 25 Jul 2001 04:18:35 GMT, Guido van Rossum wrote:
>Thanks. I am baffled by the many claims that for mathematicians 1/2
>equals zero; I've never met such a mathematicians.

Perhaps the best solution would be to make Python's integers actually be
the field of integers mod 4294967291 (not too much of a change -- they're
currently very similar to the integers mod 4294967295). The best of all
worlds -- divisions no longer have remainders, and everything's exact
again.

>--Guido van Rossum (home page: http://www.python.org/~guido/)

and-writing-the-log-function-becomes-a-lot-more-fun-ly yr's

--
-William "Billy" Tanksley

William Tanksley

unread,
Jul 25, 2001, 3:14:10 PM7/25/01
to
On Wed, 25 Jul 2001 10:55:57 -0400, Frank "Cookie Jar" Lomax wrote:
> > To many of us, programmers, 1/2 is 0 with 1 as a reminder:)
> > We are like children, and any child will say _for sure_ that 1
> > cookie for two children means one cookie for 1 child and 0
> > cookies for another:)

>No, 1 cookie for 2 children always means no cookies for either child,
>lots of crumbs for the dog to lick up, and years of therapy for the
>entire family.

_Exactly_ like floating point! Look at what it did to poor Tim.

--
-William "Billy" Tanksley

David Bolen

unread,
Jul 25, 2001, 3:59:26 PM7/25/01
to
"Terry Reedy" <tjr...@home.com> writes:

> (IMO -- and attempting to be helpful again) This (and similar
> statements) is rhetorically wrong and counter-productive. In PEP238,
> you are NOT proposing to delete integer division (and I hope/presume
> you never will), you are NOT proposing to switch it to C's version
> (ditto), nor are you proposing any other substantive change (ditto).
> From a technical viewpoint, you are merely, in Tim's words, proposing
> to change it's spelling, so that future i//j == current i/j, down to

> the very last bit. (...)

Just for clarification, I don't think that's quite right. // is being
proposed for integer division only. That is, unlike todays /, using
// with two floats, while still yielding a float, would yield the
floor() of what today's / would have yielded, and thus not the same


"down to the very last bit"

--
-- David
--
/-----------------------------------------------------------------------\
\ David Bolen \ E-mail: db...@fitlinxx.com /
| FitLinxx, Inc. \ Phone: (203) 708-5192 |
/ 860 Canal Street, Stamford, CT 06902 \ Fax: (203) 316-5150 \
\-----------------------------------------------------------------------/

David Bolen

unread,
Jul 25, 2001, 4:07:58 PM7/25/01
to
Guido van Rossum <gu...@python.org> writes:

> "Bjorn Pettersen" <BPett...@NAREX.com> writes:
>
> > I think perhaps an equally interesting example is something like:
> >
> > 2L**128/2
> >
> > which currently gives an exact result, but under the proposed new
> > semantics would give an approximation...
>
> Have you read the PEP? The PEP only returns a float if the int result
> would yield a remainder.

Does it? While returning an integral value in the above case,
wouldn't it would in fact be a float data type (barring the addition
of rationals), as per:

(from PEP238)

"The type of a/b will be either a float or a rational, depending on
other PEPs[2, 3]. However, the result will be integral in all case
the division has no remainder."

And given that, what happens if float can't represent the resulting
precision necessary?

Of course, this is only true later when this is the default, right?
Until then, the "future" implementation is an addition of 0.0 to the
divisor, so the result would definitely be float, and not necessarily
integral.

Unless you meant something other than the data type involved by
"returns a float".

Guido van Rossum

unread,
Jul 25, 2001, 4:24:46 PM7/25/01
to
David Bolen <db...@fitlinxx.com> writes:

> Guido van Rossum <gu...@python.org> writes:
>
> > "Bjorn Pettersen" <BPett...@NAREX.com> writes:
> >
> > > I think perhaps an equally interesting example is something like:
> > >
> > > 2L**128/2
> > >
> > > which currently gives an exact result, but under the proposed new
> > > semantics would give an approximation...
> >
> > Have you read the PEP? The PEP only returns a float if the int result
> > would yield a remainder.
>
> Does it? While returning an integral value in the above case,
> wouldn't it would in fact be a float data type (barring the addition
> of rationals), as per:
>
> (from PEP238)
>
> "The type of a/b will be either a float or a rational, depending on
> other PEPs[2, 3]. However, the result will be integral in all case
> the division has no remainder."
>
> And given that, what happens if float can't represent the resulting
> precision necessary?
>
> Of course, this is only true later when this is the default, right?
> Until then, the "future" implementation is an addition of 0.0 to the
> divisor, so the result would definitely be float, and not necessarily
> integral.
>
> Unless you meant something other than the data type involved by
> "returns a float".

The PEP is currently contradictory and incomplete. The "future
division" operator (generated by x/y when in the scope of a future
division statement) will return either a rational or a float --
obviously it can't return a rational until they have been made part of
the language (which may or may not ever happen). Since 2.2 won't have
rationals, it will return a float even for 2L**128/2 -- but only when
you use a future division statement, and in that case you get what you
ask for.

The current patch on SF adds 0.0 but that's not what it will do once
2.2 is released.

David Eppstein

unread,
Jul 25, 2001, 4:45:55 PM7/25/01
to
In article <slrn9lu6hc....@dolphin.openprojects.net>,
wtan...@dolphin.openprojects.net (William Tanksley) wrote:

> Perhaps the best solution would be to make Python's integers actually be
> the field of integers mod 4294967291 (not too much of a change -- they're
> currently very similar to the integers mod 4294967295). The best of all
> worlds -- divisions no longer have remainders, and everything's exact
> again.

If you instead used the ring of integers mod 2^32, you could still divide
by any odd number exactly, without remainders. Division by even numbers
would be harder, but everyone optimizes those by replacing them with
shifts, right?

I think even fewer people would like the results of division in these
systems, though -- e.g. what is 1/3?

> and-writing-the-log-function-becomes-a-lot-more-fun-ly yr's

For mod 2^32, I think what you want is the 2-adic norm...

Lloyd Zusman

unread,
Jul 25, 2001, 8:16:54 PM7/25/01
to
sb...@home.com (sburrious) writes:

Ah ... but there *is* such a solution:

One thread performs an arbitrary integer partitioning, and a second
thread chooses the value within the partition to return to the caller.

For example, to do 5/2, the first thread would arbitrarily pick one of
these 2-element partitions: [0,5], [1,4], [2,3]. It would pass this
partition to the second thread, which would also arbitrarily choose
one of the two numbers to return to the caller, with the other value
returned to the first thread. E.g., if partition [1,4] happens to be
chosen by the first thread, the second thread could return either 1 or
4 to the caller, and the other value back to the first thread.

Not very efficient, not very accurate, not very useful, and not even
very desirable, but given intelligent threads operating under heavy
self-interest (in Python 6.0 maybe?), at least it would be fair. :)


Actually, I'm very much in agreement with Guido's latest decision (to
wait until Python 3.0 before this change in division semantics goes
into full effect, tying it to _future_ in prior versions). It's a
Solomonic solution, and I applaud your wisdom, Guido.


> sburrious

--
Lloyd Zusman
l...@asfast.com

Paul Svensson

unread,
Jul 25, 2001, 9:55:05 PM7/25/01
to
"Terry Reedy" <tjr...@home.com> writes:

>> The interesting thing is that the one thing that has to change in
>> order to get a unified numeric model, whether we introduce rationals
>> in the numeric tower or not, is integer division
>
>(IMO -- and attempting to be helpful again) This (and similar
>statements) is rhetorically wrong and counter-productive. In PEP238,
>you are NOT proposing to delete integer division (and I hope/presume
>you never will), you are NOT proposing to switch it to C's version
>(ditto), nor are you proposing any other substantive change (ditto).
>From a technical viewpoint, you are merely, in Tim's words, proposing
>to change it's spelling, so that future i//j == current i/j, down to
>the very last bit.

This is not what's proposed.
i//j will be for all numeric types like current i/j for ints.
i/j will be for all numeric types like current i/j for floats.

>The *really* interesting thing is that the one thing that has to
>change for you to pursue your further numeric goals is the current
>overloading of integer and fractional division onto one symbol, which
>is exactly what 238 undoes by adding a second symbol. The main
>practical technical issue, to repeat from my essay of two weeks ago,
>is code breakage, forwards and back, and the costs and benefits
>thereof.

The important thing is that i//j will return the same value
regardless if i and j ar ints or floats; ditto for the new i/j.

Numeric unification means that (i == x and j == y) == (i op j == x op y)
for all op, i, j, x, y, regardless of numeric type
(ignoring exceptions and round-off errors).

This is not true for the current semantics of '/'. That's why it must go.

/Paul

Terry Reedy

unread,
Jul 25, 2001, 11:03:20 PM7/25/01
to

"Guido van Rossum" <gu...@python.org> wrote in message
news:cp66chb...@cj20424-a.reston1.va.home.com...
> "Chris Gonnerman" <chris.g...@newcenturycomputers.net> writes:
> > 4. Difficulty in writing backwards-compatible code is bad
> > (thus, code to implement partitioning of a dataset would
> > naturally use the // operator in 2.2+ but would not be
able
> > to in pre-2.2, so the div() function would have to be
> > religiously used, hurting readability).

> Hm, #4 is relatively new in this discussion (for me, anyway). I
will
> have to adapt to this new requirement, which I find reasonable
> (although I wish it didn't exist -- but I understand the
motivation).

My solution for this:

Since int/int and float//float will have new meanings, don't use them.
Write float(int)/int and floor(float/float) instead to get the new
meaning. Only write int//int or float/float. With the tokenizer
module, it will then be easy to change all instances of int//int to
int/int (old meaning). It should even even be possible to have
package installers check sys.version and do this conversion on site as
needed.

This is not the same as having *one* file that is cross-compatible,
but since the generation of the second is automated, it is certainly
close. A version check could be inserted in both versions (and
automatically modified) to make sure that each version of the file
only runs on versions of the interpreter it is compatible with.

For newly written code, the harder problem will be to not use
any of the other neat new features, which mostly *cannot* be
automatically back converted.

Terry J. Reedy

Terry Reedy

unread,
Jul 25, 2001, 11:15:55 PM7/25/01
to

"Guido van Rossum" <gu...@python.org> wrote in message
news:cpd76pb...@cj20424-a.reston1.va.home.com...

Just to let you know that you are making some progress ...

> It's not just an aesthetic principle. The currently / behavior is a
> design mistake that needs to be eventually eradicated,

With the metaphysical mists having mostly dissapated, I now agree with
this for Python. I also believe that the similar behaviour of C is
correct for C.

> because it makes writing reliable cood too hard and it makes
writing subtly
> broken code too easy.

This is because of Python's type system, which is considerably
different from C's.

> The only way to do that is to bite the bullet
> -- otherwise Python will still have this problem in 10 years.

Agreed, better now than later.

Terry J. Reedy


John W. Baxter

unread,
Jul 26, 2001, 1:28:20 AM7/26/01
to
In article <mailman.996045152...@python.org>, Tim Peters
<tim...@home.com> wrote:

> [Tim Roberts]
> > The average child's IQ these days is 100. That is the very definition
> > of IQ.
>
> Except in Virginia. Jealous of the rumor that the Tennessee legislature had
> defined pi to be 3 on the nose, the VA legislature defined *every* child's
> IQ to be 120. The VA school system subsequently saved a lot of money on
> now-useless tests, and by most accounts the kids didn't actually get any
> dumber. It's also a great source of amusement that the Maryland legislature
> sought to get even by mandating that all its childrens' IQs were 80.
>

That's the news from Lake Woebegone, where all the women are
strong...all the men are good looking...and all the children are above
average.

--John

Skip Montanaro

unread,
Jul 26, 2001, 2:50:30 AM7/26/01
to Paul Foley, pytho...@python.org

Paul> The most obvious problem is that it implies that every rational
Paul> can be represented as a float -- this is *severe* brokenness you
Paul> don't need. [I think it also implies that floats with integral
Paul> values (1.0, etc.) should turn into integers.]

You can't do that. Suppose that value you think is 1.0 really got truncated
during a previous calculation because your fp hardware doesn't have enough
bits and lost it? If you convert that to the integer 1 you're screwed
because you are pretending your inexact approximation of the real value is
the real value. You're better off admitting you have an inexact value and
planning accordingly. The only time the VM can convert from inexact to
exact (e.g., float->rational, float->int) is when the programmer says you
can with a cast.

--
Skip Montanaro (sk...@pobox.com)
http://www.mojam.com/
http://www.musi-cal.com/

Duncan Booth

unread,
Jul 26, 2001, 3:40:34 AM7/26/01
to
lo...@pumpichank.com (Frank "Cookie Jar" Lomax) wrote in
news:mailman.996073073...@python.org:

> No, 1 cookie for 2 children always means no cookies for either child,
> lots of crumbs for the dog to lick up, and years of therapy for the
> entire family.
>
> proof-that-integer-division-causes-thousands-of-disfunctional-families-
> per-year-and-must-be-abolished-ly y'rs, - frank
>

This newsgroup is getting decidedly surreal this morning. the post above
was immediately followed in my newsreader by one beginning:

> Check out the Cookie module in the Python distribution:
>
> http://www.python.org/doc/current/lib/module-Cookie.html
>
> It includes a simple example of how to use cookies from Python.


--
Duncan Booth dun...@rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?

Manoj Plakal

unread,
Jul 26, 2001, 3:55:45 AM7/26/01
to
Guido van Rossum <gu...@python.org> wrote on Tuesday 24 July 2001 23:18:
> Gareth.M...@pobox.com (Gareth McCaughan) writes:
>> To any mathematician on the planet, 1/2 is, well, 1/2.
>> A rational number quite different from 0.
>
> Right.

It seems to me that the word "division" is being sorely
overloaded in these threads as well as in PEP 238. Would
it be more precise (mathematically and otherwise) to
reword things like this:

- currently, the symbol `/' in Python programs signifies
two different operators depending on the arguments:
- the QUOTIENT operator with 2 integer arguments

- the DIVISION operator with at least 1 float
argument

- the proposed change is to make '/' always signify the
DIVISION operator and '//' always signify the QUOTIENT
operator

Seems to be more clear than saying "integer division"
or "truncating division" or "float division".

Just my 2 cents ...

Manoj

Marcin 'Qrczak' Kowalczyk

unread,
Jul 26, 2001, 3:34:46 AM7/26/01
to
26 Jul 2001 17:04:00 +1200, Paul Foley <see@below> pisze:

> I know that; that doesn't mean there shouldn't be a real _type_.
> It doesn't have to be instantiable. If you want to use it as a
> constructor, it can return some appropriate concrete subclass.

In other words it's not a type: it's a function which returns its
argument unchanged or throws an exception. I don't think it's a
useful function.

>> I don't understand you. What practical difference do these diagrams
>> yield? What is wrong in *consequences* of Guido's and mine model
>> which your model puts differently?
>

> The most obvious problem is that it implies that every rational

> can be represented as a float

It doesn't.

It only implies that if you have a choice of converting a float to a
rational or a rational to a float (to bring them to a common type),
you convert the rational to a float.

> [I think it also implies that floats with integral values (1.0, etc.)
> should turn into integers.]

It doesn't. My model makes the result depending on the type of
arguments, not values (except that it matters whether the exponent
of ** is a negative int or a nonnegative int).

It could be changed to unify ints and rationals, i.e. always turn
whole-number rationals into ints. I would not do it for float because
it loses the information that the data is inexact.

>> What happens if you int to float in your model? Rational to float?
>

> What do you mean, what happens? You get a float.

So it works exactly as my model! And you say my model is broken and
yours doesn't?

How it follows from your model BTW? Rationals and floats are unordered
on your diagram.

The clue: what is a practical difference between them? What expression
has different values (including the possibility of different types)
in our models? I can't find any.

Manoj Plakal

unread,
Jul 26, 2001, 4:15:17 AM7/26/01
to
Manoj Plakal <plakal...@nospam-cs.wisc.edu> wrote on Thursday 26 July
2001 02:55:

> - currently, the symbol `/' in Python programs signifies
> two different operators depending on the arguments:
> - the QUOTIENT operator with 2 integer arguments
>
> - the DIVISION operator with at least 1 float
> argument
>
> - the proposed change is to make '/' always signify the
> DIVISION operator and '//' always signify the QUOTIENT
> operator


Forgot to add that in the future, when we do unify ints and longs
and bring in rationals, then we again end up overloading the
'/' operator to mean two things:

- a constructor of rationals (with 2 integer arguments)

- the DIVISION operator (with at least 1 float argument)

Is this correct? Or maybe when we've unified everything into
a single number type, these will actually be the same thing:
you represent the number as a rational when you can and as
a real number otherwise. It's still "division".

I would be curious to know if other languages have a unified
number type (Scheme? Smalltalk?) and how they handle the
various operators and when to choose a certain representation
(rational vs real).

Manoj

Bruce Sass

unread,
Jul 26, 2001, 4:15:07 AM7/26/01
to dun...@rcp.co.uk, pytho...@python.org

On Thu, 26 Jul 2001, Duncan Booth wrote:

> lo...@pumpichank.com (Frank "Cookie Jar" Lomax) wrote in
> news:mailman.996073073...@python.org:
>
> > No, 1 cookie for 2 children always means no cookies for either child,
> > lots of crumbs for the dog to lick up, and years of therapy for the
> > entire family.
> >
> > proof-that-integer-division-causes-thousands-of-disfunctional-families-
> > per-year-and-must-be-abolished-ly y'rs, - frank
> >
>
> This newsgroup is getting decidedly surreal this morning. the post above
> was immediately followed in my newsreader by one beginning:
>
> > Check out the Cookie module in the Python distribution:
> >
> > http://www.python.org/doc/current/lib/module-Cookie.html
> >
> > It includes a simple example of how to use cookies from Python.

and if you are using Linux you can have Coffee with your cookies...

-----8<-----
COFFEE-HOWTO

Georgatos Photis, < g...@ceid.upatras.gr>

v0.5, 15 January 1998

____________________________________________________________________

One of the most bothering remarks on software, I have ever heard,
is weather this or that thing can make coffee. So, Linux
DOES make coffee. And it tastes good, instead!
____________________________________________________________________

...

The main problem is how to control the coffee machine with the
computer, so that it will be controlled by software. This generally
means an ON/OFF switch implemented as a circuit which controls the
coffee-machine's power supply.

...

----->8-----

sorry.


Grant Edwards

unread,
Jul 26, 2001, 10:39:46 AM7/26/01
to
In article <9jnt9p$qhe$1...@newsy.ifm.liu.se>, Paul Svensson wrote:

>The important thing is that i//j will return the same value
>regardless if i and j ar ints or floats; ditto for the new i/j.

If that's important, why won't the other math operators do it???

--
Grant Edwards grante Yow! Now that I have my
at "APPLE," I comprehend COST
visi.com ACCOUNTING!!

Paul Svensson

unread,
Jul 26, 2001, 11:32:55 AM7/26/01
to
Skip Montanaro <sk...@pobox.com> writes:

In the long term, I think the only manageable solution would
be to separate the issue of exactness from the representation.

/Paul (another one than the one above)

Guido van Rossum

unread,
Jul 26, 2001, 12:31:47 PM7/26/01
to
gra...@visi.com (Grant Edwards) writes:

> >The important thing is that i//j will return the same value
> >regardless if i and j ar ints or floats; ditto for the new i/j.
>
> If that's important, why won't the other math operators do it???

Huh? They do (apart from unavoidable round-off errors). 1+2 == 1.0+2.0.

Grant Edwards

unread,
Jul 26, 2001, 1:47:34 PM7/26/01
to
In article <cpitgf7...@cj20424-a.reston1.va.home.com>, Guido van Rossum wrote:
>gra...@visi.com (Grant Edwards) writes:
>
>> >The important thing is that i//j will return the same value
>> >regardless if i and j ar ints or floats; ditto for the new i/j.
>>
>> If that's important, why won't the other math operators do it???
>
>Huh? They do (apart from unavoidable round-off errors). 1+2 == 1.0+2.0.

They compare equal with the "==" operator, but they are not
the same value:

>>> 1+2
3
>>> 1.0+2.0
3.0
>>>

... unless 3 and 3.0 are "the same value". In which case my
definition of that phrase is merely different than yours.

--
Grant Edwards grante Yow! I wonder if I ought
at to tell them about my
visi.com PREVIOUS LIFE as a COMPLETE
STRANGER?

Terry Reedy

unread,
Jul 26, 2001, 1:59:48 PM7/26/01
to

"Manoj Plakal" <plakal...@nospam-cs.wisc.edu> wrote in message
news:52Q77.181728$mG4.85...@news1.mntp1.il.home.com...

> It seems to me that the word "division" is being sorely
> overloaded in these threads as well as in PEP 238. Would
> it be more precise (mathematically and otherwise) to
> reword things like this:
>
> - currently, the symbol `/' in Python programs signifies
> two different operators depending on the arguments:
> - the QUOTIENT operator with 2 integer arguments
>
> - the DIVISION operator with at least 1 float
> argument
>
> - the proposed change is to make '/' always signify the
> DIVISION operator and '//' always signify the QUOTIENT
> operator
>
> Seems to be more clear than saying "integer division"
> or "truncating division" or "float division".

Bravo. This clear and succinct summary of PEP0238 makes its intent
and virtues clearer than anything I've read (or written) so far.

Guido, please consider something very much like this for the Abstract.

Terry J. Reedy

Terry Reedy

unread,
Jul 26, 2001, 3:35:57 PM7/26/01
to
I believe that 5.0//2.0 will be 2.0, not 2

TJR

Grant Edwards

unread,
Jul 26, 2001, 4:02:11 PM7/26/01
to
In article <xi_77.30701$EP6.7...@news1.rdc2.pa.home.com>, Terry Reedy wrote:

>I believe that 5.0//2.0 will be 2.0, not 2

Ah, but 2.0 and 2 are the same value....

--
Grant Edwards grante Yow! Of course, you
at UNDERSTAND about the PLAIDS
visi.com in the SPIN CYCLE --

Guido van Rossum

unread,
Jul 26, 2001, 5:18:38 PM7/26/01
to
[Guido]

> >> >The important thing is that i//j will return the same value
> >> >regardless if i and j ar ints or floats; ditto for the new i/j.

[Grant]


> >> If that's important, why won't the other math operators do it???

[Guido]


> >Huh? They do (apart from unavoidable round-off errors). 1+2 == 1.0+2.0.

[Grant]


> They compare equal with the "==" operator, but they are not
> the same value:
>
> >>> 1+2
> 3
> >>> 1.0+2.0
> 3.0
> >>>
>
> ... unless 3 and 3.0 are "the same value". In which case my
> definition of that phrase is merely different than yours.

[Guido]
Well, they have the same *mathemtical* value, and Python does its
darndest to treat them as equal everywhere. For example, a dict with
int keys can be indexed with corresponding float or complex values.
Exceptions are operations that intrinsically require ints, e.g. list
indexing. (This would change under a unified numeric system though, I
expect, unless inexact numbers are excluded from being used as
sequence indices.)

Grant Edwards

unread,
Jul 26, 2001, 5:44:51 PM7/26/01
to
In article <cp3d7j7...@cj20424-a.reston1.va.home.com>, Guido van Rossum wrote:

>> >>> 1+2
>> 3
>> >>> 1.0+2.0
>> 3.0
>> >>>
>>
>> ... unless 3 and 3.0 are "the same value". In which case my
>> definition of that phrase is merely different than yours.
>
>[Guido]
>Well, they have the same *mathemtical* value, and Python does its
>darndest to treat them as equal everywhere.

I've been thinking in assembly language too long. :) In my
mind, floats and ints are only distantly related.

>For example, a dict with int keys can be indexed with
>corresponding float or complex values.

That's interesting -- I didn't know that.

>Exceptions are operations that intrinsically require ints, e.g. list
>indexing. (This would change under a unified numeric system though, I
>expect, unless inexact numbers are excluded from being used as
>sequence indices.)

If the numerical types all get unified, then I think one would
expect an inexact number to get "converted" to an exact one if
used in that context.

--
Grant Edwards grante Yow! I guess it was all a
at DREAM... or an episode of
visi.com HAWAII FIVE-O...

Guido van Rossum

unread,
Jul 26, 2001, 6:03:11 PM7/26/01
to
gra...@visi.com (Grant Edwards) writes:

> If the numerical types all get unified, then I think one would
> expect an inexact number to get "converted" to an exact one if
> used in that context.

There are no exact and inexact contexts. There are only exact and
inexact operations. An exact operation yields an exact result iff all
its inputs are exact, otherwise it yields an inexact result. +, -, *
are examples of exact operations; / is exact if you allow a rational
result. But inexact+exact gives an inexact result.

Bengt Richter

unread,
Jul 26, 2001, 8:30:12 PM7/26/01
to
On 25 Jul 2001 12:47:30 GMT, Marcin 'Qrczak' Kowalczyk <qrc...@knm.org.pl> wrote:

>26 Jul 2001 00:03:56 +1200, Paul Foley <see@below> pisze:
>
>>> int < long < rational < float < complex
>>
>> Well, it could, I suppose, but that would be a good reason to avoid
>> Python :-)
>>
>> What it *should* look like is this:
>>
>> int < long < rational
>> \
>> + < [real] < complex
>> /
>> float
>
>There are no real reals in programming. And Python's complex is as
>inexact as float.


>
>I don't understand you. What practical difference do these diagrams
>yield? What is wrong in *consequences* of Guido's and mine model
>which your model puts differently?
>

>What happens if you int to float in your model? Rational to float?
>

The trouble with these discussions is that common usage creates an
overloading of meanings for the words. Some of these things can be
talked about sensibly even if computers don't exist. Some can't.
From the above,

Can: rational, real, complex (integer belongs here too)
Can't: int, long, float

Separating the abstract (A) world from the world of (R)representations, you get
a different diagram, with as many variations below the line as you can
imagine (I'm mixing in C types and common typedefs to illustrate the idea)

A[integer] < A[rational] < A[real] < A[complex]
v v v v
-------v------------v------------------------v----------------v-----------
v v v v
R[integer] R[rational] R[real] R[real],R[real]
v~ ~[5] +---------v~ ~[6] +~ ~[7]
long R[i]/R[i] float[3] R[rational]
v v v v
int64 R[i] fsingle[4] R[integer]
v
fdouble[1]
v
int32
v
fsingle[2]
v
int16,short
v
int8,char
v
(single bit)

R[i] is short for R[integer] above. Specifics re fp below relate to IEEE754:
[1] as 53-bit integer
[2] as 24-bit integer
[3] as 53-bit integer * 2^n where -1022<=n<=1023 (interpret -n as /2^n )
[4] as 24-bit integer * 2^n where -126<=n<=127 (ditto)
[5] I show a wiggly side branch, because there's a zillion possible other ways
to represent integers. Python's long internally makes use of 15-bit integers,
I think I read in a post of Tim's, so it's really off to the side if you
like to think in terms of more traditional C representation types.
I included the floats at [1] and [2] just to illustrate possible variety.
[6] I added this to point out that you can/must interpret floating point numerical states
as representations of particular exact A[rational] numbers, and these exact
A[rationals] also serve as approximations to A[reals] (which can be right on or not)
represented as R[rational] under R[real]. BTW, "A[float]" is a way of referring to
the peculiar subset of A[rational] representable by concrete float states.
[7] On this branch, you could imagine various schemes for representing irrational
numbers, such as rationals with stored rational exponents, and special
representations for e and pi etc., etc.

By R[integer] etc., I mean representation in the widest sense that can have a
concrete realization. E.g., we could imagine representing really big integers
by combining the distributed resources on the internet. The point is, what's
below the line has no significance mathematically until you translate it back
to something above the line using some mapping you have in mind.

Computers have been designed to transform stuff below the line. They can't touch
stuff above the line. They can only produce stuff that may have a relationship
to what's above. It's pretty obvious if you think about it, but it's easy to
lose sight of in daily shortcut habits of thought.

Maybe our discussions would become clearer if we adopted a convention to indicate
which aspect of a number we were talking about, e.g., A[x] for the abstraction
behind our mention of x, and R[x] for some corresponding representation. If you
want to indicate a specific type of representation, it could be R[type:x], e.g.,
R[float:x]

Saying that "there are no real reals in programming" is really saying
A[real] != R[real], but that doesn't mean that we can't deal with A[problems]
with A[real] functions by using R[real] approximations.

Without [7] we can do no better than R[rational] under R[real], which is why
I didn't elaborate the tree. Note that R[rational] includes float at [3].
Decimal floats or any other monster float you can come up with will ultimatlely also
attach at [6].

Anyway, this is the way I look at it ;-)

Maybe with Guido and Tim's help, and that of lurking mathematicians, something like
the above could become a useful part of Python docs.

It would be nice to work in exact vs inexact also. Obviously, any R[] is exactly
something, because it has a particular distinct state, so there is an A[x] for every R[x].
Thus every R[x] has the possibility of serving as an exact representation (i.e., of A[x]).
But I think I'll stop here, because exactness and all that is too big a discussion.

HTH make discussions more meaningful ;-)

Dave Cole

unread,
Jul 26, 2001, 8:35:12 PM7/26/01
to
>>>>> "Guido" == Guido van Rossum <gu...@python.org> writes:

Guido> For example, a dict with int keys can be indexed with
Guido> corresponding float or complex values.

You are a legendissimo!!!

I implemented an extension type for the Sybase native NUMERIC column
type in my Sybase module but never really gave things like this much
thought.

Now I know why I do not bother adding my 2c to arguments regarding
fundamental language features...

ferret:/home/djc% python
Python 2.0.1 (#0, Jun 23 2001, 23:50:30)
[GCC 2.95.4 20010319 (Debian prerelease)] on linux2
Type "copyright", "credits" or "license" for more information.
>>> import Sybase
>>> dict = { 42: 'the answer' }
>>> n = Sybase.numeric(42)
>>> n.precision, n.scale
(16, 0)
>>> dict[n]
'the answer'
>>> n = Sybase.numeric('123456789012345678901234567890.123456789123456789')
>>> n.precision, n.scale
(49, 18)
>>> n
123456789012345678901234567890.123456789123456789
>>> n * 2
246913578024691357802469135780.246913578246913578
>>>

- Dave

--
http://www.object-craft.com.au

Ken Seehof

unread,
Jul 26, 2001, 8:02:03 PM7/26/01
to pytho...@python.org, Guido van Rossum

> --

This scares me. The whole numeric unification thing seems to be hiding
all the intrinsically difficult properties of numbers. Kind of like Windows
ME trying to hide all the intrinsically difficult properties of computers.

Hiding difficult properties usually makes those properties more difficult
in the long run, while appeasing beginners in the short run. This is not
a good trade off.

Here's some questions that come to mind that have a "sweep the can
of worms under the rug" theme:

1. If inexact numbers are excluded from being used as sequence indices,
won't there be a tendency for programs to have more special case bugs?
The value of a variable in a calculation might be usually exact, but inexact
once in awhile. So floats can be used as indices until there is a precision
error? Yikes! And I have a funny feeling in my stomach that this is just
the tip of the iceberg. Floats may or may not turn out to be exact
depending
on details of a particular run. This is a Bad Thing. Integers are always
exact. This is a good thing.

2. Wouldn't a function in an extension module that takes a number as an
argument be significantly more difficult to write, since it would have
figure out the actual runtime type of the number and deal with all the
different cases? Right now, I just have to verify the type. Seems like
even if you somehow solve the problem of breaking python code, you
will break extension code badly. One thing I like about python is that
it is highly compatible with its extension language. The further we get
from the current symmetry between python and C/C++ the harder it
will be to write extensions. The same goes for case sensitivity BTW.

3. Why do you expect it to be wise to hide all the numeric issues under
a level of abstraction? The issues will still exist, but will just be more
obscure. Right now, we have a simple and explicit numeric system with
simple and well understood problems. Trying to make it simpler for
beginners by adding complexity to the overall system won't work.

The basic fact is that all conceivable numeric systems suck badly for
different reasons, (including the one we currently have). And for every
problem there is a solution that's even worse. Just keep what we have.
It sucks less badly than all of the alternatives. Even the / operator has
it's virtues. It make integers a closed set with respect to all the basic
operators. This is a Good Thing. The grand unification of numbers is
the other way to try to create a closed set, so it's not surprising that the
1/2 debate eventually lead to it. But it won't work because the different
kinds of numbers really are different and trying to stuff them into the
same set is inherently unnatural. I'd accept 1/2 == 0.5 with 1//2 == 0
as the integer quotient operator, but going further than that is a mistake
IMHO.

Kinda-weird-that-computers-are-so-lousy-at-dealing-with-numbers-ly yrs,

- Ken

"Things should be made as simple as possible -- but no simpler."
- A. Einstein

Tim Hochberg

unread,
Jul 26, 2001, 10:04:36 PM7/26/01
to

"Ken Seehof" <ke...@sightreader.com> wrote :

[SNIP]


> 1. If inexact numbers are excluded from being used as sequence indices,
> won't there be a tendency for programs to have more special case bugs?
> The value of a variable in a calculation might be usually exact, but
inexact
> once in awhile. So floats can be used as indices until there is a
precision
> error? Yikes! And I have a funny feeling in my stomach that this is just
> the tip of the iceberg. Floats may or may not turn out to be exact
> depending
> on details of a particular run. This is a Bad Thing. Integers are always
> exact. This is a good thing.

You might want to read or reread PEP 228 (not 238). Exactness has nothing to
do with values and everything to with, well, exactness. Note that 228 is a
"pie in the skie" PEP and as such is fairly incomplete, but it may give you
a better idea what Guido was referring to.

Anyway, under the PEP 228 rules, a number would be exact if it was an
integer or rational (internally, there would externally be one number type)
and inexact if it were a float or complex-float. So floats would never be
able to be used as indices since they are inexact, by definition.

> 2. Wouldn't a function in an extension module that takes a number as an
> argument be significantly more difficult to write, since it would have
> figure out the actual runtime type of the number and deal with all the
> different cases? Right now, I just have to verify the type. Seems like
> even if you somehow solve the problem of breaking python code, you
> will break extension code badly. One thing I like about python is that
> it is highly compatible with its extension language. The further we get
> from the current symmetry between python and C/C++ the harder it
> will be to write extensions. The same goes for case sensitivity BTW.

I won't comment on case sensitivity, but don't nearly all arguments to
extensions go through PyArg_ParseTuple? Without thinking about it too much,
it seems like it would be a piece of cake to make that backwards compatible.
Did you have something specific in mind?

> 3. Why do you expect it to be wise to hide all the numeric issues under
> a level of abstraction? The issues will still exist, but will just be
more
> obscure. Right now, we have a simple and explicit numeric system with
> simple and well understood problems. Trying to make it simpler for
> beginners by adding complexity to the overall system won't work.

What specifically don't you like?

* Unification of ints and longs (PEP 237)? This seems almost impossible
to dislike.

* An addition of a rational type (PEP 239)? You might think this was
useless and argue against it on those grounds, but I can't see that would
inspire the horrified tone of the message above.

* Addition of a rational literal (PEP 240)? This one you could easily
dislike a lot. But if your really super concerned about the evils of
inexatitude, you'll probably like this more than I do.

Once you have allow PEPs 237 and 239 your 90% of the way to some variation
of PEP 228, you don't even really need 240.

Anyway I'm sure we'd all be much happier if everyone went to
python.sourceforge.net/peps, read all the number PEPs and then, if
necessary, panicked about what was actually in them.

-tim


David Eppstein

unread,
Jul 26, 2001, 10:16:37 PM7/26/01
to
In article <U_387.50579$Cy.65...@news1.rdc1.az.home.com>,
"Tim Hochberg" <tim.ho...@ieee.org> wrote:

> * Addition of a rational literal (PEP 240)? This one you could easily
> dislike a lot. But if your really super concerned about the evils of
> inexatitude, you'll probably like this more than I do.

Actually, I do dislike this. Much as I find floats generally useless, I
think that 0.666667 should return a float, and that if I want to write a
rational literal I should be able to write it as 2/3.

Also it is odd that the abstract discusses modifying division to return
rationals but that the rest of the PEP is entirely about what to do with
decimal strings.
--
David Eppstein UC Irvine Dept. of Information & Computer Science
epps...@ics.uci.edu http://www.ics.uci.edu/~eppstein/

Russell Wallace

unread,
Jul 26, 2001, 11:06:51 PM7/26/01
to
On 26 Jul 2001 15:50:15 +1200, Paul Foley <see@below> wrote:

>But rationals _are_ already in the language. Integers are rationals.
>"/" should definitely return an integer when the result can be
>represented in an integer. E.g., 4/2 should return 2, not 2.0.

The way it works right now is that the _type_ of the result depends on
the _type_ of the operands. You could argue about whether the specific
case of the current / operator is a bit too error prone, but generally
speaking this is reasonable behavior.

You want the _type_ of the result to depend on the _value_ of the
operands. My reaction to that is ***NO!!!*** It would make the
division operator for integer operands so error prone as to be
unusable. If that's the intent, much better to have it be an error to
use integer operands, that way you wouldn't get silently and
inconsistently wrong answers.

--
"How many roads must a man walk down?"
mailto:rwal...@esatclear.ie
http://www.esatclear.ie/~rwallace

Terry Reedy

unread,
Jul 26, 2001, 11:35:16 PM7/26/01
to
> [Guido]
> Well, they have the same *mathemtical* value, and Python does its
> darndest to treat them as equal everywhere. For example, a dict
with
> int keys can be indexed with corresponding float or complex values.
> Exceptions are operations that intrinsically require ints, e.g. list
> indexing. (This would change under a unified numeric system though,
I
> expect, unless inexact numbers are excluded from being used as
> sequence indices.)

If I write def(seq, n, k): return seq[3*n//k] and a call receives
n=20.0 instead of 20, it would accord with the polymorphic rationale
for new / and // to go ahead and return the item intended. Or perhaps
floored numbers should be marked as exact (if the marking is
independent of type).

Terry

Tim Peters

unread,
Jul 27, 2001, 12:10:43 AM7/27/01
to pytho...@python.org
[Terry Reedy]

> If I write def(seq, n, k): return seq[3*n//k] and a call receives
> n=20.0 instead of 20, it would accord with the polymorphic rationale
> for new / and // to go ahead and return the item intended. Or perhaps
> floored numbers should be marked as exact (if the marking is
> independent of type).

Type-based "exact vs inexact" schemes sound better than they're likely to
work, IMO.

Example:

x = 6.02e23 # reading as floating double, and presumably inexact
y = x // 1 # exact?!

y == x after those, but what sense would it make for y to be exact then?

Example:

y = w - w

Whether w is exact or inexact, it's certain that y is exactly 0 after that.
So the rule that "inexactness is always contagious" makes no sense (and,
indeed, the Scheme std leaves so many holes to accommodate cases "like this
one" that there's no guessing what will happen).

Example:

x = math.sqrt(4) # if inexact result, why?!

That is, even in float-land, sqrt(4) is just as exact as 4 is.

Scheme bit one part of this bullet so-far unchewed here: the idea that
floats are always inexact and ints always exact makes no sense either (I
worked 2 hours today and exchanged 1e3 pennies for a ten-dollar bill); so
Scheme has literal notations allowing to explictly say that an integer
literal is inexact, and that a floating literal is exact, when appropriate.

exactness-is-neither-a-type-nor-an-operation-property-ly y'rs - tim


Bengt Richter

unread,
Jul 27, 2001, 6:35:50 AM7/27/01
to
On Fri, 27 Jul 2001 03:35:16 GMT, "Terry Reedy" <tjr...@home.com> wrote:

>> [Guido]
>> Well, they have the same *mathemtical* value, and Python does its
>> darndest to treat them as equal everywhere. For example, a dict
>with
>> int keys can be indexed with corresponding float or complex values.
>> Exceptions are operations that intrinsically require ints, e.g. list
>> indexing. (This would change under a unified numeric system though,
>I
>> expect, unless inexact numbers are excluded from being used as
>> sequence indices.)

I think they should be, but IMHO linking exactness to representation
types will lead to trouble, unless you reserve float for numbers you
really have to approximate, and rework all floating point literals
so they don't cause artificial inexactness by being unnecessarily
represented as floats. I.e., convert 2.0 to an exact 2, not a float.
Convert 2.5 to rational 25/10, or 5/2, not a float. Etc. That throws
out a lot of good uses for exact floats though.


>
>If I write def(seq, n, k): return seq[3*n//k] and a call receives
>n=20.0 instead of 20, it would accord with the polymorphic rationale
>for new / and // to go ahead and return the item intended. Or perhaps
>floored numbers should be marked as exact (if the marking is
>independent of type).
>

ISTM floor couldn't make an exact number out of an inexact one unless the
inexactness was known to be constrained to the halfopen interval above
the floor. OTOH, IMHO 20.0 should not be viewed as inexact just because it is
a conventional literal for a floating point representation of 20
(end of sentence ;-). So if it were exact, floor(20.0) would also be exact.

Here's another one. What if you were simulating white noise within an interval,
and you wanted to check on it by counting instances generated that fell in
sub-intervals. Scaling the sub-intervals to width 1.0 and using floor would
be a natural way of getting an index to bins for counting. So one way or
another, there has to be a way to make the floored values exact for the purpose
of indexing. Floor values really are integers, mathematically. They could be
returned as such in a unified number system. But if so, it would be incorrect
to call them exact just because they were integers. To say ok, we'll return
floats is no better. The point is exactness ought to be representation-independent.
floor(4.0 - inexactnessEpsilon) => 3 #not an exact integer because of its heritage.

For practical purposes, the common case ought to be easy to write and fast executing.
Here I think that means indexing should automatically do floor and and raise an
exception if it got inexact inputs. However, when you know you are generating indices
from inexact sources, there should be a way of explicitly coercing exactness on
any number, so you can use the result of floor etc where exactness is required.
If float is reserved for only inexacts, then floor should definitiely return an integer,
not a float, unless it had an inexact input. Blech. All this is implementation talk,
not language talk. exactness is a language key concept for numbers. float is a
foreign-function/foreign-data issue for the language, or perhaps an optimization hint,
but not central, IMHO.

Please see my Number Tree post for more on representation ;-)

Robin Becker

unread,
Jul 27, 2001, 3:52:17 AM7/27/01
to
In article <U_387.50579$Cy.65...@news1.rdc1.az.home.com>, Tim Hochberg
<tim.ho...@ieee.org> writes
....

> * Unification of ints and longs (PEP 237)? This seems almost impossible
>to dislike.
....

well I have at least one extension that requires 32 bit unsigned as
inputs. Under existing python I can manipulate myself around bit 31
problems with ease (using negative numbers or hex). It seems it
will/might be a bit more complicated if this pep goes through. I'm sure
there are others who have explicit int size requirements. Effectively
removing ints takes away ease of external communication in at least some
cases.



>Anyway I'm sure we'd all be much happier if everyone went to
>python.sourceforge.net/peps, read all the number PEPs and then, if
>necessary, panicked about what was actually in them.
>
>-tim
>
>
>
>

--
Robin Becker

Guido van Rossum

unread,
Jul 27, 2001, 8:54:13 AM7/27/01
to Ken Seehof, pytho...@python.org
[Ken Seehof, on the new numeric system]

> This scares me. The whole numeric unification thing seems to be hiding
> all the intrinsically difficult properties of numbers. Kind of like Windows
> ME trying to hide all the intrinsically difficult properties of computers.

But that's what Python is trying to do anyway -- hide all the
uninteresting complications, like word size, byte order, memory
allocation, data types...

> Hiding difficult properties usually makes those properties more difficult
> in the long run, while appeasing beginners in the short run. This is not
> a good trade off.

The fact that you like Python so much suggests otherwise, if the
hiding is done right.

> Here's some questions that come to mind that have a "sweep the can
> of worms under the rug" theme:
>

> 1. If inexact numbers are excluded from being used as sequence indices,
> won't there be a tendency for programs to have more special case bugs?
> The value of a variable in a calculation might be usually exact, but inexact
> once in awhile. So floats can be used as indices until there is a precision
> error? Yikes! And I have a funny feeling in my stomach that this is just
> the tip of the iceberg. Floats may or may not turn out to be exact
> depending
> on details of a particular run. This is a Bad Thing. Integers are always
> exact. This is a good thing.

Assuming we'll adopt a variation of Scheme's numerical tower (which
I'm currently in favor of, more or less), this won't happen. Floats
and complex would always be considered inexact (and ints and rationals
exact), and inexact numbers are not allowed as sequence indices, even
if their exact value is an integer.

In fact, the rules won't change much: 1000000*1000000 will return
1000000000000 rather raising an OverflowError, and *maybe* (that is
still to be decided) 1/2 will return a rational instead of a float,
but

> 2. Wouldn't a function in an extension module that takes a number as an
> argument be significantly more difficult to write, since it would have
> figure out the actual runtime type of the number and deal with all the
> different cases? Right now, I just have to verify the type. Seems like
> even if you somehow solve the problem of breaking python code, you
> will break extension code badly. One thing I like about python is that
> it is highly compatible with its extension language. The further we get
> from the current symmetry between python and C/C++ the harder it
> will be to write extensions. The same goes for case sensitivity BTW.

Have you written many extension modules? Getting an argument
typically specifies the desired C type, and PyArg_ParseTuple()
converts the Python object to the right value, or raises an
exception. This mechanism already accepts multiple types, and you
won't have to change a thing.

> 3. Why do you expect it to be wise to hide all the numeric issues under
> a level of abstraction? The issues will still exist, but will just be more
> obscure. Right now, we have a simple and explicit numeric system with
> simple and well understood problems. Trying to make it simpler for
> beginners by adding complexity to the overall system won't work.

Most of the issues I plan to hide are simply nuisances, not inrinsic
complications. Float arithmetic will work exactly as before, except
maybe we'll call it inexact arithmetic. Int arithmetic will work
exactly as before, except you won't have to worry about overflow.

> The basic fact is that all conceivable numeric systems suck badly
> for different reasons, (including the one we currently have). And
> for every problem there is a solution that's even worse. Just keep
> what we have. It sucks less badly than all of the alternatives.
> Even the / operator has it's virtues. It make integers a closed set
> with respect to all the basic operators. This is a Good Thing.

Here opinions differ.

> The grand unification of numbers is the other way to try to create a
> closed set, so it's not surprising that the 1/2 debate eventually
> lead to it. But it won't work because the different kinds of
> numbers really are different and trying to stuff them into the same
> set is inherently unnatural. I'd accept 1/2 == 0.5 with 1//2 == 0
> as the integer quotient operator, but going further than that is a
> mistake IMHO.

Sounds like FUD to me. Wait until we have worked out the real
proposal. In the mean time, look at Scheme's rules:

http://www.swiss.ai.mit.edu/ftpdir/scheme-reports/r5rs-html/r5rs_8.html#SEC50

> Kinda-weird-that-computers-are-so-lousy-at-dealing-with-numbers-ly yrs,

Wait till you rely on them for dealing with words. :-)

> "Things should be made as simple as possible -- but no simpler."
> - A. Einstein

That has always been Python's unofficial motto, and it's not going to
change.

I hate to say "trust me" because I don't know why you should, but I
really do mean it. Trust me.

Guido van Rossum

unread,
Jul 27, 2001, 9:33:58 AM7/27/01
to
David Eppstein <epps...@ics.uci.edu> writes:

> In article <U_387.50579$Cy.65...@news1.rdc1.az.home.com>,
> "Tim Hochberg" <tim.ho...@ieee.org> wrote:
>
> > * Addition of a rational literal (PEP 240)? This one you could easily
> > dislike a lot. But if your really super concerned about the evils of
> > inexatitude, you'll probably like this more than I do.
>
> Actually, I do dislike this. Much as I find floats generally useless, I
> think that 0.666667 should return a float, and that if I want to write a
> rational literal I should be able to write it as 2/3.

I think you're right. An early version of ABC worked like this, and
at the time I though "hmm, but why shouldn't 0.98 be an exact number;
it could be intended as a price or something like that", and I
convinced the team to change it. But in practice it was more often
annoying. Now maybe that was because we (the biggest users) were CS
and math folks, and we tended to tackle typical math and CS problems
-- but my gut is to vote against this aspect of the PEP.

> Also it is odd that the abstract discusses modifying division to
> return rationals but that the rest of the PEP is entirely about what
> to do with decimal strings.

Most of the numeric PEPs need to be rewritten to give more motivation
and more choices and more details, but that's a lot of work... Want
to help?

Guido van Rossum

unread,
Jul 27, 2001, 9:37:51 AM7/27/01
to
rwal...@esatclear.ie (Russell Wallace) writes:

> You want the _type_ of the result to depend on the _value_ of the
> operands. My reaction to that is ***NO!!!*** It would make the
> division operator for integer operands so error prone as to be
> unusable. If that's the intent, much better to have it be an error to
> use integer operands, that way you wouldn't get silently and
> inconsistently wrong answers.

That all depends on details of the number system, and details of the
values involved. If we have rationals in our numeric tower, I
definitely want (5/2 - 3/2) to be usable as a sequence index, so
either rationals must be usable as sequence indices as long as their
value is integral, or the result of rational arithmetic may return an
int. That shouldn't matter.

On the other hand, floats should never be usable as sequence index.
Scheme defines this quite nicely:

http://www.swiss.ai.mit.edu/ftpdir/scheme-reports/r5rs-html/r5rs_8.html#SEC50

Guido van Rossum

unread,
Jul 27, 2001, 9:38:47 AM7/27/01
to
"Terry Reedy" <tjr...@home.com> writes:

> If I write def(seq, n, k): return seq[3*n//k] and a call receives
> n=20.0 instead of 20, it would accord with the polymorphic rationale
> for new / and // to go ahead and return the item intended. Or perhaps
> floored numbers should be marked as exact (if the marking is
> independent of type).

Good point. What does Scheme do?

Guido van Rossum

unread,
Jul 27, 2001, 9:50:34 AM7/27/01
to
bo...@accessone.com (Bengt Richter) writes:

> I think they should be, but IMHO linking exactness to representation
> types will lead to trouble, unless you reserve float for numbers you
> really have to approximate, and rework all floating point literals
> so they don't cause artificial inexactness by being unnecessarily
> represented as floats. I.e., convert 2.0 to an exact 2, not a float.
> Convert 2.5 to rational 25/10, or 5/2, not a float. Etc. That throws
> out a lot of good uses for exact floats though.

Hm... We did that in ABC, and it was my idea, and it didn't work out
there. See another post of mine.

> ISTM floor couldn't make an exact number out of an inexact one
> unless the inexactness was known to be constrained to the halfopen
> interval above the floor.

Good point.

> OTOH, IMHO 20.0 should not be viewed as
> inexact just because it is a conventional literal for a floating
> point representation of 20 (end of sentence ;-). So if it were
> exact, floor(20.0) would also be exact.

Big "if", see above.

> Here's another one. What if you were simulating white noise within
> an interval, and you wanted to check on it by counting instances
> generated that fell in sub-intervals. Scaling the sub-intervals to
> width 1.0 and using floor would be a natural way of getting an index
> to bins for counting. So one way or another, there has to be a way
> to make the floored values exact for the purpose of indexing.

So use int(floor(x)).

> Floor values really are integers, mathematically. They could be
> returned as such in a unified number system. But if so, it would be
> incorrect to call them exact just because they were integers. To say
> ok, we'll return floats is no better. The point is exactness ought
> to be representation-independent. floor(4.0 - inexactnessEpsilon)
> => 3 #not an exact integer because of its heritage.

*Conceptually*, exactness is independent from representation.
*Practically*, I think it makes sense to represent all exact numbers
as (unbounded precision) ints or rationals, and all inexact numbers as
doubles.

> For practical purposes, the common case ought to be easy to write
> and fast executing. Here I think that means indexing should
> automatically do floor and and raise an exception if it got inexact
> inputs.

Unclear. That would be breaking with tradition in Python; it would
probably cause lots of off-by-one errors. Scheme requires exact
indices, and declares that inexactness is contagious, except maybe in
some special cases, e.g. multiplying an inexact number by an exact
zero *may* return an exact zero in Scheme. (But there should be an
exception to this exception if the inexact number was infinity, as can
happen with Python floating point on most platforms.)

> However, when you know you are generating indices from
> inexact sources, there should be a way of explicitly coercing
> exactness on any number, so you can use the result of floor etc
> where exactness is required. If float is reserved for only
> inexacts, then floor should definitiely return an integer, not a
> float, unless it had an inexact input.

Right -- floor of a rational should return an exact integer.

But note that we don't have a floor function in Python now -- all we
have is math.floor(), and the math functions are defined to always
return a float.

> Blech. All this is implementation talk, not language talk. exactness
> is a language key concept for numbers. float is a
> foreign-function/foreign-data issue for the language, or perhaps an
> optimization hint, but not central, IMHO.
>
> Please see my Number Tree post for more on representation ;-)

Please see the Scheme docs:

http://www.swiss.ai.mit.edu/ftpdir/scheme-reports/r5rs-html/r5rs_8.html#SEC50

Guido van Rossum

unread,
Jul 27, 2001, 9:53:25 AM7/27/01
to
Robin Becker <ro...@jessikat.fsnet.co.uk> writes:

> well I have at least one extension that requires 32 bit unsigned as
> inputs. Under existing python I can manipulate myself around bit 31
> problems with ease (using negative numbers or hex). It seems it
> will/might be a bit more complicated if this pep goes through. I'm sure
> there are others who have explicit int size requirements. Effectively
> removing ints takes away ease of external communication in at least some
> cases.

This is easily solved by taking the result modulo 2**32. Python
extensions with unsigned 32-bit inputs or outputs generally Python
longs.

Tim Hochberg

unread,
Jul 27, 2001, 10:11:19 AM7/27/01
to

"Guido van Rossum" <gu...@python.org> :

> "Terry Reedy" <tjr...@home.com> writes:
>
> > If I write def(seq, n, k): return seq[3*n//k] and a call receives
> > n=20.0 instead of 20, it would accord with the polymorphic rationale
> > for new / and // to go ahead and return the item intended. Or perhaps
> > floored numbers should be marked as exact (if the marking is
> > independent of type).
>
> Good point. What does Scheme do?


Floor, ceiling, truncate and round all return integers. It seems that it
wouldn't really be possible to have // do that consistently without PEP 237
though.

-tim


Tim Hochberg

unread,
Jul 27, 2001, 10:24:12 AM7/27/01
to

"Guido van Rossum" <gu...@python.org>:

> bo...@accessone.com (Bengt Richter) writes:
> > ISTM floor couldn't make an exact number out of an inexact one
> > unless the inexactness was known to be constrained to the halfopen
> > interval above the floor.
>
> Good point.

I guess the question becomes, does "exactness" mean just precision, or both
precision and accuracy. The result of floor is infinitely precise, but it's
accuracy is potentially suspect.

It seems that any[1] operation that converts imprecise numbers to precise
numbers is going to have this problem , so it seems best just to define
"exactness" to be "infinite precision" and live with the consequences.


-tim


[1] I suppose you could map all numbers to a constant and I suppose that
wouldn't have any accuracy problems, but it's not very interesting.


"Jürgen A. Erhard"

unread,
Jul 27, 2001, 6:32:07 AM7/27/01
to tim...@home.com, pytho...@python.org
>>>>> "Tim" == Tim Peters <tim...@home.com> writes:

[...]

>> You're pissing off a fairly significant fraction of the
>> language's existing constituency in hopes of attracting some
>> non-programmers to the language who may not come anyway for
>> various other reasons.

BTW, Skip, as I said in another message, I'd dispute the "significant
fraction". Maybe it is, maybe it isn't... but volume doesn't make it
so.

Tim> I don't detect any trace of that hypothesized motive in
Tim> Guido. He wants to repair what he has come to believe is a
Tim> serious design error, and is wrestling with ways to get that
Tim> done. What a remarkably different world it would be if
Tim> people tried to help <wink>.

By pure coincidence[1], just a couple days ago I looked up info on
Ido, the "improved" version of Esperanto.

And, well, it's interesting that some of the stuff Ido does
differently than Esperanto are ideas that Zamenhof had, but didn't
change in Esperanto.

Funny how similar that looks to the / situation... is Guido an
improved Zamenhof in the end? ;-)

Bye, J

[1] I think. I'm not sure because I don't remember *why* I stumbled
upon Ido. Could have been mentioned around here...

--
Jürgen A. Erhard (juergen...@gmx.net, j...@users.sourceforge.net)
MARS: http://members.tripod.com/Juergen_Erhard/mars_index.html
"It might look like I'm doing nothing, but at the cellular level
I'm really quite busy."

--pgp-sign-Multipart_Fri_Jul_27_12:31:39_2001-1
Content-Type: application/pgp-signature
Content-Transfer-Encoding: 7bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iEYEABECAAYFAjthQxIACgkQN0B+CS56qs2RrACeLL2ohUX34AaqfOX2HRf70rtk
6aYAnRbhDItbQZshzIpHCriGo49dNdxP
YzGl
-----END PGP SIGNATURE-----

--pgp-sign-Multipart_Fri_Jul_27_12:31:39_2001-1--

Marcin 'Qrczak' Kowalczyk

unread,
Jul 27, 2001, 11:49:05 AM7/27/01
to
28 Jul 2001 02:17:57 +1200, Paul Foley <see@below> pisze:

> Paul> The most obvious problem is that it implies that every rational
> Paul> can be represented as a float -- this is *severe* brokenness you
> Paul> don't need. [I think it also implies that floats with integral
> Paul> values (1.0, etc.) should turn into integers.]
>
>> You can't do that. Suppose that value you think is 1.0 really got truncated
>
> Yeah; that's exactly my point!

But my model never treats a float as an integer, even if it's equal
to 1.0. Where does it give a wrong answer? It doesn't claim that
rationals are exactly representable as floats and doesn't implicitly
turn floats into rationals. What's wrong with it?

--
__("< Marcin Kowalczyk * qrc...@knm.org.pl http://qrczak.ids.net.pl/
\__/
^^ SYGNATURA ZASTĘPCZA
QRCZAK

Russell Wallace

unread,
Jul 27, 2001, 4:33:27 PM7/27/01
to
On Fri, 27 Jul 2001 13:37:51 GMT, Guido van Rossum <gu...@python.org>
wrote:

>That all depends on details of the number system, and details of the
>values involved. If we have rationals in our numeric tower, I
>definitely want (5/2 - 3/2) to be usable as a sequence index, so
>either rationals must be usable as sequence indices as long as their
>value is integral, or the result of rational arithmetic may return an
>int. That shouldn't matter.

Right.

>On the other hand, floats should never be usable as sequence index.

Ah, yes, we're agreed on both counts then :)

>Scheme defines this quite nicely:

*nod* I always thought Scheme has one of the most elegant number
systems of any programming language.

Bengt Richter

unread,
Jul 27, 2001, 5:06:19 PM7/27/01
to
On Fri, 27 Jul 2001 08:54:13 -0400, Guido van Rossum <gu...@zope.com> wrote:
[...]

>Assuming we'll adopt a variation of Scheme's numerical tower (which
>I'm currently in favor of, more or less), this won't happen. Floats
>and complex would always be considered inexact (and ints and rationals
>exact), and inexact numbers are not allowed as sequence indices, even
>if their exact value is an integer.
>
Why would complex have to be inexact if both its
real and imaginary parts were exact?

This looks exact, but will it be?
>>> (1+2j)**2
(-3+4j)

Guido van Rossum

unread,
Jul 27, 2001, 5:43:51 PM7/27/01
to
bo...@accessone.com (Bengt Richter) writes:

Probably not -- I don't think it's worth to have a separate exact and
inexact complex numbers, especially since exact numbers will probably
be represented as rationals (with ints and long ints as a special-case
optimization), while inexact numbers will probably all use some form
of floating point (binary or decimal).

David Bolen

unread,
Jul 27, 2001, 5:44:31 PM7/27/01
to
Robin Becker <ro...@jessikat.fsnet.co.uk> writes:

> well I have at least one extension that requires 32 bit unsigned as
> inputs. Under existing python I can manipulate myself around bit 31
> problems with ease (using negative numbers or hex). It seems it
> will/might be a bit more complicated if this pep goes through. I'm sure
> there are others who have explicit int size requirements. Effectively
> removing ints takes away ease of external communication in at least some
> cases.

If implemented cleanly, it may even make live easier for your
extension, depending on how its functions process input, since they'll
all still come in as PyObject's.

For example, if your extension uses PyArg_ParseTuple to convert to the
Python value to your internal 32 bit unsigned storage, it'll probably
still continue to do so, automatically taking into account any
unification within the Python core. In fact one could imagine the "l"
format (which presumably you're using now since 'int' wouldn't be a
portable ubit32 format in your C extension) would automatically handle
all of integers, longs, or integral floats behind the scenes. You'd
then do a final sanity check to ensure the value was within 32-bits,
but presumably you do that now as well. If, instead, you're using "i"
today and just giving it a pointer to an 'unsigned int' variable,
you're already being a bit risky in your extension coding, but that
should presumably continue to work as well, and presumably Python
would complain when trying to convert a number that wouldn't fit into
the platform 'int'.

--
-- David
--
/-----------------------------------------------------------------------\
\ David Bolen \ E-mail: db...@fitlinxx.com /
| FitLinxx, Inc. \ Phone: (203) 708-5192 |
/ 860 Canal Street, Stamford, CT 06902 \ Fax: (203) 316-5150 \
\-----------------------------------------------------------------------/

It is loading more messages.
0 new messages