On Thu, Mar 5, 2020 at 11:09 AM Todd <toddrjen@gmail.com> wrote:
On Thu, Mar 5, 2020 at 4:27 AM Steve Barnes <GadgetSteve@live.co.uk> wrote:


SNIP 

 

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

``




If you were going to do this you would probably need something like a context manager to control the scope, such as:

with TreatFloatsAsDecimal:
    a = 0.1  # decimal
    b = 0.2  # decimal
    c = 0.3  # decimal

d = 0.3  # float

I have been interested in something like this in the context of numpy arrays, but I am not sure even that would even be possible under how the python language works, and if it was I figured it was too complicated to be worthwhile. 

I like this example; I will refer to it below.

I really think that anyone proposing new syntax construct would really benefit from being able to "play" with it, being able to write and run such currently invalid Python syntax.  As I alluded to in previous emails (and as quite a few others did for years on this list), once you have a working example of an import hook (or custom encoding), in some cases, it can actually be quite straightforward to write the code needed to transform a proposed syntax into valid Python code.  So, in addition to my previous example, I will give two more, copied verbatim from my terminal.

Note: these two examples have not been included in the ideas repository (nor on the Pypi version).  Also, I show code in a console, but it could be in a script run via an import statement.

Example 1:

    >>> from ideas.examples import decimal_math_d
    >>> hook = decimal_math_d.add_hook()
    >>> from ideas import console
    >>> console.start()
    Configuration values for the console:
        source_init from ideas.examples.decimal_math_d
        transform_source from ideas.examples.decimal_math_d
    --------------------------------------------------
    Ideas Console version 0.0.15. [Python version: 3.7.3]

    ~>> a = 0.1
    ~>> a
    0.1
    ~>> b = 0.1 D
    ~>> b
    Decimal('0.1')
    ~>> a + b
    Traceback (most recent call last):
      File "IdeasConsole", line 1, in <module>
    TypeError: unsupported operand type(s) for +: 'float' and 'decimal.Decimal'
    ~>> 1 + b
    Decimal('1.1')

The actual code to do the required transformation is very short and, I think, quite readable:

    def transform_source(source, **kwargs):
        """Simple transformation: replaces any explicit float followed by ``D``
        by a Decimal.
        """
        tokens = token_utils.tokenize(source)
        for first, second in zip(tokens, tokens[1:]):
            if first.is_number() and "." in first.string and second == "D":
                first.string = f"Decimal('{first.string}')"
                second.string = ""

        return token_utils.untokenize(tokens)


The second example (a fake context) was a bit trickier to write, but not that difficult:

    >>> from ideas.examples import decimal_math_with
    >>> hook = decimal_math_with.add_hook()
    >>> from ideas import console
    >>> console.start()
    Configuration values for the console:
        source_init from ideas.examples.decimal_math_with
        transform_source from ideas.examples.decimal_math_with
    --------------------------------------------------
    Ideas Console version 0.0.16. [Python version: 3.7.3]

    ~>> a = 1.0
    ~>> with float_as_Decimal:
    ...   b = 0.1
    ...   c = 0.2
    ...   d = 0.3
    ...
    ~>> e = 0.4
    ~>> b + c == d
    True
    ~>> b
    Decimal('0.1')
    ~>> a, e
    (1.0, 0.4)
    ~>> b, c, d
    (Decimal('0.1'), Decimal('0.2'), Decimal('0.3'))


Caveat: doing source transformations prior to execution like I do is definitely not as robust as having code parsed by a well-designed grammar-based parser.

Cheers,

André

 
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-leave@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/H346THCDRRIGRIAQUVVU2PHRVH6T5VSP/
Code of Conduct: http://python.org/psf/codeofconduct/