- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 565
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement declare_var, deprecate (None)var #17958
Comments
This comment has been minimized.
This comment has been minimized.
comment:3
Does sage really need a version of |
comment:4
Not really need but:
That's those over 20 in EDIT: grep for 'sage: var(' shows 338 hits in 67 files... |
comment:5
I should have looked sooner: the catch is, I removed the EDIT: Noo, that's wrong, it's the expression on the lhs that gets injected! I still have to find a case where injection of the variable itself matters. |
comment:6
I think I don't understand what you mean:
|
comment:7
Sorry, I should say... where injection via |
comment:8
The name Vincent |
comment:10
Replying to @egourgoulhon:
+1 as well, the name "variable" causes a lot of troubles to newcommers that use By the way, note the difference between
and
So perhaps should we also make a difference between |
comment:11
How about something like |
comment:12
Replying to @vbraun:
Yes, that's probably better that the syntax I suggested. |
comment:13
Replying to @videlec:
Definitely not |
comment:14
Replying to @vbraun:
Actually
This is non-pythonic, requires additional preparsing, needs to create the name Replying to @mezzarobba:
The benefits are very significant for newcomers and anyone that interacts with newcomers, i personally spent a huge amount of time to deal with that issue (on ask.sagemath.org (see my previous link for a small sample) but also during tutorials). Sage is full of inconsistencies, refusing to clean them because they are used increases the entry cost and will eventually lead to an obscure language where each function/method has its own semantics. This is not long-term viable. This is why we have a deprecation policy. For such a function, we could make the deprecation message more verbose and pedagogical than usual. |
comment:15
Thierry, I agree fully but:
But it would be consistent and allow different ring types (later). Actually |
comment:16
Replying to @sagetrac-tmonteil:
I don't care much about "pythonicity", but what Volker suggests would be consistent with the rest of Sage. And since this is all for interactive use anyway, I don't see the problem with using the preparser, nor with writing From a pedagogical point of view, it might actually be a good thing to make it clearer that
I tend to agree in general, but I am not convinced in this particular case. Having a longer function name is inconvenient, and I find
The deprecation policy is a joke... Except perhaps for a few
Yes, but please keep in mind that it will pop up everywhere for a long time. |
comment:17
Replying to @vbraun:
No, it does not:
The problem with the mixed actions of If we have two routines, one that only returns a symbol and the other that only injects a binding, this potential for surprise is eliminated. I think we do want the possibility of injecting something, because We need the injection capability on toplevel because this is one of the first things that novices need to be able to do. I'm not completely sure we need an entry to
They probably shouldn't. At least one of them should be 'make a symbol with the given print name or raise an error'. The fact that the return type of
Cute, but I think it misses the mark for the intended audience: complete novices. It makes it very hard to convince people that Sage is a reasonable choice relative to Maple and Mathematica (and Maxima), where you can just start using a symbol. |
comment:18
Replying to @mezzarobba:
It is not consistent with the rest of sage and hard to implement, since presently it amounts to
and we would need to hack The scenario really doesn't fit in the current meaning of |
comment:19
Replying to @nbruin:
I mean from a UI point of view. Otherwise, sure, it would require the preparser to repeat the names when asking for the generators, or something similar. Is there another variant that you like better? |
comment:20
Remember that defining a new mathematical variable might be the first thing that a new Sage user will want to do, so from a UI point of view, Maybe something like |
comment:21
Replying to @jhpalmieri:
Well, then, form that point of view, I find |
comment:22
Re Remember that we have users who just want to do calculus. They don't know what a ring is. They also are not that familiar with Python, and we shouldn't use this particular situation to educate them on Python syntax. So I think we need a top-level function. The proposed The name |
comment:23
Replying to @jhpalmieri:
I doubt you can use sage (and not shoot yourself in the foot on every possible occasion) without understanding this kind of things at least a little. And for sure I've seen intelligent people with a very reasonable level in math, use sage in teaching while completely misunderstanding how basic things work... because, at first, they just wanted to do calculus, so they were led to use things like
|
comment:24
Replying to @mezzarobba:
You can do some very simple examples, such as differentiating a function, plotting one, trying to compute an antiderivative without understanding the way python names (really, python has "names" in its namespaces. Variables have other connotations) and SR symbols interact; sort of the level of "wolfram alpha". We have to give people at that level at least a way into sage, otherwise they don't even get to shoot themselves in the foot, experience that as unpleasant and then gain the motivation to learn how to avoid that in the future. There's a reason why maple, mathematica, maxima went with their approach. We can't quite do that, but we have to make the hurdle as low as possible. I think
or
are about the best we can do. I think it's a problem they return something in addition to injecting a binding. If we need to produce feedback on the action taken, I think printing something would be preferable (it's a routine that's only meant to be used interactively anyway), so perhaps:
(where the I'd be completely OK with |
comment:26
So i can imagine how much more there will be with What is currently discussed is a function that injects a symbol into the namespace, so As for the I agree that in any case, both injecting and returning is harmful ( |
comment:27
Replying to @sagetrac-tmonteil:
Except that "inject" is rather technical and not what the novice thinks about doing. You'd probably have to explain to them: "Before using y, you have to declare that it is a math symbol, which you do by I indeed agree that using "symbol" instead of "symbolic variable" would be better to distinguish the concept from a python name. However, we've been calling these things "var" since the start of sage, so changing that may be painful for our current users.
There the terminology is even worse: python actually calls its "def" and "lambda" objects "functions". So "declare_function" will be even more confusing than "declare_var". A minimal plan is to either not have
or let
If neither one is palatable then we can stop the discussion now. We're stuck with a bad design decision, for which the pain for repairing it is too high. An alternative is to migrate to the unspoilt
and let For |
comment:41
Replying to @mezzarobba:
You'd need to take into account that the By making
This is comparable to why in Python3 print was turned into a function. Otherwise I like the missing quotes in the syntax; I dislike having to explain what the modulo or string formatting sign is doing at the start of a line when you're explaining to someone that sage is "just like python" (should they know that already).
|
comment:42
Replying to @nbruin:
Exactly, and that is IMHO a big plus of the proposal. Even right row you are not supposed to use |
comment:43
PS: The Sage doctests are preparsed but not run in IPython. So |
This comment has been minimized.
This comment has been minimized.
comment:45
NOTE: I am making changes to the implementation of |
comment:46
Replying to @vbraun:
Is that spelled out? I looked at sage.calculus.var.var? (that's the var that also occurs at top-level) and didn't find it there. I don't think a programmatic approach to injecting A possible scenario:
which actually illustrates a genuine use of "inject as well as return". D'oh. |
comment:47
The var docstring (
|
comment:48
See also #18084. |
comment:49
Replying to @vbraun:
Yes that's for use in the library. The problem with Reducing support for that would be a reduction in functionality. If the advantages of |
comment:50
Oh you mean the good old
would probably be a lot better. |
comment:51
Something along these lines would MASSIVELY help with this issue. As long as we have to declare variables anyway, we should at least make it easy to do so, and the syntax currently is kind of hard to type
(try this on a qwerty board slowly to see all the unusual movements due to the shifts and non-home row things) so it would definitely be so for a beginner. As long as there is a LONG deprecation period for this (as it's likely to bite quite a few people who wouldn't upgrade very frequently) something along these lines seems fine, return value |
comment:52
I would favor an "infinite" deprecation period for |
comment:53
Seems reasonable. |
comment:54
Replying to @vbraun:
Something like that would work, but probably not under that name. The method already exists on Injecting in general isn't really a method that belongs on the object, since the object doesn't naturally have access to the dictionary into which these things should be injected. It's really more the task of a REPL utility function. In which case the spelling
would make more sense. The magic of figuring out into which dictionary the bindings should be injected is compartmentalized into a single function which could be implemented basically as
This probably much nicer than scattering references to user_globals all over the place (we'd probably want to add some sanity checks to prevent this from inserting objectionable bindings). For symbolic binding we could then have something along the lines of
Interfacing via In short, what we seem to be converging towards is:
There is some further rationalization around injection behaviour possible. |
comment:55
I've announce this discussion on sage-devel https://groups.google.com/forum/#!topic/sage-devel/iy8Ck6BbhSE |
comment:56
I'm against deprecating var. It is also common for a Python function to do something with side effects -- e.g., run a subprocess -- and also return some information about what it did, e.g., the exit code. This is computer programming, not mathematics. I prefer
to
by the way, since we have been generally deprecated non-% special commands. I was annoyed at first by, e.g., Jason Grout doing this, but I've come around. |
comment:57
os.system is a terrible example, its just a syscall wrapper. The subprocess module precisely tries to improve that interface by giving you separate check_output / check_call functions so you can create subprocesses in a more pythonic manner. |
comment:58
Replying to @williamstein:
I thought something similar originally as well (although I thought "this is mathematics software, not computer programming"), but after seeing several questions from people getting thoroughly confused, I came to the conclusion that in this case having a side effect and a return value is a major source of confusion. See the original comment We really need to decide if deprecating the current behaviour of |
comment:59
|
comment:60
I won't approve of Anyhow, I don't understand what |
comment:61
Replying to @dimpase:
Calculus. |
comment:62
To get this back on track, the minimal change that would satisfactorily resolve the issue would be a warning (but keep
and
The latter would also have to work in doctests where percent-magics currently do not work. |
comment:63
Replying to @vbraun:
I think this would be an improvement, so I'd be in favour if this change, even as proposed. Some details:
|
comment:64
Replying to @nbruin:
An option may be to print it using |
comment:65
Replying to @williamstein:
I don't think it's precise enough; for myself I understand |
comment:66
Replying to @dimpase:
To repeat what I said on #15605, I for one basically view symbolic expressions as straight-line programs that are just required to evaluate to what you'd expect when you assign values to free variables. I believe this may be more accurate than thinking in terms of rewriting rules, since, as far as I know, nothing in the Sage implementation of symbolic expression systematically applies “rewriting rules”. Many operations on symbolic expressions, however, only make sense with stronger assumptions on the expressions. Typically, simplifications are supposed to transform these ”programs“ into ”equivalent“ ones, but of course whether two ”programs“ are equivalent depends on what the variables can represent. |
comment:67
Replying to @mezzarobba:
I'm pretty sure that would be at least as annoying as dealing with values printed by a bare |
comment:68
Related to this discussion, note that there is another (strange) way to declare variables in Sage that currently works:
Apparently, it is ipython that provides this. I learn about the existence of this when I recently read the wikipedia page of Sage:
|
comment:69
Replying to @seblabbe:
Yuck. It's a good illustration of the general confusion caused by the current behaviour of
is equivalent to
which happens to do almost the same effect as the other |
Functions returning a value should not have side effects,
var
does. In #17447, comment 23 Nils Bruin proposed to separate both usages ofvar
by introducingdeclare_var
: this should behave exactly likevar
without return value, andvar
should not put the var handle in theglobals
list but should act likeSR.var
. If we want the following behaviour:declare_var('x')
==var('x')
as before but returningNone
var('x')
prints deprecation message, returns variable as before; error after deprecation periody = var('x')
as before (but without globals), NO deprecation messagewe certainly need the preparser to recognize 2/3, and to replace (2) with
declare_var('x'); deprecation(...); x
and (3) withy = SR.var('x')
. Secondly, there is a different docstring needed withvar
when compared withdeclare_var
.This and the same with functions is the most annoying problem for people doing calculus in Sage.
CC: @nbruin @kcrisman
Component: symbolics
Issue created by migration from https://trac.sagemath.org/ticket/17958
The text was updated successfully, but these errors were encountered: