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/
-~----------~----~----~----~------~----~------~--~---

Reply via email to