Sage: Ticket #14270: Remove function call syntax for symbolic expressions
https://trac.sagemath.org/ticket/14270
<p>
The function call syntax for symbolic expressions has been deprecated for almost six years. It is about time it raised some errors. This will prevent people from getting confused because of behavior <a class="ext-link" href="http://ask.sagemath.org/question/2357/the-difference-between-fx3-and-f3-of-callable"><span class="icon"></span>like this</a>.
</p>
<p>
Apply <a class="attachment" href="https://trac.sagemath.org/attachment/ticket/14270/trac_14270-raise_error_on_function-call.patch" title="Attachment 'trac_14270-raise_error_on_function-call.patch' in Ticket #14270">trac_14270-raise_error_on_function-call.patch</a><a class="trac-rawlink" href="https://trac.sagemath.org/raw-attachment/ticket/14270/trac_14270-raise_error_on_function-call.patch" title="Download"></a> to devel/sage.
</p>
<p>
See also the threads
</p>
<ul><li><a class="ext-link" href="http://groups.google.com/group/sage-devel/t/de97f91d548cc0ec"><span class="icon"></span>http://groups.google.com/group/sage-devel/t/de97f91d548cc0ec</a>
</li><li><a class="ext-link" href="http://groups.google.com/group/sage-devel/t/5f2705b2b8d21593/b11079d8299a03b5"><span class="icon"></span>http://groups.google.com/group/sage-devel/t/5f2705b2b8d21593/b11079d8299a03b5</a>
</li></ul>en-usSagehttps://trac.sagemath.org/chrome/site/logo_sagemath_trac.png
https://trac.sagemath.org/ticket/14270
Trac 1.1.6ppurkaThu, 14 Mar 2013 16:39:06 GMTstatus, description changed; author set
https://trac.sagemath.org/ticket/14270#comment:1
https://trac.sagemath.org/ticket/14270#comment:1
<ul>
<li><strong>status</strong>
changed from <em>new</em> to <em>needs_review</em>
</li>
<li><strong>description</strong>
modified (<a href="/ticket/14270?action=diff&version=1">diff</a>)
</li>
<li><strong>author</strong>
set to <em>Punarbasu Purkayastha</em>
</li>
</ul>
TicketppurkaFri, 15 Mar 2013 03:00:21 GMTstatus changed; work_issues set
https://trac.sagemath.org/ticket/14270#comment:2
https://trac.sagemath.org/ticket/14270#comment:2
<ul>
<li><strong>status</strong>
changed from <em>needs_review</em> to <em>needs_work</em>
</li>
<li><strong>work_issues</strong>
set to <em>fix doctests</em>
</li>
</ul>
TicketppurkaTue, 19 Mar 2013 08:46:02 GMTwork_issues changed
https://trac.sagemath.org/ticket/14270#comment:3
https://trac.sagemath.org/ticket/14270#comment:3
<ul>
<li><strong>work_issues</strong>
changed from <em>fix doctests</em> to <em>fix combinat/tutorial.py</em>
</li>
</ul>
<p>
I am able to fix all the doctests except for the following one in combinat/tutorial.py.
</p>
<p>
The example which fails seems to make no sense to me. A <code>substitute_function</code> method is being used to substitute a function with a symbolic expression.
</p>
<pre class="wiki">sage: C, z = var('C,z');
sage: sys = [ C == z + C*C ]
sage: sol = solve(sys, C, solution_dict=True); sol
[{C: -1/2*sqrt(-4*z + 1) + 1/2}, {C: 1/2*sqrt(-4*z + 1) + 1/2}]
sage: s0 = sol[0][C]; s1 = sol[1][C]
...
sage: C = s0; C
-1/2*sqrt(-4*z + 1) + 1/2
...
sage: equadiff
(4*z - 1)*D[0](C)(z) - 2*C(z) + 1 == 0
sage: Cf = sage.symbolic.function_factory.function('C')
sage: equadiff.substitute_function(Cf, s0) # Original answer is the deprecation + answer
...
TypeError: %d format: a number is required, not NoneType
</pre><p>
Let us try to "fix" this (<code>z</code> is a symbolic variable). Somehow the following works (beats me why it does):
</p>
<pre class="wiki">sage: equadiff.substitute_function(Cf(z), s0)
(4*z - 1)*D[0](C)(z) - 2*C(z) + 1 == 0 # OK, so this seems to work
</pre><p>
But now the next command in the tutorial gives <code>False</code> instead of <code>True</code>
</p>
<pre class="wiki">sage: bool(equadiff.substitute_function(Cf(z), s0))
False
</pre><p>
Why is all this happening? Looking at the documentation of <code>substitute_function</code> shows that it should be used for substituting <em>functions</em>, not anything else
</p>
<pre class="wiki"> def substitute_function(self, original, new):
"""
Returns this symbolic expressions all occurrences of the
function *original* replaced with the function *new*.
</pre><p>
And what exactly are we substituting above?
</p>
<pre class="wiki">sage: type(Cf)
sage.symbolic.function_factory.NewSymbolicFunction
sage: type(s0)
sage.symbolic.expression.Expression
</pre><p>
We are substituting a symbolic function with a symbolic expression! How was this even working earlier?
</p>
<p>
What should I do with this portion of the tutorial? Delete this?
</p>
TicketppurkaTue, 19 Mar 2013 08:46:38 GMTattachment set
https://trac.sagemath.org/ticket/14270
https://trac.sagemath.org/ticket/14270
<ul>
<li><strong>attachment</strong>
set to <em>trac_14270-raise_error_on_function-call.patch</em>
</li>
</ul>
<p>
Apply to devel/sage
</p>
TicketkcrismanWed, 20 Mar 2013 03:16:12 GMTcc set
https://trac.sagemath.org/ticket/14270#comment:4
https://trac.sagemath.org/ticket/14270#comment:4
<ul>
<li><strong>cc</strong>
<em>nthiery</em> added
</li>
</ul>
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14270#comment:3" title="Comment 3">ppurka</a>:
</p>
<blockquote class="citation">
<p>
I am able to fix all the doctests except for the following one in combinat/tutorial.py.
</p>
</blockquote>
<p>
<snip>
</p>
<blockquote class="citation">
<p>
What should I do with this portion of the tutorial? Delete this?
</p>
</blockquote>
<p>
I'm cc:ing Nicolas, who should know what is going on here.
</p>
TicketkcrismanWed, 20 Mar 2013 03:23:08 GMT
https://trac.sagemath.org/ticket/14270#comment:5
https://trac.sagemath.org/ticket/14270#comment:5
<p>
I'd also say that I think the prep tutorial one should still talk about this at some length, to explain (in the event this is done) <em>why</em> this doesn't work, because a lot of people will now and forevermore expect that it will work. Similarly, most of these examples presumably should be moved to the new syntax, perhaps even with an explanatory remark as to exactly why that is the syntax. For instance, how <em>would</em> one do the matrix example <code>h(x)</code> now? We should be careful not to remove anything, just to change how it works to the appropriate way post-this-ticket.
</p>
<p>
Rant I don't actually want to rehash any more, but put here for completeness:
</p>
<blockquote>
<p>
<rant>
Because distinguishing between a function and a symbolic expression is an unnatural, CS-y thing to do; any symbolic expression is obviously a function of all variables in it, mathematically; for any function with more than one <code>var</code> I agree we don't want this (as indeed the example in the prep document points out) but for one-variable expressions (pace Jason, who will immediately ask whether <code>x+y-y</code> is one variable) it seems worth the potential for confusion...
</rant>
</p>
</blockquote>
TicketppurkaWed, 20 Mar 2013 05:00:45 GMT
https://trac.sagemath.org/ticket/14270#comment:6
https://trac.sagemath.org/ticket/14270#comment:6
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14270#comment:5" title="Comment 5">kcrisman</a>:
</p>
<blockquote class="citation">
<p>
I'd also say that I think the prep tutorial one should still talk about this at some length, to explain (in the event this is done) <em>why</em> this doesn't work, because a lot of people will now and forevermore expect that it will work.
</p>
</blockquote>
<p>
IMHO, the people who expect this to <em>still</em> work need to change their code. It has been in deprecated mode for over four years. That's more than enough time to change their habit and old code. I think someone hasn't complained before either because they are complacent or because they don't use this at all.
</p>
<p>
While teaching a course with Sage, I remember that we ourselves ran into this problem with the students. It was annoying and confusing because we were unaware of the code and how to fix it. We would just ask the students to ignore those warnings. What would a beginner do after defining <code>f(x) = x^2</code>? The most natural thing would be to do <code>f(2)</code> or something similar to "see" that it can actually evaluate. Now imagine the same with <code>f = x^2</code> and what you get is the deprecation message and then the correct answer. Second time it is evaluated, there is no deprecation message, so a beginner will wonder what just happened in the first invocation. It is not a favorable impression. It gives the impression of a half-done software.
</p>
<p>
I agree with you that it should be explained in the tutorial that there is a difference between symbolic functions and symbolic expressions and python functions.
</p>
TicketkiniFri, 22 Mar 2013 05:41:15 GMTcc changed
https://trac.sagemath.org/ticket/14270#comment:7
https://trac.sagemath.org/ticket/14270#comment:7
<ul>
<li><strong>cc</strong>
<em>kini</em> added
</li>
</ul>
TicketjdemeyerTue, 13 Aug 2013 15:35:53 GMTmilestone changed
https://trac.sagemath.org/ticket/14270#comment:8
https://trac.sagemath.org/ticket/14270#comment:8
<ul>
<li><strong>milestone</strong>
changed from <em>sage-5.11</em> to <em>sage-5.12</em>
</li>
</ul>
Ticketvbraun_spamThu, 30 Jan 2014 21:20:52 GMTmilestone changed
https://trac.sagemath.org/ticket/14270#comment:9
https://trac.sagemath.org/ticket/14270#comment:9
<ul>
<li><strong>milestone</strong>
changed from <em>sage-6.1</em> to <em>sage-6.2</em>
</li>
</ul>
Ticketvbraun_spamTue, 06 May 2014 15:20:58 GMTmilestone changed
https://trac.sagemath.org/ticket/14270#comment:10
https://trac.sagemath.org/ticket/14270#comment:10
<ul>
<li><strong>milestone</strong>
changed from <em>sage-6.2</em> to <em>sage-6.3</em>
</li>
</ul>
Ticketvbraun_spamSun, 10 Aug 2014 16:51:03 GMTmilestone changed
https://trac.sagemath.org/ticket/14270#comment:11
https://trac.sagemath.org/ticket/14270#comment:11
<ul>
<li><strong>milestone</strong>
changed from <em>sage-6.3</em> to <em>sage-6.4</em>
</li>
</ul>
TicketrwsSun, 01 Feb 2015 09:32:20 GMTdescription changed
https://trac.sagemath.org/ticket/14270#comment:12
https://trac.sagemath.org/ticket/14270#comment:12
<ul>
<li><strong>description</strong>
modified (<a href="/ticket/14270?action=diff&version=12">diff</a>)
</li>
</ul>
<p>
This is actually the same as <a class="closed ticket" href="https://trac.sagemath.org/ticket/8214" title="defect: Remove callable symbolic expressions (closed: duplicate)">#8214</a>, but that has no code, so I'm copying the two links from there to here before declaring it a dupe.
</p>
TicketppurkaSun, 01 Feb 2015 15:01:05 GMT
https://trac.sagemath.org/ticket/14270#comment:13
https://trac.sagemath.org/ticket/14270#comment:13
<p>
This ticket is unlikely to get fixed unless someone who knows the code really well addresses <a class="ticket" href="https://trac.sagemath.org/ticket/14270#comment:3" title="Comment 3">comment:3</a>
</p>
TicketnbruinSun, 01 Feb 2015 17:28:26 GMT
https://trac.sagemath.org/ticket/14270#comment:14
https://trac.sagemath.org/ticket/14270#comment:14
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14270#comment:3" title="Comment 3">ppurka</a>:
</p>
<blockquote class="citation">
<p>
I am able to fix all the doctests except for the following one in combinat/tutorial.py.
</p>
</blockquote>
<p>
OK, from what you've written down here, I can come up with one way of rewriting the example.
</p>
<blockquote class="citation">
<pre class="wiki">sage: C, z = var('C,z');
sage: sys = [ C == z + C*C ]
sage: sol = solve(sys, C, solution_dict=True); sol
[{C: -1/2*sqrt(-4*z + 1) + 1/2}, {C: 1/2*sqrt(-4*z + 1) + 1/2}]
sage: s0 = sol[0][C]; s1 = sol[1][C]
</pre></blockquote>
<blockquote class="citation">
<pre class="wiki">sage: C = s0; C
-1/2*sqrt(-4*z + 1) + 1/2
</pre></blockquote>
<p>
I think this should be deleted. Use s0 if you want that and just leave C bound to the variable. It's already bad enough that we need "C as a function" further down.
</p>
<blockquote class="citation">
<pre class="wiki">sage: equadiff
(4*z - 1)*D[0](C)(z) - 2*C(z) + 1 == 0
sage: Cf = sage.symbolic.function_factory.function('C')
</pre></blockquote>
<p>
Didn't we need Cf before to arrive at <code>equadiff</code>? How did <code>C(z)</code> get into that expression in the first place?
</p>
<blockquote class="citation">
<pre class="wiki">sage: equadiff.substitute_function(Cf, s0) # Original answer is the deprecation + answer
...
TypeError: %d format: a number is required, not NoneType
</pre></blockquote>
<p>
I think the following should work (it does in vanilla, without a deprecation warning):
</p>
<pre class="wiki">sage: equadiff.substitute_function(Cf, s0.function(z))
</pre><blockquote class="citation">
<p>
Let us try to "fix" this (<code>z</code> is a symbolic variable). Somehow the following works (beats me why it does):
</p>
<pre class="wiki">sage: equadiff.substitute_function(Cf(z), s0)
(4*z - 1)*D[0](C)(z) - 2*C(z) + 1 == 0 # OK, so this seems to work
</pre></blockquote>
<p>
I'm not so sure it "works". It doesn't give an error (which is surprising in its own right; perhaps that should change), but I don't think it gives the same answer. In vanilla:
</p>
<pre class="wiki">sage: equadiff.substitute_function(Cf(z), s0)
(4*z - 1)*D[0](C)(z) - 2*C(z) + 1 == 0
sage: equadiff.substitute_function(Cf, s0.function(z))
(4*z - 1)/sqrt(-4*z + 1) + sqrt(-4*z + 1) == 0
</pre><blockquote class="citation">
<p>
But now the next command in the tutorial gives <code>False</code> instead of <code>True</code>
</p>
</blockquote>
<p>
Rightly so, judging from the results above.
</p>
<blockquote class="citation">
<p>
Why is all this happening? Looking at the documentation of <code>substitute_function</code> shows that it should be used for substituting <em>functions</em>, not anything else
</p>
<pre class="wiki"> def substitute_function(self, original, new):
"""
Returns this symbolic expressions all occurrences of the
function *original* replaced with the function *new*.
</pre><p>
And what exactly are we substituting above?
</p>
<pre class="wiki">sage: type(Cf)
sage.symbolic.function_factory.NewSymbolicFunction
sage: type(s0)
sage.symbolic.expression.Expression
</pre><p>
We are substituting a symbolic function with a symbolic expression! How was this even working earlier?
</p>
</blockquote>
<p>
I guess because symbolic expressions were deprecated "functions": you could call then with symbolic arguments and get a symbolic expression, at the cost of a deprecation warning.
</p>
<blockquote class="citation">
<p>
What should I do with this portion of the tutorial? Delete this?
</p>
</blockquote>
<p>
No, just do
</p>
<pre class="wiki">sage: equadiff.substitute_function(Cf, s0.function(z))
</pre><p>
That's probably a useful example to have anyway. It shows how to turn a symbolic expression into a function in a non-ambiguous way, because you need to specify argument order.
</p>
TicketkiniSun, 01 Feb 2015 21:18:02 GMTdescription changed
https://trac.sagemath.org/ticket/14270#comment:15
https://trac.sagemath.org/ticket/14270#comment:15
<ul>
<li><strong>description</strong>
modified (<a href="/ticket/14270?action=diff&version=15">diff</a>)
</li>
</ul>
TicketrwsWed, 23 Aug 2017 07:48:43 GMT
https://trac.sagemath.org/ticket/14270#comment:16
https://trac.sagemath.org/ticket/14270#comment:16
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14270#comment:5" title="Comment 5">kcrisman</a>:
</p>
<blockquote class="citation">
<blockquote>
<p>
<rant>
Because distinguishing between a function and a symbolic expression is an unnatural, CS-y thing to do; any symbolic expression is obviously a function of all variables in it, mathematically; for any function with more than one <code>var</code> I agree we don't want this (as indeed the example in the prep document points out) but for one-variable expressions (pace Jason, who will immediately ask whether <code>x+y-y</code> is one variable) it seems worth the potential for confusion...
</rant>
</p>
</blockquote>
</blockquote>
<p>
I actually agree and I don't see why a function call with non-relational argument should not be allowed IF there is only one variable in the expression. The confusion comes from the fact that things like <code>sqrt(2)(x+y)</code> almost always are typos where the <code>*</code> is missing. These should be marked as error. Now Sage cannot distinguish between <code>f=x^2; f(2)</code> and <code>sqrt(2)(x+y)</code> because <code>f</code> is replaced immediately with <code>x^2</code> and so in both cases an expression has its <code>__call__</code> member executed. BUT, first with <code>sqrt(2)(x+y)</code> the expression has no variables and so it can be doubtlessy marked as error; secondly, before <code>f</code> is silently expanded to <code>x^2</code> it is seen by the parser---maybe the parser can distinguish between calls that are done to <code>f</code> (like calls to functions) and other calls, and only allow the former?
</p>
TicketrwsWed, 23 Aug 2017 07:50:29 GMTstatus, milestone changed
https://trac.sagemath.org/ticket/14270#comment:17
https://trac.sagemath.org/ticket/14270#comment:17
<ul>
<li><strong>status</strong>
changed from <em>needs_work</em> to <em>needs_info</em>
</li>
<li><strong>milestone</strong>
changed from <em>sage-6.4</em> to <em>sage-8.2</em>
</li>
</ul>
TicketjdemeyerWed, 23 Aug 2017 07:58:18 GMT
https://trac.sagemath.org/ticket/14270#comment:18
https://trac.sagemath.org/ticket/14270#comment:18
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14270#comment:16" title="Comment 16">rws</a>:
</p>
<blockquote class="citation">
<p>
maybe the parser can distinguish between calls that are done to <code>f</code> (like calls to functions) and other calls, and only allow the former?
</p>
</blockquote>
<p>
That would be adding even more special cases just for Sage.
</p>
<p>
In Python, you expect the following two to do the same thing
</p>
<pre class="wiki">f = x^2
print(f(2))
</pre><p>
and
</p>
<pre class="wiki">print((x^2)(2))
</pre><p>
It would be very surprising if somehow these would become different.
</p>
TicketkcrismanWed, 23 Aug 2017 12:03:42 GMT
https://trac.sagemath.org/ticket/14270#comment:19
https://trac.sagemath.org/ticket/14270#comment:19
<p>
But of course Jason's <code>x+y-y</code> still has to be dealt with, if only to ignore it ...
</p>
TicketrwsWed, 23 Aug 2017 13:08:11 GMT
https://trac.sagemath.org/ticket/14270#comment:20
https://trac.sagemath.org/ticket/14270#comment:20
<p>
This is equality (or zero) proving in the symbolic ring, so it can be arbitrarily complex. Ignore it, yes.
</p>
TicketrwsWed, 23 Aug 2017 13:43:06 GMT
https://trac.sagemath.org/ticket/14270#comment:21
https://trac.sagemath.org/ticket/14270#comment:21
<blockquote class="citation">
<p>
... The confusion comes from the fact that things like <code>sqrt(2)(x+y)</code> almost always are typos where the <code>*</code> is missing. These should be marked as error.
</p>
</blockquote>
<p>
This is now <a class="needs_work ticket" href="https://trac.sagemath.org/ticket/23684" title="enhancement: Improve error message with some called expressions (needs_work)">#23684</a>
</p>
Ticket