> On Mar 5, 2020, at 01:27, Steve Barnes <gadgetst...@live.co.uk> wrote:
> One of the lovely things about Python is that we have the capability to avoid 
> issues such as the vagaries of the floating point type with libraries such as 
> decimal and fractions. This is wonderous to me but comes with an issue that I 
> suspect is limiting its usage. That issue is that you have to litter your 
> code with constructors of those types, e.g.
> 
>  
> 
> ```
> 
> a = 0.1
> 
> b = 0.2
> 
> c = 0.3
> 
> a + b == c # This doesn’t work but it is easy to forget why
> 
> ```
> 
> vs:
> 
> ```
> 
> from decimal import *  # I know why this is bad but it comes straight from 
> the examples
> 
> a = Decimal("0.1")  # Needs to be a string to avoid being temporarily a float
> 
> b = Decimal("0.2")  # Ditto
> 
> c = Decimal("0.3")  # Ditto
> 
> a + b == c  # Magic this works!
> 
> ```
> 
>  
> 
> While this works it is not very friendly to users and there will often be 
> cases where people forget to quote the values, etc. and there are similar 
> issues with using the fractions library and I am sure with others. I suspect 
> that this is why the decimals library, and some others, is not used as widely 
> as it possibly should be.
> 
>  
> 
> Wouldn’t it be possible to have something along the lines of:
> 
>  
> 
> ```
> 
> from decimal import TreatFloatsAsDecimal
> 
> @TreatFloatsAsDecimal
> 
> a = 0.1  # These are all now decimals
> 
> b = 0.2
> 
> c = 0.3
> 
> a + b == c # This now works
> 
> ```
> 
I don’t think this could work, because assignment doesn’t have anything magic 
you can hook in an obvious way.

Also, you can’t turn all float _values_ into decimals without losing all the 
benefits of Decimal. What you want is to turn all float _literals_ into decimal 
literals. Which is definitely doable. See 
https://github.com/abarnert/floatliteralhack for some inspiration, and maybe 
https://github.com/abarnert/userliteralhack. But of course if this is built 
into the compiler rather than being an import hook, it wouldn’t have to be 
hacky like those examples.

What you want is some kind of syntax that marks a context—presumably either a 
block or a scope, so a magic with statement or a decorator might be sufficient, 
or at least sufficient for a proof of concept:

    with TreatFloatsAsDecimals:
        assert 1.0 + 2.0 == 3.0

This would be a real context manager, but also be magical, in the same way that 
__future__ is a real module but also magical.

However, I think adding user-defined suffixes, or maybe just one new hardcoded 
suffix D, is a better way to handle this:

    assert 1.0D + 2.0D == 3.0D
    assert 1.0 + 2.0 != 3.0
> I do know that this goes against the explicit is better than implicit so an 
> alternative might be to have a flexible base modifier, something like:
> 
> ```
> 
> from decimal import DecimalBase as D
> 
>  
> 
> a = 0D0.1  # These are all now decimals
> 
> b = 0D0.2
> 
> c = 0D0.3
> 
> a + b == c # This now works
> 
That’s an interesting variant on suffixes or prefixes, because it leverages an 
existing prefix that at least some number literals already handle. I suspect it 
has the same implementation issues—the real questions are (1) how to get that D 
into some scope that the compiler can look up at compile time or emit code to 
defer to at runtime, and (2) which of those two it should do. Look over any of 
the past threads on user-defined affixed for lots of argument.
> Since anything like this would require overriding at least part of the base 
> interpreter I do not think that this is a suitable one for an external PyPi 
> library or at least some hooks in the interpreter would be required to make 
> it possible.
> 
Python already has an import hook mechanism, and mechanisms to run each stage 
of the compilation process manually (except tokens to AST, but it has tokenize 
and untokenize that can be used to fake that), and a way to easily create a 
pre-hooked REPL, which together are all you need to write this as an external 
library.

In fact, this seems almost tailor made as a perfect first use case for André’s 
ideas import-hook-helper library: https://github.com/aroberge/ideas

_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/JISE3VI42OPIYU4YBORM66AX4S7IYE5M/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to