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-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/ZMUV4OUDUX3NSROM2KRUIQKSIBUCZOCD/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to