Le jeudi 17 mai 2012 à 22:33 +0200, [email protected] a écrit :
> >>> * Why is this new behaviour limited to Expr? Callability and
> >>> existence of arithmetic operations are orthogonal concepts.
> >> I did not understand the question. A possible answer if I understand
> >> would be: The idea is to have an identity between "1 + function(arg ->
> >> f(arg))" and "function(arg -> 1+f(arg))". It is a very frequent "abuse
> >> of notation". Admittedly, "abuses of notation" should rarely be
> >> implemented in CAS, however this does not interfere with the rest of
> >> sympy and it can be made rigorous by stating "arithmetics and function
> >> definition commute". As I already mentioned a precedent can be seen in
> >> "Functional Differential Geometry" by Sussman and Wisdom.
> >
> > I think what he's saying is that if we have this, it should go in
> > Basic, not Expr.
> >
> To me this seems related to the question of merging Basic and Expr.
> Please excuse me if there are obvious reasons against the merge, it is
> just that I do not know them for the moment. I propose that we put off
> this discussion for later.

Well, the obvious reason is that lumping together vastly different
objects is bad design. E.g. if we merged Expr back into Basic, what
should Basic.__add__ mean? Addition as in Expr, set union as in Set (not
a really good choice, IMO, but that's what we have now) or concatenation
as in Tuple?

> >>
> >>>
> >>> * What about function arity? If f = Lambda(x, x) and
> >>> g = Lambda((x, y), x+y), what is 1 + f + g?
> >> Quite seriously I would answer "Why should we care?". It would be nice
> >> to have partial (lazy) evaluation, but even if we do not have it, this
> >> would be considered just an mis-formed expression that should not be
> >> created (I like more the partial evaluation possibility). Also, we
> >> have already discussed something like this during the argument about
> >> "symbolic lazy nsolve" https://github.com/sympy/sympy/pull/968 . I
> >> would very much like to continue the discussion about this pull
> >> request as I had some unanswered questions. The most important one was
> >> about the "infinitely evaluated" semantics used by Mathematica. I left
> >> a reference to some documentation on the subject but I did not get any
> >> answers.
> >
> > Partial evaluation (a.k.a. currying) is an interesting idea, but it's
> > probably better for this expression to just raise an error (it would
> > do so at call time, to avoid overhead in Add).
> >
> > What was the Mathematica thing?  Can you give a link?
> >
> 
> Two details about Mathematica (that maybe I misunderstand):
> - less importantly: it permits you to write nonsense:
> Integral[Manifold[Circle[InputFile[blah blah]]]] will not raise an
> error, it will just be left unevaluated because Integral does not know
> what to do with Manifold which does not know ... etc.
> 
> - this leads us to "infinite evaluation system"
> reference.wolfram.com/legacy/v1/contents/4.2.7.pdf 2nd paragraph
> To quote: "In Mathematica the evaluation goes on until the result you
> get no longer change."

I'm not sure whether the reference to Mathematica is really useful.
Mathematica is a programming language, in addition to a CAS, and it
follows a completely different paradigm from Python: rewriting rules vs
OO/imperative. What you mention seems more relevant to the language than
to the CAS.
> 
> Two examples how this is useful:
> 
> - It permits the user to create AST with sympy expression that may not
> make sense for sympy, but that make sense in the formalism that the
> user implements. At the moment this is not always possible as sympy is
> rather draconian about raising errors and demanding that everything is
> Expr (not Basic).

That's not really true. You can create '1 + Add(FiniteSet(1, 2), And(x,
y))', you just can't print it.
> 
> - The symbolic nsolve I was talking about. If there are too many free
> symbols nsolve can not change and thus it returns symbolic unevaluated
> version of itself. Obviously the parallels with Mathematica are flawed
> as this is a feature of the language that Python does not support and
> that we are only emulating.

The problem with this is that nsolve is, by definition, supposed to
return a numeric result. A Python function is obviously not a numeric
value and getting one where the other was expected will surely crash the
program using it, possibly at an arbitrary distance from the nsolve()
call. What you want can easily be achieved using standard Python
constructs, like functools.partials or a lambda expression, e.g. 
lambda a0: nsolve((tan(a*x) - 1).subs(a, a0), x, 1).

BTW, calling this a "symbolic nsolve" is confusing, because it's not
symbolic in the sympy sense (where, basically, "a symbolic object" means
"an instance of Basic").

> >>> * 1 + Function('f') can't work anyway, because Function('f') is a
> >>> class, not a sympy object.
> >> This is a second time that you mention this argument. I have some
> >> questions about it.
> >>
> >> Actually Lambda has the same semantics as Function and it works
> >> perfectly with this (just because it subclasses Expr). I have some
> >> open questions about this on our recent discussion on the mailing list
> >> "why is Lambda not subclassing Applications".
> >
> > Does this also apply to 1 + sin?  Personally I think we should change
> > how Function('f') works, if just for issue 1198.
> >
> It should apply but it does not because you can not write 1+sin
> because Add accepts only Expr. Ether Add should be less picky or sin
> (ugh... Function?) should subclass Expr.

Function (and therefore sin) does subclass Expr. When you have f =
Function('f'), then f is a subclass of Function and it is not an
instance of it, while f(x) is an instance of f and therefore of Function
and of Expr. In other words, "f = Function('f')" is nearly equivalent to
"class f(Function): pass".
> 
> Also here we have much black magic and jumping through circles during
> the creation of sin(x) with what I consider an excessive use of
> metaclasses. However I may be very very wrong on this one (more than
> usual ;)

Huh? Metaclasses aren't involved in the instantiation of sin(x). The
only real indirection is that the parent class, Application, calls
sin.eval().
> 
> > I can say, however, that if this worked that it would be extremely
> > useful.  I can give examples if anyone wants convincing of that.
> >
> 
> When you have the time some more examples will be useful for me, as I
> may be missing some of the details.
> 


-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sympy?hl=en.

Reply via email to