On Thu, 14 Apr 2022 at 20:30, Aaron Meurer <[email protected]> wrote: > > On Thu, Apr 14, 2022 at 12:26 PM Oscar Benjamin > <[email protected]> wrote: > > > > As an example it would be trivial in SymPy to make substitutions > > involving large expressions and many replacements much faster with a > > small redesign. The problem though is backwards compatibility: each > > expression class can implement its own _eval_subs method so for > > backwards compatibility the subs implementation must recurse in the > > same slow way once throughout the whole tree for each replacement that > > is to be made. (There are ways to work around this but the design > > makes it harder than it should be.) > > Just to be clear, isn't this already fixed with xreplace, which does > only replacement with no smart substitution and no dispatching to > _eval methods? That isn't to say xreplace itself couldn't be more > performant, which I'm sure it could.
Even xreplace runs the evaluation code which is baked into __new__. Also it recurses down through all of the args in the tree which can in many cases be done much more efficiently if the expression is represented as a DAG rather than a tree. > > This is a small example of a more general problem. Using classes means > > you have to use the interfaces of the class which means that efficient > > algorithms needing something not provided by that public interface are > > impossible. Even worse both SymPy and SymEngine allow the > > *constructors* of those classes to do nontrivial work without > > providing any good way to override that. This means that you can't > > even represent a symbolic expression without allowing arbitrary code > > execution: it's impossible to optimise higher-level algorithms if you > > have so little control over execution from the outside. > > What's your suggested alternative? It seems like you on the one hand > are saying that it's not extensible enough (I guess because any > extension has to be in C++) and at the same time that it's too > extensible, because custom classes can do anything. > > I think there is a balance in general between extensibility and > performance. The only way to make something performant is to limit the > domain of what can be expressed so that more efficient data structures > can be used. I think it's possible to get more extensibility and more performance by taking a different approach. It's not that SymPy can't be extended: it's just not easy to extend. The Python/SymPy knowledge required to be able to create new symbolic classes is too great for "ordinary users" to make use of it. I think that what is needed is a core that is well-defined in its scope but designed fundamentally around extensibility. The core operations that manipulate expressions should be implemented in a low-level language but it should be possible to define and control their behaviour precisely from a higher level. -- Oscar -- 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/CAHVvXxS%2BCo%2BE5hxOxM4RfjZgH0XkryQtnTtH7n5Az21dNygr%2BQ%40mail.gmail.com.
