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 -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/ZMUV4OUDUX3NSROM2KRUIQKSIBUCZOCD/
Code of Conduct: http://python.org/psf/codeofconduct/