From: Barton W. <wi...@un...> - 2014-08-07 11:10:46
|
In Maxima, declared constants cannot be formal parameters; thus every Maxima function that happens to have a formal parameter named 'n' will misbehave when n is a declared constant. (%i1) declare(n,constant)$ (%i2) f(n) := n^2; define: in definition of f, found bad argument n (%i3) invert(matrix([1,0],[0,1])); define: in definition of hilbert_matrix, found bad argument n (%i4) ode2('diff(f,x)=42,f,x); define: in definition of integfactor, found bad argument n Other than (re)naming all formal parameters something goofy and hard to read, I cannot think of a workaround. Lambda forms are allowed to have a formal parameter that is a declared constant (%i5) declare(n,constant)$ (%i6) f : lambda([n],n^2)$ (%i7) f(5); (%o7) 25 but I don't see that as reasonable workaround. |
From: Stavros M. (Σ. Μ. <mac...@al...> - 2014-08-07 14:27:26
|
Agreed. Only sysconst's should have this restriction. BTW, with sysconsts, you do get an error at apply time (though not at simp time): f: lambda([%pi],%pi)$ => no error f(5) => error, cannot assign to %pi On Thu, Aug 7, 2014 at 7:10 AM, Barton Willis <wi...@un...> wrote: > In Maxima, declared constants cannot be formal parameters; thus every > Maxima function that happens > > to have a formal parameter named 'n' will misbehave when n is a declared > constant. > > > (%i1) declare(n,constant)$ > (%i2) f(n) := n^2; > define: in definition of f, found bad argument n > > (%i3) invert(matrix([1,0],[0,1])); > define: in definition of hilbert_matrix, found bad argument n > > (%i4) ode2('diff(f,x)=42,f,x); > define: in definition of integfactor, found bad argument n > > > Other than (re)naming all formal parameters something goofy and hard to > read, I cannot think of a workaround. Lambda forms are allowed to have a > formal parameter that is a declared constant > > > (%i5) declare(n,constant)$ > (%i6) f : lambda([n],n^2)$ > (%i7) f(5); > (%o7) 25 > > > but I don't see that as reasonable workaround. > > > > > > ------------------------------------------------------------------------------ > Infragistics Professional > Build stunning WinForms apps today! > Reboot your WinForms applications with our WinForms controls. > Build a bridge from your legacy apps to the future. > > http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk > _______________________________________________ > Maxima-discuss mailing list > Max...@li... > https://lists.sourceforge.net/lists/listinfo/maxima-discuss > > |
From: Barton W. <wi...@un...> - 2014-08-08 03:08:38
|
> Agreed. Only sysconst's should have this restriction. Maybe the fix is as easy as (defined in mlisp) change (defun mdefparam (x) (and (atom x) (not (maxima-constantp x)) (not (stringp x)))) to (defun mdefparam (x) (and (symbolp x) (not (get x 'sysconst)) (not (stringp x)))) This disallows subscripted variables from being formal parameters...ahh was there a discussion about this sometime ago? As for > f: lambda([%pi],%pi)$ => no error f(5) => error, cannot assign to %pi there should be a easy fix to mdefine1 (defun mdefine1 (args body) (list '(lambda) (cons '(mlist) args) body)) (I like my errors to show up sooner, not later). --Barton ________________________________ Subject: Re: [Maxima-discuss] declared constants cannot be formal parameters Agreed. Only sysconst's should have this restriction. BTW, with sysconsts, you do get an error at apply time (though not at simp time): f: lambda([%pi],%pi)$ => no error f(5) => error, cannot assign to %pi On Thu, Aug 7, 2014 at 7:10 AM, Barton Willis <wi...@un...<mailto:wi...@un...>> wrote: In Maxima, declared constants cannot be formal parameters; thus every Maxima function that happens to have a formal parameter named 'n' will misbehave when n is a declared constant. (%i1) declare(n,constant)$ (%i2) f(n) := n^2; define: in definition of f, found bad argument n (%i3) invert(matrix([1,0],[0,1])); define: in definition of hilbert_matrix, found bad argument n (%i4) ode2('diff(f,x)=42,f,x); define: in definition of integfactor, found bad argument n Other than (re)naming all formal parameters something goofy and hard to read, I cannot think of a workaround. Lambda forms are allowed to have a formal parameter that is a declared constant (%i5) declare(n,constant)$ (%i6) f : lambda([n],n^2)$ (%i7) f(5); (%o7) 25 but I don't see that as reasonable workaround. ------------------------------------------------------------------------------ Infragistics Professional Build stunning WinForms apps today! Reboot your WinForms applications with our WinForms controls. Build a bridge from your legacy apps to the future. http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk _______________________________________________ Maxima-discuss mailing list Max...@li...<mailto:Max...@li...> https://lists.sourceforge.net/lists/listinfo/maxima-discuss |
From: Stavros M. (Σ. Μ. <mac...@al...> - 2014-08-08 03:43:30
|
Subscripted variables shouldn't be formal parameters. If n=1, then a[1] and a[n] are the same variable, not good. By the way, we don't currently check that the variables are distinct, either. Maxima allows f(i,i):=i and f(2,3) => 3. lambda([i,i]...) should be an error, just as it is in at least some Lisps (SBCL). -s On Thu, Aug 7, 2014 at 11:08 PM, Barton Willis <wi...@un...> wrote: > > Agreed. Only sysconst's should have this restriction. > > > Maybe the fix is as easy as (defined in mlisp) change > > > (defun mdefparam (x) > (and (atom x) (not (maxima-constantp x)) (not (stringp x)))) > > > to > > > (defun mdefparam (x) > (and (symbolp x) (not (get x 'sysconst)) (not (stringp x)))) > > > This disallows subscripted variables from being formal parameters...ahh > was there a discussion about > > this sometime ago? As for > > > > f: lambda([%pi],%pi)$ => no error f(5) => error, cannot assign > to %pi > > > there should be a easy fix to mdefine1 > > > (defun mdefine1 (args body) > (list '(lambda) (cons '(mlist) args) body)) > > > > > (I like my errors to show up sooner, not later). > > > --Barton > > > > > > > > > > > ------------------------------ > > *Subject:* Re: [Maxima-discuss] declared constants cannot be formal > parameters > > Agreed. Only sysconst's should have this restriction. > > BTW, with sysconsts, you do get an error at apply time (though not at > simp time): > > f: lambda([%pi],%pi)$ => no error > f(5) => error, cannot assign to %pi > > > > On Thu, Aug 7, 2014 at 7:10 AM, Barton Willis <wi...@un...> wrote: > >> In Maxima, declared constants cannot be formal parameters; thus every >> Maxima function that happens >> >> to have a formal parameter named 'n' will misbehave when n is a declared >> constant. >> >> >> (%i1) declare(n,constant)$ >> (%i2) f(n) := n^2; >> define: in definition of f, found bad argument n >> >> (%i3) invert(matrix([1,0],[0,1])); >> define: in definition of hilbert_matrix, found bad argument n >> >> (%i4) ode2('diff(f,x)=42,f,x); >> define: in definition of integfactor, found bad argument n >> >> >> Other than (re)naming all formal parameters something goofy and hard to >> read, I cannot think of a workaround. Lambda forms are allowed to have a >> formal parameter that is a declared constant >> >> >> (%i5) declare(n,constant)$ >> (%i6) f : lambda([n],n^2)$ >> (%i7) f(5); >> (%o7) 25 >> >> >> but I don't see that as reasonable workaround. >> >> >> >> >> >> ------------------------------------------------------------------------------ >> Infragistics Professional >> Build stunning WinForms apps today! >> Reboot your WinForms applications with our WinForms controls. >> Build a bridge from your legacy apps to the future. >> >> http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk >> _______________________________________________ >> Maxima-discuss mailing list >> Max...@li... >> https://lists.sourceforge.net/lists/listinfo/maxima-discuss >> >> > |
From: Richard F. <fa...@be...> - 2014-08-08 05:12:40
|
Well, we could vastly expand the possibilities of parameters, at some cost to mdefine and meval. For example, we could allow patterns, as Mathematica does ... f[x_?EvenQ]:= Print[" here is an even number", x] f[x_?OddQ]:= Print ["here is an even number", x] f[x_]:= Print ("here is something that is not an even or odd number", x) Though in Maxima syntax it would look like f(PatternTest(Pattern(x,Blank()),evenp) ) := print( ...) For another example, we could allow common lisp lambda list equivalents such as keyword parameters, optional parameters. We sort of have rest parameters as f(a,[L]:= a+L f(a,b,c) returns [b+a,c+a] though probably most people don't know that. RJF ps, I haven't given up on putting this kind of pattern matching directly in Maxima. On 8/7/2014 8:08 PM, Barton Willis wrote: > > > Agreed. Only sysconst's should have this restriction. > > > Maybe the fix is as easy as (defined in mlisp) change > > > (defun mdefparam (x) > (and (atom x) (not (maxima-constantp x)) (not (stringp x)))) > > > to > > > (defun mdefparam (x) > (and (symbolp x) (not (get x 'sysconst)) (not (stringp x)))) > > > This disallows subscripted variables from being formal > parameters...ahh was there a discussion about > > this sometime ago? As for > > > > f: lambda([%pi],%pi)$ => no error f(5) => error, cannot > assign to %pi > > > there should be a easy fix to mdefine1 > > > (defun mdefine1 (args body) > (list '(lambda) (cons '(mlist) args) body)) > > > > > (I like my errors to show up sooner, not later). > > > --Barton > > > > > > > > > > ------------------------------------------------------------------------ > > *Subject:* Re: [Maxima-discuss] declared constants cannot be formal > parameters > Agreed. Only sysconst's should have this restriction. > > BTW, with sysconsts, you do get an error at apply time (though not at > simp time): > > f: lambda([%pi],%pi)$ => no error > f(5) => error, cannot assign to %pi > > > > On Thu, Aug 7, 2014 at 7:10 AM, Barton Willis <wi...@un... > <mailto:wi...@un...>> wrote: > > In Maxima, declared constants cannot be formal parameters; thus > every Maxima function that happens > > to have a formal parameter named 'n' will misbehave when n is a > declared constant. > > > (%i1) declare(n,constant)$ > (%i2) f(n) := n^2; > define: in definition of f, found bad argument n > > (%i3) invert(matrix([1,0],[0,1])); > define: in definition of hilbert_matrix, found bad argument n > > (%i4) ode2('diff(f,x)=42,f,x); > define: in definition of integfactor, found bad argument n > > > Other than (re)naming all formal parameters something goofy and > hard to read, I cannot think of a workaround. Lambda forms are > allowed to have a formal parameter that is a declared constant > > > (%i5) declare(n,constant)$ > (%i6) f : lambda([n],n^2)$ > (%i7) f(5); > (%o7) 25 > > > but I don't see that as reasonable workaround. > > > > > ------------------------------------------------------------------------------ > Infragistics Professional > Build stunning WinForms apps today! > Reboot your WinForms applications with our WinForms controls. > Build a bridge from your legacy apps to the future. > http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk > _______________________________________________ > Maxima-discuss mailing list > Max...@li... > <mailto:Max...@li...> > https://lists.sourceforge.net/lists/listinfo/maxima-discuss > > > > > ------------------------------------------------------------------------------ > Want fast and easy access to all the code in your enterprise? Index and > search up to 200,000 lines of code with a free copy of Black Duck > Code Sight - the same software that powers the world's largest code > search on Ohloh, the Black Duck Open Hub! Try it now. > http://p.sf.net/sfu/bds > > > _______________________________________________ > Maxima-discuss mailing list > Max...@li... > https://lists.sourceforge.net/lists/listinfo/maxima-discuss |
From: Barton W. <wi...@un...> - 2014-08-09 18:21:25
|
The user documentation for ":=" or "define" doesn't say that formal parameters are not allowed to be declared constants. Neither do I find any explanation of why the formal parameter of a lambda form can be a declared constant, but a function defined by ":=" cannot: (%i1) declare(n,constant)$ (%i2) f : lambda([n],n+42)$ (%i3) g(n) := n+42$ define: in definition of g, found bad argument n The user documentation for ode2 (for example), doesn't explain why ode2 fails when n (and maybe a few other popular variable names) is a declared constant fails: (%i6) ode2('diff(f,x)=2014,f,x); define: in definition of integfactor, found bad argument n Now that's pretty confusing--I had declared n to be a constant to simply some noncommutative products--opps, ode, invert, and .. didn't work after that. By my understanding of scoping, this isn't a lex vs dynamic issue. --bw |
From: Richard F. <fa...@be...> - 2014-08-09 19:21:08
|
On 8/9/2014 11:21 AM, Barton Willis wrote: > The user documentation for ":=" or "define" doesn't say that formal parameters are not allowed to > be declared constants. Neither do I find any explanation of why the formal parameter of a lambda > form can be a declared constant, but a function defined by ":=" cannot: > > (%i1) declare(n,constant)$ > (%i2) f : lambda([n],n+42)$ > (%i3) g(n) := n+42$ > define: in definition of g, found bad argument n furthermore rr(n):=block([],declare(n,constant),ss[n]:=n+1,ss(4)) > > The user documentation for ode2 (for example), doesn't explain why ode2 fails when > n (and maybe a few other popular variable names) is a declared constant fails: > > (%i6) ode2('diff(f,x)=2014,f,x); > define: in definition of integfactor, found bad argument n > > Now that's pretty confusing--I had declared n to be a constant to simply some noncommutative > products--opps, ode, invert, and .. didn't work after that. > > By my understanding of scoping, this isn't a lex vs dynamic issue. I think that all Maxima declarations and assumptions are global. That is, when you say declare(n,constant), ALL stack bindings are ignored. Why? because only name-value pairs are eligible for binding locally. There is a declaration local() which provides an opportunity to bind name-function pairs. We could consider whether this is optimal or should be changed ... (a) technical standpoint (supporting programmers) (b) easiest to explain / principle of least surprise for users (c) not breaking existing code (d) fixing apparently surprising "features" -- later revealed to be more like bugs. (e) other criteria? At the moment (d) seems to push us in the direction of allowing constants to be bound. It would be possible to change meval and friends to do lexical scoping, or a flag which makes the change. Some years ago Maple did a revision (or a revolution!) and changed its scoping. I think it is a credit to the generally shallow programming in these systems that for a huge majority of the existing code, it doesn't matter. A programmer deeply into Scheme probably would write programs where it does matter. RJF > > > --bw > ------------------------------------------------------------------------------ > _______________________________________________ > Maxima-discuss mailing list > Max...@li... > https://lists.sourceforge.net/lists/listinfo/maxima-discuss |
From: Robert D. <rob...@gm...> - 2014-08-09 19:13:37
|
On 2014-08-09, Barton Willis <wi...@un...> wrote: > By my understanding of scoping, this isn't a lex vs dynamic issue. Isn't it? The problem is that 'n' in a function definition is the same 'n' that appears anywhere else in the program. I guess it can be argued that since Maxima allows assignment to symbols declared constant, there's no reason to disallow dynamic binding for formal arguments. But then there's an inconsistency between a declared property and the use of the symbol -- lexical scope would make the ambiguity go away. best Robert Dodier |
From: Richard F. <fa...@be...> - 2014-08-09 19:30:20
|
On 8/9/2014 12:13 PM, Robert Dodier wrote: > On 2014-08-09, Barton Willis <wi...@un...> wrote: > >> By my understanding of scoping, this isn't a lex vs dynamic issue. > Isn't it? The problem is that 'n' in a function definition is the same > 'n' that appears anywhere else in the program. > > I guess it can be argued that since Maxima allows assignment to symbols > declared constant, there's no reason to disallow dynamic binding for > formal arguments. But then there's an inconsistency between a declared > property and the use of the symbol -- lexical scope would make the > ambiguity go away. I think not. (this is sort of related to what used to be call the "upward funarg" problem) f(x):=block([n], declare(n,constant) g(r):= something-with-n... ); is there a way to preserve this declaration if someone subsequent does, say, kill(n); If you were able to stack more than the name-value pair, but all the properties of n, there might be a solution. I think you could do this with lexical or dynamic scope :) I mentioned this in a post just recently.. RJF |
From: Robert D. <rob...@gm...> - 2014-08-09 23:14:49
|
On 2014-08-09, Richard Fateman <fa...@be...> wrote: > It would be possible to change meval and friends to do lexical > scoping, or a flag which makes the change. Some years ago Maple > did a revision (or a revolution!) and changed its scoping. > I think it is a credit to the generally shallow programming > in these systems that for a huge majority of the existing code, it > doesn't matter. I think it's true that most existing Maxima programs would continue to work the same if lexical scope were introduced. I think that's an argument in favor. > A programmer deeply into Scheme probably would write programs where it > does matter. It is quite easy to write such a program by accident -- in fact, such accidents are reported on a regular basis. Isn't that how we got onto this subject again? I'm not sure what your point is -- are you arguing that lexical scoping is unneeded? or what? best Robert Dodier |
From: Barton W. <wi...@un...> - 2014-08-09 23:54:10
|
A workaround: (%i1) declare(n,constant)$ (%i2) block([n], local(n), f(n) := n+42)$ (%i3) f(5); (%o3) 47 (%i4) f(n); (%o4) n+42 (%i5) constantp(%); (%o5) true --Barton |
From: Richard F. <fa...@be...> - 2014-08-10 13:42:17
|
On 8/9/2014 4:14 PM, Robert Dodier wrote: > On 2014-08-09, Richard Fateman <fa...@be...> wrote: > >> It would be possible to change meval and friends to do lexical >> scoping, or a flag which makes the change. Some years ago Maple >> did a revision (or a revolution!) and changed its scoping. >> I think it is a credit to the generally shallow programming >> in these systems that for a huge majority of the existing code, it >> doesn't matter. > I think it's true that most existing Maxima programs would continue > to work the same if lexical scope were introduced. I think that's an > argument in favor. > >> A programmer deeply into Scheme probably would write programs where it >> does matter. > It is quite easy to write such a program by accident -- in fact, such > accidents are reported on a regular basis. Isn't that how we got onto > this subject again? > > I'm not sure what your point is -- are you arguing that lexical > scoping is unneeded? or what? I think that lexical scope would not solve this problem unless the name-value binding were expanded to name-{value,function, properties,assumptions,...} binding. For example, mockMMA associates with each name (global, stack-allocated), a hash table which stores any number of things. (Mathematica associates "Attributes" with names). It does not matter if lexical or dynamic scoping is used, if you just have a name-value binding. I'm not arguing for a sweeping change for lexical scope, though I think it is overall better. But in case you haven't thought about it, lexical scope introduces nasty complications for debugging. RJF |
From: Robert D. <rob...@gm...> - 2014-08-08 22:30:21
|
On 2014-08-07, Barton Willis <wi...@un...> wrote: > In Maxima, declared constants cannot be formal parameters; thus every > Maxima function that happens to have a formal parameter named 'n' > will misbehave when n is a declared constant. Given existing policies for declarations and formal arguments, that's exactly as one should expect. We could make this and various other gotchas just go away by switching over to lexical scope. I don't remember at the moment whether I'm in favor of that. best Robert Dodier |
From: Robert D. <rob...@gm...> - 2014-08-08 22:39:56
|
On 2014-08-07, Stavros Macrakis <mac...@al...> wrote: > Agreed. Only sysconst's should have this restriction. That's not very satisfying, right? The SYSCONST property isn't exposed at the user level, so there's no way to identify such symbols, or to create new ones. A larger problem is that the present behavior is a simple consequence of existing policies, so distinguishing different classes of symbols creates an inconsistency which must therefore be explained ... I hope we don't make Maxima any more incomprehensible than it already is. best Robert Dodier |
From: Robert D. <rob...@gm...> - 2014-08-08 22:45:14
|
On 2014-08-08, Barton Willis <wi...@un...> wrote: > This disallows subscripted variables from being formal parameters... > ahh was there a discussion about this sometime ago? Yeah -- I think the conclusion (well, my reading of it, anyway) was that allowing subscripted variables as formal arguments causes more trouble than it's worth. As ever I suppose that isn't the final word. best Robert Dodier |
From: Robert D. <rob...@gm...> - 2014-08-08 22:50:57
|
On 2014-08-08, Richard Fateman <fa...@be...> wrote: > Though in Maxima syntax it would look like > > f(PatternTest(Pattern(x,Blank()),evenp) ) := print( ...) We could merge matchdeclare predicates into function definitions -- something like foo (evenp (x)) := (stuff appropriate for even x) foo (oddp (x)) := ... (for odd x) foo (lambda ([u], ...) (x)) := ... (for x which passes lambda(...)) > ps, I haven't given up on putting this kind of pattern matching > directly in Maxima. Me neither. An open question is whether functions so defined would be simplifying functions (more consistent with existing pattern matching stuff) or evaluating functions (more consistent with existing function definition stuff). best Robert Dodier |
From: Robert D. <rob...@gm...> - 2014-08-10 20:51:45
|
On 2014-08-10, Richard Fateman <fa...@be...> wrote: > I think that lexical scope would not solve this problem unless the > name-value binding were expanded to name-{value,function, > properties,assumptions,...} binding. Lexical scope just means that things with the same name in different contexts are distinct, right? So lexical scope must solve the problem as originally posed (assuming that a function definition is a different context than the context in which declare(n, constant) appeared). The stuff about name-foo bindings is an implementation detail, right? best, Robert Dodier |
From: Robert D. <rob...@gm...> - 2014-08-10 21:52:44
|
On 2014-08-09, Barton Willis <wi...@un...> wrote: > A workaround: > > (%i1) declare(n,constant)$ > > (%i2) block([n], local(n), f(n) := n+42)$ Yes. A couple of other ways to resolve it with some experimental code. One way is to use the existing share package 'namespaces'. (%i1) load (namespaces) $ (%i2) declare (n, constant) $ (%i3) in_namespace (my); (%o3) #<$MY package> (%i4) f(n) := n + 1 $ (%i5) in_namespace (maxima); (%o5) #<MAXIMA package> (%i6) constantp (n); (%o6) true (%i7) constantp (my|n); (%o7) false (%i8) my|f (1); (%o8) 2 Another way is to use the blex(...) lexical block construct. See: https://www.ma.utexas.edu/pipermail/maxima/2013/034618.html (%i1) load ("blex.lisp") $ (%i2) declare (n, constant) $ (%i3) n1 : blex ([n], f(n) := n + 1, n); (%o3) n (%i4) constantp (n); (%o4) true (%i5) constantp (n1); (%o5) false (%i6) f (1); (%o6) 2 blex is a toy, but namespaces is maybe a little less shaky, as it is just glue code for the CL symbol package system. For what it's worth, Robert Dodier |