
solve(x**2 == 1/2)
pip install funcoperators
solve(x ** 2 |Equals| 1/2) <<< Equals = infix(Eq) <<< from sympy import Eq
Le mer. 19 mai 2021 à 08:40, Martin Teichmann <martin.teichmann@gmail.com> a écrit :
Hi list,
as you might have noticed, I am trying to improve the syntax and semantics for symbolic math in Python. Until now, I have to say, my ideas were not that well received, but I learned from the discussion and maybe this time I come up with something people like.
To frame the problem, let us try to solve the equation x ** 2 == 1/2 using sympy:
>>> from sympy import Eq, solve, symbols, S >>> x = symbols("x") >>> solve(Eq(x**2, S(1)/2)) [-sqrt(2)/2, sqrt(2)/2]
that worked well, but actually we would like to write the last line simply as
>>> solve(x**2 == 1/2)
as you might notice, this is fully legal Python syntax. Unfortunately the semantics is such that sympy has no way to determine what is actually going on, this is why they invented all those helper functions shown above.
My idea is now to start at the line above, "x = symbols('x')". I propose a new syntax, "symbolic x", which tells the parser that x is a symbolic variable, and expressions should not be executed, but handed over as such to the calling functions. To stay with the example, the code would look like this (this is fake, I did not prototype this yet):
>>> from sympy import solve >>> symbolic x >>> solve(x**2 == 1/2) [-sqrt(2)/2, sqrt(2)/2]
Now to the details. The scope that "symbolic" acts on should be the same as the scope of "global". Note that "symbolic x" is currently illegal syntax, so we would not even need to make "symbolic" a keyword.
Expressions that contain a symbolic variable are not executed, but instead the expression should be given to the function as a tuple, so in the example above, solve would be given ('==', ('**', ('x', 2)), ('/', 1, 2)). If that looks like LISP to you, then you are not completely wrong. The boundaries of expressions are function calls, assignments, getitems and getattrs, as they can be overloaded much easier by other means. To give an example with gory details (again, this is fake):
>>> symbolic x >>> d = {"a" : 5} >>> c = 7 # not symbolic! >>> print(c * x + d["a"]) ('+', ('*', 7, 'x'), 5)
Maybe we would want to have a new class "expressiontuple" which simply acts as a pretty-printer, then the last lines would become
>>> print(x + d["a"]) 7 * x + 5
What sympy does with this tuple would be fully at its discretion.
I think that other libraries could also benefit from this proposal. As an example, in a numerics library (numpy? scipy?) one could improve numerical integration as in
>>> symbolic x >>> integrate(sin(x), x, 0, pi)
then the integrator could even compile the expression to machine code for faster integration.
numpy could also compile expressions to machine code, making it even faster than it is now, as in
>>> symbolic x >>> f = compile(5 * x + 7 * y, (x, y)) >>> f(matrix_a, matrix_b)
Let's see how well this proposal fares.
Cheers
Martin _______________________________________________ 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/ZMUV4O... Code of Conduct: http://python.org/psf/codeofconduct/