Sage: Ticket #15025: automatically injected function does not work with desolve
https://trac.sagemath.org/ticket/15025
<p>
The following does not work:
</p>
<pre class="wiki">sage: x = var('x')
sage: f = function('y', x)
sage: desolve(diff(y,x)-y == 0,y)
Traceback (click to the left of this block for traceback)
...
TypeError
</pre><p>
altough <code>y</code> is automatically injected to the gobal namespace.
</p>
<p>
This is because <code>y</code> is of the wrong type:
</p>
<pre class="wiki">sage: f, type(f)
(y(x), sage.symbolic.expression.Expression)
sage: y, type(y)
(y, sage.symbolic.function_factory.NewSymbolicFunction)
</pre><p>
It works with <code>f</code>:
</p>
<pre class="wiki">sage: desolve(diff(f,x)-f == 0,f)
c*e^x
</pre><p>
This is confusing, especially, since in the docstring of <code>function</code> under "Note" you can find
</p>
<blockquote class="citation">
<blockquote>
<p>
The new function is both returned and automatically injected into the global namespace.
</p>
</blockquote>
</blockquote>
<p>
Therefore, it is not absurd to assume that this automatically injected variable is the one I want to use, i.e. the one you would get by <code>y = function('y', x)</code> (similar to the <code>var</code>-command).
</p>
<p>
(If this is behavior of <code>function</code> is (really) on purpose, then at least the error message of <code>desolve</code> should be more clearifying and give a hint.)
</p>
en-usSagehttps://trac.sagemath.org/chrome/site/logo_sagemath_trac.png
https://trac.sagemath.org/ticket/15025
Trac 1.1.6nbruinSat, 10 Aug 2013 17:47:02 GMT
https://trac.sagemath.org/ticket/15025#comment:1
https://trac.sagemath.org/ticket/15025#comment:1
<p>
It seems what gets injected and what gets returned is always an issue. On top level,
</p>
<pre class="wiki">x = var('x')
</pre><p>
is redundant: <code>var('x')</code> already injects the binding. On the other hand,
</p>
<pre class="wiki">t = SR.var('t')
</pre><p>
is not redundant because the methods on <code>SR</code> do not have injection side effects.
</p>
<p>
Looking at the side-effect free methods:
</p>
<pre class="wiki">sage: from sage.symbolic.function_factory import function as new_function
sage: new_function('g')
g
sage: new_function('g',x)
g(x)
sage: type(new_function('g'))
sage.symbolic.function_factory.NewSymbolicFunction
sage: type(new_function('g',x))
sage.symbolic.expression.Expression
</pre><p>
you see the design problem: The routine that constructs new symbolic functions creates entirely different objects depending on the arguments given.
</p>
<p>
A <code>NewSymbolicFunction</code> is really a different kind of object: it goes into the "operator" slot of symbolic expressions:
</p>
<pre class="wiki">sage: (y(x)).operator()
y
sage: (2*x).operator()
<function operator.mul>
</pre><p>
I understand how the shorthand <code>new_function('f',x)</code> was considered convenient, but it really muddles the interface and it's only one character shorter than the unambiguous <code>new_function('f')(x)</code>.
</p>
<p>
The confusion is compounded by the top-level <code>function</code> which does inject the function into the global namespace as well, but both <code>function('f')</code> and <code>function('f',x)</code> inject the same thing into the global namespace: the <a class="missing wiki">NewSymbolicFunction?</a>. It has to do that because after typing either, one would expect f(x) to work. But it does raise the expectation that after declaring <code>function('f',x)</code>, the system would somehow know that even the bare function <code>f</code> has something to do with <code>x</code>. It doesn't:
</p>
<pre class="wiki">sage: var('t')
t
sage: function('f',t)
f(t)
sage: f.number_of_arguments()
0
sage: f.variables()
()
sage: f.default_variable()
x
</pre><p>
You would get the same results from <code>function('f')</code>.
</p>
<p>
For the problem at hand in this ticket: The problem is that <code>desolve</code> really wants a symbolic expression, and that there's no good way of turning a bare function into a symbolic expression: It might try
</p>
<pre class="wiki">f( *(f.default_variable() for i in range(f.number_of_arguments())))
</pre><p>
but you'll quickly see why that's a senseless try.
</p>
<p>
<strong>IN SHORT:</strong>
</p>
<ul><li>The interface for <code>function</code> leads to wrong expectations by the user
</li><li>The writer of the documentation of <code>function</code> was equally confused
</li><li><code>desolve</code> should return a more informative error message when the given argument cannot be turned into a symbolic expression.
</li></ul>
Ticketvbraun_spamThu, 30 Jan 2014 21:20:52 GMTmilestone changed
https://trac.sagemath.org/ticket/15025#comment:2
https://trac.sagemath.org/ticket/15025#comment:2
<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/15025#comment:3
https://trac.sagemath.org/ticket/15025#comment:3
<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/15025#comment:4
https://trac.sagemath.org/ticket/15025#comment:4
<ul>
<li><strong>milestone</strong>
changed from <em>sage-6.3</em> to <em>sage-6.4</em>
</li>
</ul>
TickettmonteilFri, 30 Jan 2015 12:26:50 GMT
https://trac.sagemath.org/ticket/15025#comment:5
https://trac.sagemath.org/ticket/15025#comment:5
<p>
A similar problem was just hit on <a class="ext-link" href="http://ask.sagemath.org/question/25641/typeerror-in-creating-ode-variable/"><span class="icon"></span>this ask question</a>.
</p>
<p>
The bug is about wrong variable injection (the value injected into the Python variable does not correspond to the returned value, while it is claimed), not about <code>desolve</code>:
</p>
<pre class="wiki">sage: z = function('y', x)
sage: y
y
sage: z
y(x)
sage: y == z
False
sage: type(y)
<class 'sage.symbolic.function_factory.NewSymbolicFunction'>
sage: type(z)
<type 'sage.symbolic.expression.Expression'>
</pre><p>
Besides fixing this bug, i have nothing against removing automatic variable injection from Sage (which seems to concern only <code>var()</code> and <code>function()</code>), since it creates a lot of confusion between symbolic and Python variables among new users, for example we can see a lot of <code>var('n') ; n=2</code> on ask.sagemath.org, as if <code>var()</code> was a kind of variable declaration.
</p>
<p>
As for the <code>NewSymbolicFunction</code> vs <code>Expression</code> issue depending on the arguments of <code>function()</code>, our options are:
</p>
<ul><li>create two distinct Python functions for the two situations,
</li><li>deprecate the use of <code>function('y', x)</code>,
</li><li>do not touch anything and provide a better documentation in the <code>function()</code> function.
</li></ul><p>
I like the second one since it goes towards better consistency. But, as for removing the ugly <code>var()</code> (or even the ugly <code>RR</code> that breaks the <code>RDF</code>, <code>RIF</code>, <code>RLF</code> naming scheme and causes meaningless discussions about whether <code>Infinity</code> or <code>NaN</code> belong to it), i expect not everyone to agree, even if this would help newcomers to grasp Sage's logic.
</p>
TicketrwsFri, 30 Jan 2015 14:42:47 GMT
https://trac.sagemath.org/ticket/15025#comment:6
https://trac.sagemath.org/ticket/15025#comment:6
<p>
See also <a class="closed ticket" href="https://trac.sagemath.org/ticket/17447" title="enhancement: Clarify and complete documentation of function() (closed: fixed)">#17447</a>, <a class="needs_info ticket" href="https://trac.sagemath.org/ticket/14270" title="defect: Remove function call syntax for symbolic expressions (needs_info)">#14270</a>
</p>
<p>
FWIW, in Sympy <code>Function</code> creates an <code>UndefinedFunction</code> which is clear enough, and you get simply
</p>
<pre class="wiki">In [2]: f = Function('f',x)
...
TypeError: __new__() takes exactly 2 arguments (3 given)
</pre>
TickettmonteilFri, 30 Jan 2015 15:05:12 GMT
https://trac.sagemath.org/ticket/15025#comment:7
https://trac.sagemath.org/ticket/15025#comment:7
<p>
Thanks for the pointers !
</p>
TicketrwsSat, 19 Mar 2016 15:45:08 GMTstatus, milestone changed
https://trac.sagemath.org/ticket/15025#comment:8
https://trac.sagemath.org/ticket/15025#comment:8
<ul>
<li><strong>status</strong>
changed from <em>new</em> to <em>needs_review</em>
</li>
<li><strong>milestone</strong>
changed from <em>sage-6.4</em> to <em>sage-duplicate/invalid/wontfix</em>
</li>
</ul>
<p>
I think it's a duplicate of <a class="needs_work ticket" href="https://trac.sagemath.org/ticket/17701" title="defect: diff(f,t) should work even with Function objects (needs_work)">#17701</a> (ready for review). True?
</p>
Ticket