Hi Oscar,

It wouldn't be hard to make any new definition of a Symbol with the
same name as a previously created symbol raise an error but it would
break the assumption that it is okay to define a symbol that is only
used local to some context and that assumption is depended on by many
users and downstream libraries and is also used internally by sympy
itself.

This context what I meant when I was talking about the 'scope' of a variable, and now it makes sense to me. Is it right that this function is "broken":

def my_power(n):
        x=Symbol('x')
        expr = x**n
        return expr

because the scope of x is lost on function return?  But this function is OK:

def my_power(x, n):
        expr = x**n
        return expr

because when the second function is called, the variable x is already defined in the scope/context of the calling function?

What I said about the overhead is that when creating an expression like

x = Symbol('x')
x2 = Symbol('x', positive=True)
expr = x*x2

it would be possible to check here that expr contains two different
symbols having the same name. However that would need to be checked in
the evaluation of x*x2 and then also in the evaluation of cos(x) +
3*sin(x2) etc. We would need to walk the expression tree looking for
symbols with the same name every time any operation constructs a new
expression which would be too expensive.

Wouldn't it be enough if the second line above:
x2 = Symbol('x', positive=True)
issued a warning message to the user, saying that "Symbol('x', ...) was called more than once with the same name? Or is that what would break existing code/libraries?

Certainly the behavior surprised me, and it means that some of the sympy
code I have written in the past month is wrong. Even though it appears
to work correctly, that's accidental, not by design.

I think that the root of the surprise here is the fact that it
sometimes works. Actually it is better to never depend on independent
calls to Symbol giving interchangeable results regardless of the names
of the symbols. All symbols in your calculation should just be defined
in one place and then if you need to use them somewhere else (e.g. in
a function) then you should pass them through.

I'll take a closer look at this code. What you write makes sense to me for code with independent scope/context. What I had not appreciated was that this could cause an issue in code that shares a context (for example, in a single interactive session).

Of course pickle does need to depend on this and so we need to fix the
pickling code to do this correctly. I sent a pull request here that
fixes the original issue that Bruce had although it disables pickling
with older versions of the pickle protocol:
https://github.com/sympy/sympy/pull/21260

I'm sorry that I have not tested this yet. I'm trying hard to get a paper finished, and that makes it hard to focus on other things.

Cheers,
        Bruce

--
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sympy/dbe3f718-8840-efa9-35f9-e747e4222267%40googlemail.com.

Reply via email to