On Sep 12, 2007, at 6:23 AM, Ondrej Certik wrote: > Hi, > > I have a few design questions that I would like to discuss and they > are relevant to both SymPy and SAGE, so I am posting to both > mailinglists. > > We are currently redesigning the class hierarchy in SymPy so that: > > 1) > > Add(sin, cos) > > and > > Add(sin(1),cos(1)) > > are valid constructions. Here (Add(sin, cos))(1) will produce > Add(sin(1), cos(1)). So that we can use both applied (sin(x)) and > unapplied (sin) functions. > > 2) we have the least amount of classes in there > > For details, see: > > http://code.google.com/p/sympy/issues/detail?id=329 > > However, there are some longterm questions: > > 1) when you type sin(x), it's an instance of the class "sin". Now, all > classes in Python should be CamelCase, so we should rather use > "Sin(x)". Currently, SymPy/SAGE/Maple uses "sin(x)", while Mathematica > uses "Sin[x]". > > What is your opinion about this? See also: > > http://code.google.com/p/sympy/issues/detail?id=329#c11 > > I'd very much like to obey Python conventions, because this is what > people expect when seeing the code for the first time. Of course we > can do something like > > sin=Sin > > so that people can use both. But I am against it, since there should > be just one way of doing things. And especially, there should be just > one way how things are done both inside and outside SymPy, i.e. there > shouldn't be one way how to create functions in SymPy core and another > way how users will create functions. > > So for the time being, we use lower case name of some classes in > SymPy, like "sin", "cos", so that we don't break the current code.
I think sin should be an instance rather than a class, and it would have a reasonable __call__ method. This would have the side effect of being consistent with Python conventions, and would be more consistent with the user's idea that "sin" is a function. One can also then do things like sage: sin.is_zero() False > 2) I was looking at how this is done in SAGE.calculus: > > There is: > > class Function_sin(PrimitiveFunction): > .... > > sin = Function_sin() > _syms['sin'] = sin > > example: > > sage: from sage.calculus.calculus import Function_sin > sage: sin(x) > sin(x) > sage: Function_sin()(x) > sin(x) > sage: type(sin) > <class 'sage.calculus.calculus.Function_sin'> > sage: type(sin(x)) > <class 'sage.calculus.calculus.SymbolicComposition'> > > > So first there are two ways how to create a sin(x): "sin(x)", or > "Function_sin()(x)" I don't see the latter ever getting used, or even being exposed. It seems as unnatural as sage: import types sage: types.IntType(4) # instead of using int(4) > and second everything is an instance of > SymbolicComposition. Currently in SymPy it's very similar, there is > Sin and ApplySin, Cos and ApplyCos (in sage you just use > SymbolicComposition for all those ApplySin, ApplyCos,...). In SymPy, > it's a mess and we are changing that. > > How do you test, if "e" is of type sin? > > In SymPy, we would like to do this: > > e = sin(x) > print isinstance(e, sin) > > (currently on needs to do isinstance(e, ApplySin), but this is going > to be changed) for the unnapplies, one would do e == sin, for the applied one would have to do isinstance(e, SymbolicComposition) and e._operands[0] == sin (this should probably be fixed by adding methods to SymbolicComposition) > In SymPy, we are just going to try a very simple approach and see how > it goes, see the 329 issue above for details. > > 2) What is your position on this: > > sage: (sin(x)).taylor(x, 0, 5) > x - x^3/6 + x^5/120 > sage: taylor(sin(x), x, 0, 5) > x - x^3/6 + x^5/120 > > shouldn't there be just one way how to do series expansion? In SymPy > we also have those 2 ways - but it's kind of inconsistent, we have it > for some methods, but not all. My own opinion is more in favor of > removing all those module level functions (like taylor, expand), if > there is a corresponding method. But there are other opinions as well. Usually we go for the former, so as not to clutter the namespace and to avoid big if-then lists. Occasionally, though, we provided a global function like def foo(x): try: return x.foo() except AttributeError: # generic code or raise a value error - Robert --~--~---------~--~----~------------~-------~--~----~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~----------~----~----~----~------~----~------~--~---