[Python-ideas] User-defined literals
Chris Angelico
rosuav at gmail.com
Wed Jun 3 23:48:30 CEST 2015
On Thu, Jun 4, 2015 at 2:55 AM, Andrew Barnert <abarnert at yahoo.com> wrote:
> In Python, it's perfectly fine that -2 and 1+2j and (1, 2) are all compiled into expressions, so why isn't it fine that 1.2d is compiled into an expression? And, once you accept that, what's wrong with the expression being `literal_d('1.2')` instead of `Decimal('1.2')`?
>
That's exactly the thing: 1.2d should be atomic. It should not be an
expression. The three examples you gave are syntactically expressions,
but they act very much like literals thanks to constant folding:
>>> dis.dis(lambda: -2)
1 0 LOAD_CONST 2 (-2)
3 RETURN_VALUE
>>> dis.dis(lambda: 1+2j)
1 0 LOAD_CONST 3 ((1+2j))
3 RETURN_VALUE
>>> dis.dis(lambda: (1, 2))
1 0 LOAD_CONST 3 ((1, 2))
3 RETURN_VALUE
which means they behave the way people expect them to. There is no way
for run-time changes to affect what any of those expressions yields.
Whether you're talking about shadowing the name Decimal or the name
literal_d, the trouble is that it's happening at run-time. Here's
another confusing case:
import decimal
from fractionliterals import literal_fr
# oops, forgot to import literal_d
# If we miss off literal_fr, we get an immediate error, because
# 1/2fr gets evaluated at def time.
def do_stuff(x, y, portion=1/2fr):
try: result = decimal.Decimal(x*y*portion)
except OverflowError: return 0.0d
You won't know that your literal has failed until something actually
triggers the error. That is extremely unobvious, especially since the
token "literal_d" doesn't occur anywhere in do_stuff(). Literals look
like atoms, and if they behave like expressions, sooner or later
there'll be a ton of Stack Overflow questions saying "Why doesn't my
code work? I just changed this up here, and now I get this weird
error". Is that how literals should work? No.
ChrisA
More information about the Python-ideas
mailing list