Hi Steven,

> Python is never going to look good for symbolic maths, because symbolic 
> maths is a two-dimensional layout and Python (like most programming 
> languages) is line-oriented in a way that does not lend itself to 
> complex mathematical notation.

While this is certainly true, I think that improving is always a good idea. One 
of the cool things about Python is that it is a very broad general purpose 
language. Many people from many communities like its concise syntax. Those 
include the symbolic math community. And it is unfortunate that it is indeed 
possible to write symbolic math expressions very beautifully in Python, just 
the Python interpreter mangles it, as I show here without need.

> What is so special about constant expressions like `1/3`? Why shouldn't 
> non-constant expressions like `one/three` work?

Because reality. People would like to write 1/2 * m * v**2 to mean the obvious 
thing, without having to think about the details. And there are many people 
like this, this is why it shows up on this mailing list regularly. I have never 
felt the urge to write two/three * m * v**two.

Sure, one can add yet another syntax to Python to express fractions, adding 
some letter here, some special character there. %But $the $cool @thing $about 
?Python is $that !this _is_ $normally &unnecessary.

> How about expressions like `(1-3**-2)*7`?

I will make the ** operator work as well. Certainly only as long as the 
exponent is integer.

> If you care about making symbolic maths look good, don't you need a way 
> for expressions like √2 and sin π/3 to give you an exact symbolic result 
> too?

Sure. I am waiting for your proposal.

> How do you respond to the argument that this will add lots of complexity 
> to the mental model of numbers in Python, without actually making Python 
> a symbolic maths language?

There are quite a number of people using Python as a symbolic math language, 
sympy and sagemath are examples. They constantly invent pre-processors, as 
mentioned in this thread and the previous one before, to make their life 
easier. Those preprocessors usually have something that turns 1/2 into some 
magic. I think it is fruitful to look at the existing preprocessors in more 
detail and pick the best they offer for standard Python.

Also, I do not think it makes the mental model of numbers more complicated. If 
you don't need it, you won't even notice. But for symbolic math, users will 
actually need to think less about the details, not more.

> You suggest:
> > only when we start calculating with them, the receiving function will 
> > pick whatever it prefers.
> > In concrete terms, how do I write a function to do that?

   class Fraction:
      def __init__(self, x):
          self.numerator = x.numerator
          self.denominator = x.denominator

> Once I have a ratiofloat and do arithmetic to it, what happens?

The result is a simple float. For backwards compatibility.

> x = 1/3  # this is a ratiofloat
>     # what are these?
>     x + 1

a float

>     x**2

a float

>     x**0.5

a float

As I said, everything happens on the parser level.

> You say:
> > All of this does not only work for integers, but also for float 
> > literals
> > and give 0.1 as an example. Okay, I will grant you that *most* people 
> will expect that 0.1 is 1/10, rather than 
> 3602879701896397/36028797018963968 but what about less obvious examples?
> If I write 0.6666666666666666 will I get 2/3?

No. Because 0.6666666666666666 != 2/3. We are talking about exact math here, as 
in exact. Not high precision, exact.

What if I write it as 
> 0.6666666666666667 instead? (They are different floats.) How about 
> 0.666666666667, copied from my calculator?
> How about 0.66667? Is that close enough to get 2/3? Its obvious that in 
> real life anyone writing 0.66667 is thinking "2/3".

Nobody would like to write 0.66667 * x to mean 2/3 * x. So your example is 
actually very artificial. And no, my code does not do any magic, it just 
retains the original exact value entered by the user. Actually, it does that 
only on a best effort basis, some 9 digits are possible, after that it just 
drops the details entirely. I do not think this is too bad, as I do believe 
nobody has a deep desire to write things like 134512342/234233. And if they do, 
telling them to write F(134512342, 234233) is certainly not such a big issue.

> What's the size of your ratiofloats?
> >>> sys.getsizeof(2.5)
>     24

On my system:

    >>> import sys
    >>> a=2.5
    >>> b=float(2.5)
    >>> type(a)
    <class 'ratiofloat'>
    >>> type(b)
    <class 'float'>
    >>> sys.getsizeof(a)
    32
    >>> sys.getsizeof(b)
    24

So it is 8 bytes bigger, that are the two C ints mentioned before. Remember 
that they are only created at compile time and stored in the .pyc files, so I 
have a hard time imagining that they will ever take up more than some kilobytes.

> You say:
> > All this is only interesting once you teach some classes about it.
> > What is involved in teaching classes about this? For example, how much 
> work did it take for you to get this result?
> >>> Decimal(0.1)
>     Decimal('0.1')

It's this commit: 
https://github.com/tecki/cpython/commit/15c7e05cd50e4c671072b8497dbccbebf654b477
It took me about 30 min. Sympy was a bit harder, an hour or two.


> I can see that, maybe, sympy would be interested in this. Aside from 
> sympy, what benefit do you think other libraries will get from this? 

sagemath will also benefit. Those are the symbolic math libraries I know about. 
Those are not small communities, though.

> Especially libraries like numpy and scipy which pretty much do all their 
> work in pure floating point.

I think numpy and scipy will get nothing from it, because they do not do 
symblic math. They are actually the unfortunate guys, because they would have 
to modify some (not much) of their code, as they sometimes do use "type(x) is 
float" instead of "isinstance(x, float)" to do their magic. That said, once 
that's fixed I do not see any more problems, ratiofloat is binary backwards 
compatible to float, so I do not even see a speed penalty (like always that has 
to be shown).

Cheers

Martin
_______________________________________________
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/6WHCNGEL6MA3VZP4PJNOYMIYK334KC74/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to