Opened 8 years ago

# Remove function call syntax for symbolic expressions — at Version 12

Reported by: Owned by: ppurka burcin major sage-8.2 symbolics nthiery, kini Punarbasu Purkayastha N/A fix combinat/tutorial.py

The function call syntax for symbolic expressions has been deprecated for over four years. It is about time it raised some errors. This will prevent people from getting confused because of behavior like this.

Apply trac_14270-raise_error_on_function-call.patch to devel/sage.

### comment:1 Changed 8 years ago by ppurka

• Authors set to Punarbasu Purkayastha
• Description modified (diff)
• Status changed from new to needs_review

### comment:2 Changed 8 years ago by ppurka

• Status changed from needs_review to needs_work
• Work issues set to fix doctests

### comment:3 follow-up: ↓ 4 Changed 8 years ago by ppurka

• Work issues changed from fix doctests to fix combinat/tutorial.py

I am able to fix all the doctests except for the following one in combinat/tutorial.py.

The example which fails seems to make no sense to me. A `substitute_function` method is being used to substitute a function with a symbolic expression.

```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

...

(4*z - 1)*D[0](C)(z) - 2*C(z) + 1 == 0
sage: Cf = sage.symbolic.function_factory.function('C')
...
TypeError: %d format: a number is required, not NoneType
```

Let us try to "fix" this (`z` is a symbolic variable). Somehow the following works (beats me why it does):

```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
```

But now the next command in the tutorial gives `False` instead of `True`

```sage: bool(equadiff.substitute_function(Cf(z), s0))
False
```

Why is all this happening? Looking at the documentation of `substitute_function` shows that it should be used for substituting functions, not anything else

```    def substitute_function(self, original, new):
"""
Returns this symbolic expressions all occurrences of the
function *original* replaced with the function *new*.
```

And what exactly are we substituting above?

```sage: type(Cf)
sage.symbolic.function_factory.NewSymbolicFunction
sage: type(s0)
sage.symbolic.expression.Expression
```

We are substituting a symbolic function with a symbolic expression! How was this even working earlier?

What should I do with this portion of the tutorial? Delete this?

### Changed 8 years ago by ppurka

Apply to devel/sage

### comment:4 in reply to: ↑ 3 Changed 8 years ago by kcrisman

I am able to fix all the doctests except for the following one in combinat/tutorial.py.

<snip>

What should I do with this portion of the tutorial? Delete this?

I'm cc:ing Nicolas, who should know what is going on here.

### comment:5 follow-up: ↓ 6 Changed 8 years ago by kcrisman

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) why 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 would one do the matrix example `h(x)` now? We should be careful not to remove anything, just to change how it works to the appropriate way post-this-ticket.

Rant I don't actually want to rehash any more, but put here for completeness:

<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 `var` 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 `x+y-y` is one variable) it seems worth the potential for confusion... </rant>

### comment:6 in reply to: ↑ 5 Changed 8 years ago by ppurka

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) why this doesn't work, because a lot of people will now and forevermore expect that it will work.

IMHO, the people who expect this to still 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.

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 `f(x) = x^2`? The most natural thing would be to do `f(2)` or something similar to "see" that it can actually evaluate. Now imagine the same with `f = x^2` 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.

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.

### comment:8 Changed 7 years ago by jdemeyer

• Milestone changed from sage-5.11 to sage-5.12

### comment:9 Changed 7 years ago by vbraun_spam

• Milestone changed from sage-6.1 to sage-6.2

### comment:10 Changed 7 years ago by vbraun_spam

• Milestone changed from sage-6.2 to sage-6.3

### comment:11 Changed 6 years ago by vbraun_spam

• Milestone changed from sage-6.3 to sage-6.4

### comment:12 Changed 6 years ago by rws

• Description modified (diff)

This is actually the same as #8214, but that has no code, so I'm copying the two links from there to here before declaring it a dupe.

Note: See TracTickets for help on using tickets.