On Thu, Mar 5, 2020 at 11:09 AM Todd <toddr...@gmail.com> wrote:

> On Thu, Mar 5, 2020 at 4:27 AM Steve Barnes <gadgetst...@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-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/H346THCDRRIGRIAQUVVU2PHRVH6T5VSP/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
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/TEZXXQPUL7RQR5HNEQZ5YCEQASOMS6Z5/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to