Proposal: Magic Constants

C

Chris Gonnerman

A while back (a long while actually) I was a
participant in a long argument over decimal and
rational numbers, and their inclusion into the
core of Python.

Last night in a dream I came up with an
interesting solution (no, really!) which, in the
cold light of morning, still seems pretty cool.

The gist is this: Constants would be allowed to
be trailed by any single alphabetic character.
When compiled, a constant with a nonstandard
letter code would be stored in the compiled code
in the form of a text literal, appropriately
marked.

When the code is executed, and the special
literal is processed, the interpreter would look
up a conversion function in an internal list. If
no conversion is found, a runtime error would be
raised.

Modules to handle alternate numeric formats, such
as decimal, fixed-point, rational, etc. would
include a call to a builtin registration function
which would allow them to "take over" a specific
alphabetic specifier.

So, to use a supposed Decimal.py module, one
would do thusly:

"decimal arithmetic example"

import Decimal

a = 1.05D

and so on.

Limitations: The literal would be required by
the compiler to match the format of a real number
(float or integer); the conversion function could
raise its own runtime error if the text string
were out of its range. So, to write a rational
number:

"rational arithmetic example"

import Rational

b = 1R/15

Note that the 1R is actually the rational 1/1,
whereas the 15 is an integer; the division sign
is not part of the rational here, but actually
indicates division. The result would be the
rational 1/15, which is assigned to the variable
b.

The only other disadvantage I can see is that a
small class of syntax errors become runtime
errors. I'm don't think this is a major thing
though.

Thoughts and opinions welcome...

Chris Gonnerman -- (e-mail address removed)
http://newcenturycomputers.net
 
B

Bernhard Herzog

John Roth said:
There's another namespace with a possibility
of collisions here, and also the same old "we
can't make one of these a builtin because it
might break user code."

This could be alleviated by doing something similar to how metaclasses
can be specified at the module level. Put a dictionary mapping suffixes
to constructors into a module level variable called e.g. __literals__ so
that you'd either do it by hand like this:

__literals__ = {"r": Rational}

or if you only need e.g. rational literals in your module could do

from rational import __literals__

Assuming the rational module provides a suitable dictionary for the
user's convenience.
One overall thought: why limit it to numbers?
The new datetime module would benefit from
a datetime literal, but that would have to be
a character string.

Indeed.

Allowing this for strings would also provide a way to get self
interpolating string literals because the constructor could use
introspection to get a dictionary with all local variables in the
calling scope.
Another thing to think about is whether
this could cause problems with existing
code. I can't immediately think of a case
where a literal can be next to a character,

I think "1.or 2" would have to produce a syntax error under the new
rules.


Bernhard
 
R

Robert Kern

[snip]
Another thing to think about is whether
this could cause problems with existing
code. I can't immediately think of a case
where a literal can be next to a character,
but I'm also not a real deep authority on all
of the oddities of Python syntax.
10L
0X
1e+10
10j

John Roth

--
Robert Kern
(e-mail address removed)

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter
 
R

Raymond Hettinger

[Chris Gonnerman]
The gist is this: Constants would be allowed to
be trailed by any single alphabetic character.
When compiled, a constant with a nonstandard
letter code would be stored in the compiled code
in the form of a text literal, appropriately
marked.

When the code is executed, and the special
literal is processed, the interpreter would look
up a conversion function in an internal list. If
no conversion is found, a runtime error would be
raised.

Modules to handle alternate numeric formats, such
as decimal, fixed-point, rational, etc. would
include a call to a builtin registration function
which would allow them to "take over" a specific
alphabetic specifier.

-1

This should not be done for several reasons:

* Constructors are more explicit: Rational(12, 3)

* The appearance unpleasantly reminds me of VB

* There are potential conflicts between alphabetic specifiers which
results in hard to spot bugs. Doest "1.25D" represent the
decimal class, Dewey decimals, or US dollars?

* Previous discussions on special syntaxes initially found them
to be enticing and then someone would realize that real programs
rarely have more than a handful of constants that would benefit
from the syntax. For instance, an accounting program is not
filled with specific values like $1.83. Instead, it constructs
nearly all of its data from user input or files. The program itself
likely checks for zero and amounts being under $1.00. Those
constants are easily and explicitly codeable with a normal
constructor: Decimal("1.00", 2) or some such.

* The registration process by-passes Python's elegant namespaces
and makes global changes resulting in hard to diagnose effects:

import bookaccounting # Hmm, did this just set D to DeweyDecimal?
import Decimal # Did this just reset the value of D or
was it F?
. . .
if foreign_currency:
import Francs
val = 15F # Was this the original F (for Fixed)
or the
# new F (for Francs) ?
# Does it automatically convert
from Euros?

* Guido is already uncomfortable with the number of kinds of string literals:
'abc', u'abc', ur'abc', r'abc', etc. He is unlikely to adopt any related
ideas
for numbers.

Other than that, it is a great idea ;-)


Raymond Hettinger
 
M

Michael Hudson

John Roth said:
But these are existing literal syntax. I was thinking
more of random code where someone could currently
juxtapose a literal and an identifier, say, without an
intervening white space character.
5

Very much a wart of the tokenizer, though.

Cheers,
mwh
 
J

John Roth

Michael Hudson said:
5

Very much a wart of the tokenizer, though.

Ah, right. I forgot about alphabetic operators.

Why do you call it a wart, though? I would have
thought that not requiring white space in that context
was a feature.

John Roth
 
R

Raymond Hettinger

But these are existing literal syntax. I was thinking
Ah, right. I forgot about alphabetic operators.

Why do you call it a wart, though? I would have
thought that not requiring white space in that context
was a feature.

Because the human eye/mind parses 10and as single a token.


Raymond Hettinger
 
M

Michael Hudson

John Roth said:
Ah, right. I forgot about alphabetic operators.

Why do you call it a wart, though? I would have
thought that not requiring white space in that context
was a feature.

Well, it's just odd. I'm pretty sure it's not intentional, and fairly
sure it's not documented. I don't care enough to check, though :)

Cheers,
mwh
 
J

John Roth

Raymond Hettinger said:
Because the human eye/mind parses 10and as single a token.

Well, to be truthful about it, I'd just as soon require white
space between all tokens except for the delimiter types.
However, that's not going to happen because of the backwards
compatability issues.

John Roth
 
J

John Roth

Michael Hudson said:
Well, it's just odd. I'm pretty sure it's not intentional, and fairly
sure it's not documented. I don't care enough to check, though :)

The whitespace rule (from the Python Language Reference Manual)
is:

[begin excerpt LRM 2.1.8 in Python 2.2.3]
Except at the beginning of a logical line or in string literals, the
whitespace characters space, tab and formfeed can be used interchangeably to
separate tokens. Whitespace is needed between two tokens only if their
concatenation could otherwise be interpreted as a different token (e.g., ab
is one token, but a b is two tokens).
[end excerpt]

John Roth
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,100
Messages
2,570,633
Members
47,239
Latest member
LorrineHor

Latest Threads

Top