[Python-Dev] PEP for adding a decimal type to Python
Michael McLay
mclay@erols.com
Fri, 27 Jul 2001 01:44:33 -0400
The PEP I posted yesterday, which currently doesn't have a number, addresses
the syntactic issues of adding a decimal number type to Python and it
investigates how to safely introduce the new type in a language with a large
base of legacy code. The PEP does not address the definition of how decimal
numbers should be implemented in Python. This topic has been the subject of
other PEPs.
The PEP also proposes the definition of a new language dialect that makes
some small improvements on the syntax of the classic Python language. The
changes to the numerical model is tailored to make the language attractive to
two very important markets. Many of the users attracted from these markets
may initially have little or no interest in classic Python. They may not
even know that the Python language exists. They will happily use a language
called dpython that works very well for their profession. The interesting
thing about the proposed language is how little effort will be required to
create and maintain it. The additions to Python were straightforward and the
total patch was only a few hundred lines.
The prototype implementation uses the following rules when interpreting the
type to be created from a number literal.
literal '.py' '.dp' interactive interactive
value file file python dpython
2.2b float float float float
2b int int int int
2.2 float decimal float decimal
2 int decimal int decimal
2.2d decimal decimal decimal decimal
2d decimal decimal decimal decimal
Based on a comment from Guido I've decided to change the 'f' to 'b' in the
next version of dpython. That will be more descriptive of the distinction
the types.
[Michael]
>> This was a proposal for a mechanism for mingling types safely. It
>> was not intended as a definition of how decimal numbers should be
>> implemented. My implementation tests the interaction of the current
>> number types with the decimal type and I only completed enough of
>> the decimal type implementation to support this testing. I was not
>> expecting to discuss how decimal types should work. That has been
>> discussed already. I was primarily interested in testing the effects
>> of adding a new number type as I described in the PEP.
> Can you summarize the rules you used for mixed arithmetic? I forget
> what your PEP said would happen when you add a decimal 1 to a binary
> 1. Is the result decimal 2 or binary 2? Why?
The rule is very simple. You can't mix the types. You must explicitly cast
a binary to a decimal or a decimal to a binary. This introduces the least
chance of error. This pedantic behavior is very important in fields like
accounting. I want accountants to think of the proposed dpython language as
the COBOL version of Python:-) This approach is also the correct one to take
for newbies. They will get a nice clean exception if they mix the types.
This error will be something they can easily look up in the documentation.
An unexpected answer, like 1/2=0, will just leave them scratching their head.
This proposal tries to be consistent with what I like about Python and what I
think makes Python a great language. The implementation maintains complete
backwards compatibility and it requires that programmers explicitly state
that they want to do something rather than have bad things happen
unexpectedly. Mixing different types of numbers can lead to bugs that are
very difficult to identify. The nature of the errors that would occur
when binary numbers are used instead of decimals would be particularly
difficult to detect. The answers would always be very close, and sometimes
they would be correct. Without the use of an explicit cast these errors
would be silent. The price paid for being pedantic will be the occasional
need to add an int() or float() around a decimal number or an decimal()
around a float or int.
>> What did you think of the idea of adding a new command and file format?
> I don't think that would be necessary. I'd prefer the 'd' and 'f' (or
> maybe 'b'?) suffixes to be explicit, perhaps combined with an optional
> per-module directive to set the default. This would be more robust
> than keying on the filename extension.
Why do you think a directive statement would be more robust than using a file
suffix or command name as the directive? I'll try to explain why I think the
opposite is true.
Take the example of teaching a newbie to program. They must be told some
basic things For instance, they will have only been told to use a specific
suffix for the file name in order to create a new module. So how do you make
sure that the newbie always uses decimal numbers? If a directive statement is
required then the newbie must remember to always add this statement at the
top of a file. If they forget they will not get the expected results. With
the file suffix based approach they will have to use a '.dp' suffix for the
file name of a new module. If the are told to use a '.dp' suffix from the
outset then the chances of their accidentally typing '.py' instead of '.dp'
is very unlikely, whereas, forgetting to add a directive would be a silent
error that they might easily forget.
Your request to have an explicit 'd' and 'f' is already implemented. The
prototype implementation allows an explicit 'd' or 'f' to be used at anytime.
The rules on the interpretation of the values that have no suffix were
defined earlier. The prototype implementation simply uses the suffix of the
module file and the name of the command as the directive. This approach
provides a very natural language experience to someone working in a
profession that normally uses decimal numbers. They are not treated as
second class citizens who must endure the clutter of a magic directive
statements at the top of every module they create. They just use their
special command and the file extension.
> If you have to change the
> default globally, I'd prefer a command line option. After all it's
> only the scanner that needs to know about the different defaults,
> right?
I think there would be a problem with only using a command line option. It
would work for files that are named on the command line and for code being
interpreted in an interactive session. However, for imported modules the
meaning of a number literal must be based on the author intentions when the
module was created. This means that the interpreter must recognize the type
of file so it can determine how compile the literals defined in the module.
If the command line option determines how a scanner is to convert the number
literals then a module source file could incorrectly be converted if the
wrong command line option were used.
> I wonder about the effectiveness of the default though. If you write
> a module for decimal arithmetic, how do you prevent a caller to pass
> in a binary number?
Since the module is written with decimal numbers an exception would be raised
if a binary number was used where a decimal number was required. For
instance:
---------------
#File spam.py
a = 1.0
---------------
#File eggs.dp
import spam
c = a + 1.0
---------------
The name 'a' was compiled into a float type object when the spam.py file was
scanned. So when the expression being assigned to 'c' is executed it would
result in an TypeError being raised because a float was being added to a
decimal.
>> decimalobject.c so I could test the impact of introducing an
>> additional command and file format to Python. I expect this code to
>> be replaced. As I said in the PEP I also think the decimal number
>> implementation will evolve into a type that supports inheritance.
> Please, please, please, unify all these efforts. A decimal PEP would
> be a good one, but there should be only one.
Absolutely. The PEP process is suppose to formalize the capture of ideas so
they can be reference. This PEP is mostly orthogonal to Aahz's proposal.
They can be merge, or we can reference each others PEP. I'm probably not the
best choice for doing the implement of the decimal number semantics, so I'd
be happy to work with Aahz.