symbolic functions

11 views
Skip to first unread message

YannLC

unread,
Feb 26, 2009, 3:22:09 PM2/26/09
to sage-devel
Hi,
am I doing something wrong here?
If not, this is a bug...

sage: f=function('f',x)
sage: f
f(x)
sage: g(f,x)=f(x+1)
sage: g
(f, x) |--> x + 1

Robert Bradshaw

unread,
Feb 26, 2009, 3:40:43 PM2/26/09
to sage-...@googlegroups.com

When one writes g(f, x) it creates two variables f and x, and your
original f is gone. I'm not sure what the best fix is here... There
is also the counter-intuitive

sage: f = var('f')
sage: f(3)
3

- Robert

YannLC

unread,
Feb 26, 2009, 4:15:09 PM2/26/09
to sage-devel


On Feb 26, 9:40 pm, Robert Bradshaw <rober...@math.washington.edu>
wrote:
My point was unclear.
* First, how to define a function 'g' doing what I want then? I mean
with an argument which is a function; is it possible?
* then, I think that f shouldn't disappear like this:
sage: g(f,x)=f(x)
sage: g
(f, x) |--> x

Yann

Robert Bradshaw

unread,
Feb 26, 2009, 5:14:50 PM2/26/09
to sage-...@googlegroups.com

That can't be done (yet). You can do

def g(f, x):
return x+1

But then it's a Python function, not a calculus function.

- Robert


YannLC

unread,
Feb 26, 2009, 5:28:36 PM2/26/09
to sage-devel
Forgive my stubborness, but you answered only half of my question :)
do you think the following is a sane behavior?

sage: var('f x')
(f, x)
sage: f(x+3)
x+3

I would prefer a NotImplementedError...

Yann

On Feb 26, 11:14 pm, Robert Bradshaw <rober...@math.washington.edu>

Robert Bradshaw

unread,
Feb 26, 2009, 5:35:41 PM2/26/09
to sage-...@googlegroups.com
On Feb 26, 2009, at 2:28 PM, YannLC wrote:

> Forgive my stubborness, but you answered only half of my question :)
> do you think the following is a sane behavior?
>
> sage: var('f x')
> (f, x)
> sage: f(x+3)
> x+3
>
> I would prefer a NotImplementedError...

This has come up many times, and it's unclear exactly what the best
behavior should be. What about

sage: var('x')
sage: f = x
sage: f(3)
3

Carl Witty

unread,
Feb 26, 2009, 5:42:39 PM2/26/09
to sage-...@googlegroups.com
On Thu, Feb 26, 2009 at 2:35 PM, Robert Bradshaw
<robe...@math.washington.edu> wrote:
>
> On Feb 26, 2009, at 2:28 PM, YannLC wrote:
>
>> Forgive my stubborness, but you answered only half of my question :)
>> do you think the following  is a sane behavior?
>>
>> sage: var('f x')
>> (f, x)
>> sage: f(x+3)
>> x+3
>>
>> I would prefer a NotImplementedError...
>
> This has come up many times, and it's unclear exactly what the best
> behavior should be. What about
>
> sage: var('x')
> sage: f = x
> sage: f(3)
> 3

To add a little more detail here: I'm not sure you're understanding
what's going on in your example.

Consider this:
sage: E = (x+3)*sin(x)
sage: E(5)
8*sin(5)
sage: E.subs(x=5)
8*sin(5)

So E(5) is treated as a shorthand for E.subs(x=5).

Now if we consider:


sage: var('f x')
(f, x)
sage: f(x+3)
x + 3

sage: f.subs(f=x+3)
x + 3

it's the exact same thing.

This causes trouble in other situations, as well; if you wanted
multiplication, but you left off the '*' symbol:
sage: x(x+1)
x + 1
sage: x.subs(x=x+1)
x + 1

I've argued before that this shorthand should be removed because it's
too confusing, but I haven't managed to convince enough people, so
it's still there. (The shorthand isn't there in the new, Pynac-based
symbolics, so when we switch over to that system, this particular
source of confusion will be gone.)

Carl

YannLC

unread,
Feb 26, 2009, 5:52:10 PM2/26/09
to sage-devel
Thanks for the explanation.
I definitely don't like this shortcut:

sage: var('foo bar')
(foo, bar)
sage: E = foo+bar
sage: E(5)
foo + 5

why not "bar +5" ?

but I'll learn to live with it :)

Yann

Mike Hansen

unread,
Feb 26, 2009, 5:54:22 PM2/26/09
to sage-...@googlegroups.com
On Thu, Feb 26, 2009 at 2:52 PM, YannLC <yannlaig...@gmail.com> wrote:
>
> Thanks for the explanation.
> I definitely don't like this shortcut:
>
> sage: var('foo bar')
> (foo, bar)
> sage: E = foo+bar
> sage: E(5)
> foo + 5
>
> why not "bar +5" ?
>
> but I'll learn to live with it :)

It goes by alphabetical order by default:

sage: E.variables()
(bar, foo)

--Mike

Robert Bradshaw

unread,
Feb 26, 2009, 6:26:36 PM2/26/09
to sage-...@googlegroups.com

Yes, this is strange, and one thing that I'm glad is going away. (I
like the f(...) notation, but only if there's no ambiguity to be
resolved.)

- Robert


rjf

unread,
Feb 26, 2009, 6:47:58 PM2/26/09
to sage-devel
The discussion of "lisp 1" vs "lisp 2" designs periodically occurs in
the comp.lang.lisp
newsgroup, and may be the subject of a FAQ. The Scheme dialect of lisp
is a lisp 1.
Common Lisp is a lisp 2.

The question revolves around the issue of whether there is are
separate namespaces for functions and values or do they share the same
space.

Sometimes you cannot reach consensus.

(defun foo(x cos) (cos x))
calls the cosine function , cos, in common lisp, and ignores the
second arg of foo.

(defun foo(x cos) (funcall cos x)) uses the second argument as the
function to apply.

Maxima is like a lisp 2.

foo(x,cos):=apply(cos,[x]); this is what you should say.

however, if you do this in Maxima..

foo(x, _xyzzy_) := _xyzzy_(x)

you will use the second arg for a function to apply, so long as there
is not a separately
defined function in the visible scope with the name _xyzzy_.

Does this make everyone happy? Probably not.
RJF





On Feb 26, 3:26 pm, Robert Bradshaw <rober...@math.washington.edu>
wrote:

kcrisman

unread,
Feb 26, 2009, 11:06:11 PM2/26/09
to sage-devel
> Consider this:
> sage: E = (x+3)*sin(x)
> sage: E(5)
> 8*sin(5)
> sage: E.subs(x=5)
> 8*sin(5)
>
> So E(5) is treated as a shorthand for E.subs(x=5).
>
> Now if we consider:
> sage: var('f x')
> (f, x)
> sage: f(x+3)
> x + 3
> sage: f.subs(f=x+3)
> x + 3
>
> it's the exact same thing.
>
> This causes trouble in other situations, as well; if you wanted
> multiplication, but you left off the '*' symbol:
> sage: x(x+1)
> x + 1
> sage: x.subs(x=x+1)
> x + 1

This would only be ambiguous for current Sage behavior if
ImplicitMultiplication=True, correct (if even there)? Just checking;
perhaps there are other places this notation occurs I haven't seen,
and I would be very interested in that if it were the case.

>
> I've argued before that this shorthand should be removed because it's
> too confusing, but I haven't managed to convince enough people, so
> it's still there. (The shorthand isn't there in the new, Pynac-based
> symbolics, so when we switch over to that system, this particular
> source of confusion will be gone.)

Hmm, I didn't know that. So I tried it.

sage: f=x^2
sage: f(2)
4
sage: y=var('y',ns=1)
sage: g=y^2
sage: g(2)
<long error message telling me subs doesn't work here>

So does that mean that this particular shorthand for subs will never
reappear in Pynac, or just that as currently implemented it doesn't
use it? It doesn't look all that difficult to do a check for
'unambiguity' ala Robert's comment:
sage: g.variables()==1
True
and then do something like
sage: temp=g.variables()[0]
sage: g.subs(temp=2)
4
in the symbolic/expression.pyx code. Or am I missing something? I
understand the point about multi-variable situations.

Anyway, as several have commented, this discussion has taken place
many times before, but having to use
sage: f(x)=x^2
instead of
sage: f=x^2
many times for single-variable symbolic expressions could be very
annoying in the long run, IMHO. Let's not be stultified by trying to
solve computer problems when this is mathematical software; the
distinction between symbolic and callable-symbolic seems different to
me than e.g. formal power series versus actually convergent ones.
FWIW.

- kcrisman

Carl Witty

unread,
Feb 26, 2009, 11:38:26 PM2/26/09
to sage-...@googlegroups.com

I'm not sure what you're trying to say here. Are you saying that
since x(x+1) has no other useful meaning, we might as well make it
mean x+1?

I hope that the shorthand does not come back, but I don't know that
any sort of final decision has been made. I don't think it's
technically difficult to implement, I just think it's a bad idea.

> Anyway, as several have commented, this discussion has taken place
> many times before, but having to use
> sage: f(x)=x^2
> instead of
> sage: f=x^2
> many times for single-variable symbolic expressions could be very
> annoying in the long run, IMHO.  Let's not be stultified by trying to
> solve computer problems when this is mathematical software; the
> distinction between symbolic and callable-symbolic seems different to
> me than e.g. formal power series versus actually convergent ones.
> FWIW.

I don't understand this paragraph at all. What problem are you
talking about? The problem I see is that people are confused when
x(x+1) gives them (x+1); I wouldn't call that a computer problem
exactly.

Carl

William Stein

unread,
Feb 26, 2009, 11:55:14 PM2/26/09
to sage-...@googlegroups.com

I also think it is a bad idea, and I believe that Burcin and I decided
(as a "final decision") that the shorthand will not be in the new
Pynac. I think it was a condition for Burcin to keep working on the
new Pynac in fact :-).

I'm amazed that implicit calling of symbolic expressions is still in
Sage. I knew that it absolutely *had* to go while watching repeatedly
the problems it causes in the high school students in a summer course
I taught using Sage over a year ago.

>> Anyway, as several have commented, this discussion has taken place
>> many times before, but having to use
>> sage: f(x)=x^2
>> instead of
>> sage: f=x^2
>> many times for single-variable symbolic expressions could be very
>> annoying in the long run, IMHO.  Let's not be stultified by trying to
>> solve computer problems when this is mathematical software; the
>> distinction between symbolic and callable-symbolic seems different to
>> me than e.g. formal power series versus actually convergent ones.
>> FWIW.
>
> I don't understand this paragraph at all.  What problem are you
> talking about?  The problem I see is that people are confused when
> x(x+1) gives them (x+1); I wouldn't call that a computer problem
> exactly.

Just out of curiosity, do you think we should also get rid of this?

sage: R.<x> = ZZ[]


sage: x(x+1)
x + 1

-- William

Jason Grout

unread,
Feb 27, 2009, 12:05:06 AM2/27/09
to sage-...@googlegroups.com
Carl Witty wrote:

>> Anyway, as several have commented, this discussion has taken place
>> many times before, but having to use
>> sage: f(x)=x^2
>> instead of
>> sage: f=x^2
>> many times for single-variable symbolic expressions could be very
>> annoying in the long run, IMHO. Let's not be stultified by trying to
>> solve computer problems when this is mathematical software; the
>> distinction between symbolic and callable-symbolic seems different to
>> me than e.g. formal power series versus actually convergent ones.
>> FWIW.
>
> I don't understand this paragraph at all. What problem are you
> talking about? The problem I see is that people are confused when
> x(x+1) gives them (x+1); I wouldn't call that a computer problem
> exactly.

I agree with Carl. I can't count how many times I've thought I would be
annoyed by being more explicit (i.e., saying f(x)=x^2 instead of f=x^2),
but it turned out to be not that bad. I also can't count the number of
times that I've been glad and relieved that I was explicit when I came
back and read or modified my code (i.e., suppose I want to change
f=x^2+1 to f=x^2+c to analyze what happens when c changes? Now I have
to go back through and change all of my code from f(1) to f(x=1)!).

I very much support what pynac is doing, which to my understanding, is this:

f(x,y) = x^2+y # explicitly ordered parameters
f(-1,2) then gives 3

f=x^2+y # no explicit parameters for f, so they must be specified
f(x=-1,y=2) then gives 3
f(-1,2) gives an error
f.subs(x=-1,y=2) then gives 3

I think having x(x+1) return x+1 is a far greater annoyance than having
to explicitly write f(x)=x;f(x+1) or x.subs(x=x+1) or even x(x=x+1), all
of which would hardly be written as an innocent-looking mistake.

I'm always telling my students to not leave off the "dx" in an integral,
even though there is only one variable, since it is so very important
when we introduce other parameters or move to multivariable calculus. I
try to use d/dt notation for derivatives because it is more explicit
about what variable I'm dealing with, even if initially we only see one
variable. I think there are great benefits for three more keystrokes
(i.e., "(x)") in the definition of a function if it makes things much
more explicit and easy for anyone to understand and takes away
innocent-looking errors that almost surely will trip new users up.

Gee, the last few paragraphs sound a lot more rant-like than I intended.
I wasn't trying to pick on anyone. I guess I was just realizing how
strongly I support what I think are the conventions introduced by pynac.

Thanks,

Jason

Rob Beezer

unread,
Feb 27, 2009, 12:09:02 AM2/27/09
to sage-devel
+1

Carl Witty

unread,
Feb 27, 2009, 12:08:56 AM2/27/09
to sage-...@googlegroups.com
On Thu, Feb 26, 2009 at 8:55 PM, William Stein <wst...@gmail.com> wrote:
> Just out of curiosity, do you think we should also get rid of this?
>
> sage: R.<x> = ZZ[]
> sage: x(x+1)
> x + 1

Ouch, that's a tougher question, since I actually use that construct :)

But since I don't want to be a total hypocrite, I'm going to say yes,
we should get rid of it. (With a deprecation message -- eventually to
be replaced by an error message -- that gives the recommended
replacement.)

So, should I prepare patches that deprecate implicit calling of
symbolics and of polynomials? (Would they be likely to be accepted?)

Carl

William Stein

unread,
Feb 27, 2009, 12:24:58 AM2/27/09
to sage-...@googlegroups.com
On Thu, Feb 26, 2009 at 9:08 PM, Carl Witty <carl....@gmail.com> wrote:
>
> On Thu, Feb 26, 2009 at 8:55 PM, William Stein <wst...@gmail.com> wrote:
>> Just out of curiosity, do you think we should also get rid of this?
>>
>> sage: R.<x> = ZZ[]
>> sage: x(x+1)
>> x + 1
>
> Ouch, that's a tougher question, since I actually use that construct :)

:-) One possibility would be that if f is a polynomial over a ring R, then
f(a) is defined when a is canonically convertible to R, but raises an error
otherwise. Then x(x+1) would give an error, but x(5) would give 5.

> But since I don't want to be a total hypocrite, I'm going to say yes,
> we should get rid of it.  (With a deprecation message -- eventually to
> be replaced by an error message -- that gives the recommended
> replacement.)
>
> So, should I prepare patches that deprecate implicit calling of
> symbolics and of polynomials?  (Would they be likely to be accepted?)

Definitely for symbolics. I'm less clear about the situation for
polynomials. Regarding symbolics, I think we should definitely do
this before the Pynac switchover -- i.e., the sooner the better. That
will make the pynac switchover smoother.

William

Robert Bradshaw

unread,
Feb 27, 2009, 12:33:51 AM2/27/09
to sage-...@googlegroups.com
On Feb 26, 2009, at 9:08 PM, Carl Witty wrote:

>
> On Thu, Feb 26, 2009 at 8:55 PM, William Stein <wst...@gmail.com>
> wrote:
>> Just out of curiosity, do you think we should also get rid of this?
>>
>> sage: R.<x> = ZZ[]
>> sage: x(x+1)
>> x + 1
>
> Ouch, that's a tougher question, since I actually use that
> construct :)
>
> But since I don't want to be a total hypocrite, I'm going to say yes,
> we should get rid of it.

I'm would vote no, that would be pedantic to the point of reducing
usability. My justification is that ZZ[x] can be viewed as the set of
rational functions from Z to Z, much closer to the "f(x) = x^2+1"
than "f = x^2+1" construction. There is a well-defined "input
variable" for all elements of ZZ[x], even constant ones, unlike the
"symbolic ring" where the "inputs" are not well defined.

However, what about plot(x^2, 0, 10)? I can see that plot(x^2, (x, 0,
10)) would still work...

BTW, the the issue of implicit multiplication came up. It would not
accept "x(x+1)"--it only handles cases that are otherwise invalid
syntax, like "2x".

> (With a deprecation message -- eventually to
> be replaced by an error message -- that gives the recommended
> replacement.)
>
> So, should I prepare patches that deprecate implicit calling of
> symbolics

Yes.

Carl Witty

unread,
Feb 27, 2009, 1:08:25 AM2/27/09
to sage-...@googlegroups.com

I'm having a hard time coming up with good wording for the deprecation
message. This is what I've got so far; any suggestions for
improvements?

"Doing substitutions by calling a symbolic expression is deprecated;
use EXPR.subs(x=..., y=...) instead"

Is there a way to make it clear in this message that we're not
deprecating EXPR(x=...)? (At least I assume we're not.)

And should the recommended replacement be EXPR.subs(x=..., y=...) or
EXPR(x=..., y=...)?

Carl

Stan Schymanski

unread,
Feb 27, 2009, 4:26:41 AM2/27/09
to sage-...@googlegroups.com
Dear all,

I am so glad to hear that the implicit substitutions are going to go! It
is so much clearer to write e.g.

var('a b c x')
f = a*x^2 + b*x + c
f(x=4,a=1,b=3,c=2)

rather than

f(1,3,2,4)

to get the desired result. Most people I know got burned with implicit
assumptions in Fortran until they learned to always put 'implicit none'
at the top of their code.

While talking about substitutions, could someone have a look at thread
http://groups.google.com/group/sage-support/browse_thread/thread/0f1086c43611242a?

It seems that subs(locals()) still causes problems and I am sure you are
the right people to fix it. Sorry for distracting from the issue at hand. :)

All the best,
Stan
--
________________________________________

Stan Schymanski
Scientist
Max Planck Institute for Biogeochemistry
Postfach 10 01 64
D-07701 Jena

Phone: +49.3641.576264
Fax: +49.3641.577274
WWW: http://www.bgc-jena.mpg.de/~sschym

Biospheric Theory and Modelling Group
http://www.bgc-jena.mpg.de/bgc-theory/
_________________________________________

Jason Grout

unread,
Feb 27, 2009, 5:29:20 AM2/27/09
to sage-...@googlegroups.com

Can't you put both?

"Doing substitutions by calling a symbolic expression is deprecated;

use EXPR(x=...,y=...) or EXPR.subs(x=..., y=...) instead"

Or

"Function evaluation of symbolic expressions without specifying
variables is deprecated; use EXPR(x=...,y=...), or EXPR.subs(x=...,
y=...), or explicitly give the order of variables by using f(x,y)=EXPR;
f(xvalue, yvalue)"

Jason

kcrisman

unread,
Feb 27, 2009, 10:47:17 AM2/27/09
to sage-devel
Jason's argument is interesting. I'll think about that one; if good
math and good programming go together, it should probably be done.
Anyway, the decision is made.

But I'm not sure that x(x+1) being x+1 is as much of a problem; does x
(x+1) have any meaning in the current Sage framework other than
calling something? Since one already has to use * for multiplication
in pretty much any context, this is a learning curve already met by
trying something like integrate(2*x). f=x^2 versus f(x)=x^2 isn't in
the same category.

> However, what about plot(x^2, 0, 10)? I can see that plot(x^2, (x, 0,  
> 10)) would still work...

Same thing with integrate(x^2,0,1) versus integrate(x^2,x,0,1). Is it
pretty easy to change plot/integrate/diff/etc. so that symbolic
expressions with one variable are automatically changed to callable
symbolic expressions in order to use these things? It would be
unfortunate to lose this capability.

As for the polynomial/symbolic question, I understand the composition
argument. This still seems weird to me, though, since polynomials are
really no more callable than single-variable symbolic expressions; in
fact, they ARE single-variable callable expressions of a particular
module form, don't you think? It is case where len(f.variables())==1
that seems quite different to me, because as I mention above things
like x(x+1) already have no Sage meaning.

sage: R.<y> = ZZ[]
sage: g=y^2
sage: g(2)
4
sage: z=var('z',ns=1)
sage: h=z^2
sage: h(2)
---------------------------------------------------------------------------
TypeError Traceback (most recent call
last)

Especially because the distinction is not clear in the tutorial
regarding this. Even the error message is a little unhelpful:

sage: 2x
------------------------------------------------------------
File "<ipython console>", line 1
2x
^
SyntaxError: invalid syntax

In fact, I can't find a reference to the fact that 2x should yield an
error in Chapter 2 of the tutorial; this and the distinction above
should be very prominent in that, because it will not be obvious at
all. Will the tutorial, cookbook, etc. be available to edit via
hg_sage after the 3.4 transition? Not that it be said I am unwilling
to help clarify all this to newcomers :)

- kcrisman

Carl Witty

unread,
Feb 27, 2009, 11:24:44 AM2/27/09
to sage-...@googlegroups.com
On Fri, Feb 27, 2009 at 2:29 AM, Jason Grout
<jason...@creativetrax.com> wrote:
> Can't you put both?
>
> "Doing substitutions by calling a symbolic expression is deprecated;
> use EXPR(x=...,y=...) or EXPR.subs(x=..., y=...) instead"
>
> Or
>
> "Function evaluation of symbolic expressions without specifying
> variables is deprecated; use EXPR(x=...,y=...), or EXPR.subs(x=...,
> y=...), or explicitly give the order of variables by using f(x,y)=EXPR;
> f(xvalue, yvalue)"

Hmm... if I saw one of those messages, probably my first response
would be to go look up in the documentation what the difference
between EXPR(x=..., y=...) and EXPR.subs(x=..., y=...) was, followed
by slight annoyance because I wasted my time once I discovered they
were the same. But maybe that's just because I'm strange.

That's why I'd rather not put both, anyway.

Carl

Jason Bandlow

unread,
Feb 27, 2009, 1:20:34 PM2/27/09
to sage-...@googlegroups.com

<my 2 cents>

What about


"Doing substitutions by calling a symbolic expression is deprecated;

use EXPR(x=...,y=...) or equivalently EXPR.subs(x=..., y=...) instead"
?

That way people who prefer one idiom over the other will see the one
they like, and hopefully nobody is confused into thinking they are
different.

</my 2 cents>

Cheers,
Jason Bandlow

Nick Alexander

unread,
Feb 27, 2009, 1:37:11 PM2/27/09
to sage-...@googlegroups.com
> "Doing substitutions by calling a symbolic expression is deprecated;
> use EXPR(x=...,y=...) or equivalently EXPR.subs(x=..., y=...) instead"

I like the "equivalently", but EXPR(x=...) *is* calling a symbolic
expression -- both EXPR(1) and EXPR(x=1) go through the __call__
method. This is contradictory to someone who knows the Python
internals.

Nick

Carl Witty

unread,
Feb 27, 2009, 1:59:54 PM2/27/09
to sage-...@googlegroups.com

One more message about why I don't like mentioning both, and then I'll
shut up on that topic:

"... people who prefer one idiom over the other...": How is our
presumed beginning Sage user supposed to choose one over the other, if
we can't? Flip a coin?

Nick Alexander's point about EXPR(x=...) actually being a call is
another reason to not mention both options. That could presumably be
fixed with a wording change, but I also have a preference for not
including a multi-paragraph essay in the warning message :)

Carl

Nick Alexander

unread,
Feb 27, 2009, 2:08:02 PM2/27/09
to sage-...@googlegroups.com
> Nick Alexander's point about EXPR(x=...) actually being a call is
> another reason to not mention both options. That could presumably be
> fixed with a wording change, but I also have a preference for not
> including a multi-paragraph essay in the warning message :)

If we want short and sweet, just say: "... is deprecated: use ...".

Nick

Carl Witty

unread,
Mar 1, 2009, 1:04:39 PM3/1/09
to sage-...@googlegroups.com
On Thu, Feb 26, 2009 at 9:08 PM, Carl Witty <carl....@gmail.com> wrote:
> So, should I prepare patches that deprecate implicit calling of
> symbolics and of polynomials?  (Would they be likely to be accepted?)

OK, I've posted a patch that deprecates implicit calling of symbolics
(not polynomials) at
http://trac.sagemath.org/sage_trac/ticket/5413

Interested parties can look at the patch there and see how much
syntactic overhead it adds to avoid the deprecation warnings (not
much, IMHO). Also, there's one set of warnings that I didn't fix (in
piecewise.py); any suggestions on the right thing to do there would be
welcome.

Carl

Reply all
Reply to author
Forward
0 new messages