It seems like a good plan if everybody agrees. I believe S is some
other global object, so it should be renamed and S should be a
function. sympify() should return a deprecated warning for some time,
before we remove it.
Ondrej
Contracting "convert" to "cv" is *not* easy to understand.
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
-- Umberto Eco
One thing I think we do need to do though is to make sympify() more prevalent in the docs. I have seen more than one instance on the internet where someone was trying to write their own equation parser for SymPy because they didn't know about the existence of the sympify() function.
Aaron Meurer
After thinking about it for a while, I think you are right, we should
probably keep both.
>
> One thing I think we do need to do though is to make sympify() more prevalent in the docs. I have seen more than one instance on the internet where someone was trying to write their own equation parser for SymPy because they didn't know about the existence of the sympify() function.
Yes, we need to improve our docs for sure.
Ondrej
Vinzent
--
You received this message because you are subscribed to the Google Groups "sympy" group.
To post to this group, send email to sy...@googlegroups.com.
To unsubscribe from this group, send email to sympy+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/sympy?hl=en.
I don't really have an opinion on the naming issue, but it seems
relevant to mention an insight I've had while trying to implement
generic functions and to refactor sympify() as such a generic function
(see http://github.com/rlamy/sympy/tree/generic ).
So, the idea is that sympify(), as currently implemented, mixes two
distinct concepts: coercion and conversion. The difference between the
two can be hard to grasp but it corresponds quite well to the difference
between the internal-use function _sympify() and plain sympify().
Coercion is the transformation of an object that is already conceptually
a sympy object into an actual sympy object, for example the
transformation of a Python int into a sympy Integer. End users are only
meant to use it implicitly, usually by using binary operators. For
instance, in the expression 'Integer(1)/3', the int instance '3' is
coerced to 'Integer(3)'.
Conversion, on the other hand, is an explicit request to take any object
and return a sympy object. For instance, in 'S("1/3")', the string "1/3"
is converted to 'Rational(1, 3)'.
If we want a consistent and easily explainable system, I think that the
two concepts should be clearly separated and that the result of both
should only ever be a sympy object (i.e. an instance of Basic).
Aaron Meurer
Also, what is the generic stuff? The commit messages and docstrings aren't very clear.
Aaron Meurer
But that would be misleading since the function has nothing to do with making things simple. It makes them into sympy object. Shortening to sympy won't work. sympyfy is ok but it looses the pythonic cuteness (IMO). What about sympyit?
The point is to avoid calling the conversion function when implementing
an unrelated function. There are currently many methods and functions
that call the full sympify() (with some inconsistencies:
simplify('(1-x**2)/(1-x)') raises but cancel('(1-x**2)/(1-x)') works).
In most or perhaps all cases, they should only perform coercion. If the
user wants to use a string, they can wrap it with S() - explicit is
better than implicit.
> Also, what is the generic stuff? The commit messages and docstrings
> aren't very clear.
Well, I'm not quite sure yet... The general idea is to allow a single
function to call different implementations depending on the types of its
arguments - like built-in functions such as len() or iter(), but without
the special method name trick.
> Aaron Meurer
>
> On Dec 7, 2010, at 7:34 PM, Aaron S. Meurer wrote:
>
> > So are you suggesting that S(list) shouldn't work then (or else
> return a Tuple or whatever)?
Yes, I'm suggesting one of these. Also, I think we should have S.True
and S.False and let S(True) and S(False) return these.
> Le mardi 07 décembre 2010 à 19:38 -0700, Aaron S. Meurer a écrit :
>> Ah, but I see, something like 1 + '1' doesn't work. Coercion means
>> automatic conversion in an operator or function call. So even then, I
>> don't see the need for two separate sympify functions.
>
> The point is to avoid calling the conversion function when implementing
> an unrelated function. There are currently many methods and functions
> that call the full sympify() (with some inconsistencies:
> simplify('(1-x**2)/(1-x)') raises but cancel('(1-x**2)/(1-x)') works).
> In most or perhaps all cases, they should only perform coercion. If the
> user wants to use a string, they can wrap it with S() - explicit is
> better than implicit.
>
I see. I was thinking why have separate functions as opposed to one function with a keyword argument, but I think either one could be reasonable in this case. I do agree that sympy_function(string) is bad style and should be discouraged at best.
>> Also, what is the generic stuff? The commit messages and docstrings
>> aren't very clear.
>
> Well, I'm not quite sure yet... The general idea is to allow a single
> function to call different implementations depending on the types of its
> arguments - like built-in functions such as len() or iter(), but without
> the special method name trick.
If we require everything to be Basic, what is the use of this?
>
>
>> Aaron Meurer
>>
>> On Dec 7, 2010, at 7:34 PM, Aaron S. Meurer wrote:
>>
>>> So are you suggesting that S(list) shouldn't work then (or else
>> return a Tuple or whatever)?
>
> Yes, I'm suggesting one of these. Also, I think we should have S.True
> and S.False and let S(True) and S(False) return these.
Why? Is this needed for the Boolean stuff?
Aaron Meurer
So, even if we don't change anything else, I think we should make those
functions use _sympify instead of sympify, or perhaps remove
sympification entirely (after all, I don't remember anybody complaining
that 'simplify(1)' doesn't work, so why should 'cancel(1)'?).
> >> Also, what is the generic stuff? The commit messages and docstrings
> >> aren't very clear.
> >
> > Well, I'm not quite sure yet... The general idea is to allow a single
> > function to call different implementations depending on the types of its
> > arguments - like built-in functions such as len() or iter(), but without
> > the special method name trick.
>
> If we require everything to be Basic, what is the use of this?
Obviously, we can't require the arguments of sympify() to be Basic,
which is why this was the first function I tried to "genericise". For
ordinary sympy functions, it allows to define new functions without
altering existing classes and to define new classes making use of
existing functions without altering them.
There are already plenty of functions that are effectively generic. They
use one of 3 mechanisms:
* 1) Call some predefined method on their argument (either
_eval_the_function or __the_function__)
* 2) Find a function whose name matches the argument class name inside
some namespace (usually a class): that's what printers and "ask
handlers" do.
* 3) Use ugly ad-hoc elif chains.
3) is unpythonic. 1) doesn't allow new functions without modifying the
core. 2) forces every new class to modify the functions' namespace.
> >
> >
> >> Aaron Meurer
> >>
> >> On Dec 7, 2010, at 7:34 PM, Aaron S. Meurer wrote:
> >>
> >>> So are you suggesting that S(list) shouldn't work then (or else
> >> return a Tuple or whatever)?
> >
> > Yes, I'm suggesting one of these. Also, I think we should have S.True
> > and S.False and let S(True) and S(False) return these.
>
> Why? Is this needed for the Boolean stuff?
Actually, there are several reasons to do it:
* as I said, it allows us to say that sympify() always returns a sympy
object, i.e. an instance of Basic
* it's the only way to ensure that all arguments of Boolean expressions
are instances of Basic
* it would force us to clarify whether functions return a Boolean
expression or a built-in bool (in the latter case, None can often be
returned as well).