mm-29 === Can you solve this equation for x?> x log(kx) = (x - 1)log(1 - x)> the answer might involve Lambert's W function, but I'm not sureIt's not solved for x, but it looks nice this way...> log(k)=Int(1+log(s),s=1/x-1 .. 1/x); 1/x / | ln(k) = | ln(s) + 1 ds | / 1/x - 1 === >> In what general systems are you thinking? Are you saying that there are>> some systems where solving is easier than simplification or just not>> -much- worse (i.e. the same complexity).> The paper below, by Daniel Richardson proves that the task tell me if > this expression is zero or not is undecidable. The expression class > is necessarily broader than polynomials, for which the decision problem> is easily solvable.> Daniel Richardson: Some Undecidable Problems Involving Elementary> Functions of a Real Variable. J. Symb. Log. 33(4): 514-520 (1968). >> Solving whatever that means --- is not going to be harder.Do you mean not harder than undecidable? I see you point if you take that to be a ceiling (in the universe of problems, almost all are undecidable). But there is a hierarchy of undecidablility (suppose, contrary to reality, that you have an oracle for a particular undecidable problem; some previously undecidable problems are now decidable, but some still are not).I take solving to be determining the member or members of the domain that, when substituted into the formula, make it true, that is a satisfying valuation.simplification for me is creating a new formula that has the same solutions, but is canonical (smallest) in some given ordering (so I suppose the ordering is a hidden parameter to the problem).I suppose that if all variables are eliminable and eliminated in the simplification process, then -that- is a solution.And I see that it is very plausible that simplification can be reduced to solving (if you have a solution then -that- is your simplified form).So are you saying in your experience these two processes are usually interreducible (as opposed to the poly simplification/poly solution case)?Mitch === > Do you mean not harder than undecidable? I see you point if you take > that to be a ceiling (in the universe of problems, almost all are > undecidable). But there is a hierarchy of undecidablility (suppose, > contrary to reality, that you have an oracle for a particular > undecidable problem; some previously undecidable problems are now > decidable, but some still are not).> I think this is interesting. If you have an oracle Q that can tellyou is this expression in the variable x identically zero then you(with some additional conditions) have a perfect simplifier.The condition is that you are able to generate, in order of simpler tocomplicated, all legal expressions in your class, a[0], a[1], .... .and you can substract...In order to simplify the expression E, just runfor i:=0 to infinity do if Q(E-a[i]) then return(a[i]).The simplest expression equivalent to E is the answer.You might be able to do the same thing for solve, assuming you have a procedure that will plug the answer in and check is this a solution?Of course for solve it may be that no answer in your class of expressions is a solution and so you will never terminate.You can apply this reasoning to the polynomial situation, but for polynomial simplification you can do much better!RJF === > [...]> Hence my preference to C++ over C because you can overlad> arithmetic operator (I'm not sure but I believe you can't> in java,> There are other ways of doing extensions in Java, which I am> sure Java advocates will be happy to explain.Normally there are no extensions in java, in the sense of changes that affect the grammar. This makes it simple and readable, but as a consequence arithmetic operator overload can't be implemented.There is an exception though : the grammar can change with new versions, and precisely, with jdk1.5, there will be autoboxing, which enables using the arithmetic operators with reference types like Integer, Long, Double etc. However this feature will be limited to these build-in wrapper types, so with no application in computer algebra. === .. notation for GCD>> No, I think the usual notation in mathematics is (b,c).>> see Van der Waerden, Algebra (vol 2) section 15.2 p 119.>> (my copy is (c) 1970).> I have never seen this notation for gcd. Sometimes ^ is used> but most of the time the prefix notation.I just looked in a second algebra book on my shelf,Birkhoff and MacLane, A Brief Survey of Modern Algebra.Page 17. In fact it say of the two possible g.c.d.'s +-d for a and b, thepositive one is often denoted by the symbol . (a , b)...And here is another place..http://mathworld.wolfram.com/GreatestCommonDivisor.html >> Furthermore, mathematics typically has no assignment operation,>> and the meaning of the mathematics notation a=b is ambiguous. It>> certainly does not mean what any of the assignment statements above>> mean... thus a notation like x=x+1 is on the face of it absurd.>> What does = mean in mathematics?>> It could be a statement like 1+1=2, of a fact.>> It could be a relation like sin(x)=y to be converted to some other >> relation by solve for x.>> It could be a FALSE hypothesis, such as suppose a^2+b^2=c^2.>> It could be a definition (though often a different notation is used>> for this.)> Mathematicians use the = notation and the meaning is clear from> the context.Since programmers rarely have the full context of the mathematics,it seems to me to be better not to use =.Lisp has setf for assignment = for numeric equality eq for identical equal addresses equal for list structure eql ...>> Mathematics does not use * for multiplication. a*b might mean>> almost anything. transpose(a)? conjugate(a), Kleene star?> Ask anyone who used a calculator what * means, you will get> the answer: * clearly means multiplication.My calculator has an X on it, not an asterisk (*).> For the same reason, I prefer to write> a=1/(b+c*d)> than say a=gdiv(1,gadd(b,gmul(c,d)))>> I do not know what your statement means. Does division mean an>> operation in a field, or division in a ring? e.g.>> 12/3 --> 4 is valid in a ring, so division sometimes works.>> 12/5 --> not a ring element, so it sometimes doesn't work.>> In the rational field,>> (12/1) / (3/1) --> (4/1)>> (12/1) / (5/1) --> (12/5) so this is OK.>> Without knowing which / you mean your program may be>> erroneous, or sloppy. A generic division doesn't work!> Come back in the world of mortals. Ask anyone what / means> he will answer division. I of course assume we have a C++> generic type (like GEN in pari, gen in giac, ex in GiNaC, ...).>> If you prefer to write lisp in infix, there are several widely>> available infix notation packages that allow you to do something like>> (setf a #.[1/(b+c*d)])>> or even #.[ a:=1/(b+c*d)] but of course this assumes you mean>> to use the operations as given.> remove the #.[ ] and I'll be happy.> I do not find the infix operations helpful in expressions like this one,>> from a paper of mine...>> (* (+ (* x (+ (* x (+ (* w (+ -1.745986568814345d0 w z))>> 1.213871280862968d0))>> 9.4939615625424d0))>> -94.9729157094598d0)>> -0.00420059d0)>> - 0.00420059d0 * (x * (x * (w * (z + w - 1.74598656881434d0) + >> 1.21387128086296d0) + 9.4939615625424d0) - 94.9729157094598d0)>> Is this better?> Yes (except I don't understand what 1.21387128086296d0 means),> but that's too long, it's better to have an intermediate variable> gen tmp= w * (z + w - 1.74598656881434d0) + 1.21387128086296d0;> gen result=- 0.00420059d0 * (x * (x *tmp+ 9.4939615625424d0) - > 94.9729157094598d0);That is a double precision float. 1.23d0 means 1.23 X 10^0.I do not find infix arithmetic particularly compelling, and ithas the extra problem of requiring you to either understandthe precedence or put in extra parentheses.> There are other ways of doing extensions in Java, which I am>> sure Java advocates will be happy to explain.>> I don't know for lisp but it seems a constant of lisp> to use 5-th like notations), >> That is because they are better, not because Lisp forces>> you to use them!!!> You claim this, but I don't see any reason why.The answer is in the next sentence:> I don't have a personal experience in Lisp,That's why.> but in reverse> polish lisp (RPL) where you use a stack and functions are> applied to their arguments on the stack and return their> arguments on the stack, for example gcd(a,b) would be> a b gcd> (i.e. the reverse of lisp, without parenthesis, which BTW> requires a fixed number of arguments for every function).> I have implemented a CAS in RPL and I'm implementing a CAS> in C++, I can tell you that it's much much easier to do it> in C++ (it would probably also be easier in Lisp than in RPL but> both languages have more in common than C++ and RPL or Lisp> hence my guess that it is in fact harder to write a CAS in Lisp> than in C++).Your assumption that RPL and Lisp have more in common thanLisp and C++ is not reasonable. You should really learnsome Lisp. I suggest Paul Graham's ANSI Common Lisp.>> I find maple code to be unreadable, partly because the typical>> way of returning values is to have one or more return value parameters>> as strings as arguments to a procedure. This makes the assignment>> of values resulting from a procedure some arbitrary distance away>> from the invocation of the procedure. > I don't understand what you mean. Is it that you don't> like constructions like you would have for the extended> euclidean algorithm in C> int egcd(int a,int b,int & u,int &v);Yes, that is a similar situation.In Lisp you could handle the return of some number of argumentsin a variety of ways, but one is this way:(multiple-value-bind (u v) (egcd a b) ... compute with u, v ....)where egcd would look like this...(defun egcd(r s) ..... compute stuff..... (return (values c d)) ..)>> There are also different>> rules for evaluation depending on whether you type an expression>> at the top level or call it from another procedure.> This has nothing to do with clarity of an algorithm.It means you can't debug a function f(a,b,c) in Mapleby typing in f(a,b,c). You must write a procedure to callit if you want the same semantics.>> C++ is generally used as a batch language, and from my perspective,>> this makes it almost inconceivable that anyone familiar with an >> interactive language would use ANY batch language for complex>> prototyping and experimentation.> I don't see why. As I said each language has its good points> and weak points. I would probably use an interactive language for> a quick test without much programming, but not for a complex task> with many subroutines.Why would you not use an interactive language for a complex task?> I don't believe there is *a* language more appropriate than others.> The best would be of course to have all these languages> be able to talk one to each other in an almost transparent way.>> Maybe not. If you had to make uncomfortable adaptations, you>> might not want this. Say someone said, let's all use Microsoft .net.>> Would that be best?> I was probably not clear enough. I meant in an ideal world,> you could use your prefered language and have full access to> all the packages developped using other languages. And everything> would run on every platform. Unfortunately, we are not living> in this world. So you have to choose a language and the decision> will be based on many factors. For me, using a language that> is widely used by the open source community is very important> because it's reasonnably certain that 30 years from now it will> compile and run.My experience is that programs written in C require extensivere-porting to run in different environments. The use of a configurescript is an example of how much effort is required to make aprogram in C run on every platform. Of course other programminglanguages may need such help, but it is simply not true that aprogram written in C or Java will run on an arbitrary platform.> You have to choose depending on what you want to do exactly> and what tools are available (the first one being the compiler),> where you want to port your application, what kind of user> interface, etc.>> The major restriction is not what tools are available, but what>> tools you and your programmers know how to use.> I don't agree. Using some C or C++ libraries is certainly> way easier from C++ than from any other language. Then consider> the amount of such libraries that can be included in a CAS.Since you seem to look at GMP as an example, can you compare theease with which you can use GMP from Python, C++, Perl, Ruby, Java,Lisp? Actually, I suspect that the obvious interface between C andGMP leaks memory.> In the case of someone who knows C and want to write a program> to compute GCD of polynomials of small degree with integer> coefficients, learning the C++ vector to represent polynomials> and using GMP (mpz_class) for the coefficients and implementing> gcdheu requires probably around 2 weeks.>> If you want to do any sequence of calculations with polynomials>> that produces intermediate expressions, you need to also write>> storage management.> No, mpz_class and vector do the storage management, you can use> them like a fixed-length data type in a C++ program.If you have variables which point to mpz (gnu multiple-precision integers), how do you know when the numbers can be erased? Perhapsyou are assuming no shared values, in which case an assignment a=b must become mpz_deallocate(a); a=mpz_copy(b).This is not a very good plan.Allocating storage is easy. Deallocating storage is harder todo correctly.>> Obviously, * should return (x+1)*(x-1), because the first form> requires simplification that the programmer should explicitely> write (e.g. a=normal(b*c);)>> so you are saying that 3*4 should return the tree for 3*4, and to>> get the result 12 you need to write normal(3*4) ?> Of course not. The * operator will check the argument> types and do the operations on integers. It should return> what you expect it to return. I claim that (x+1) times (x-1)> should return the tree (x+1)*(x-1) and not x^2-1 because> the second form requires a relatively complex operation,> as 4 times 3 should return 12 because it's a simple operation.Simple? is a product of two big numbers simple or not? A call toa GMP routine? How about two rational numbers? Two complex numberswhose real and imaginary parts are huge rational numbers? Doesa/b rationalize the denominator for complex a,b?>> I might want>> to create a tree that looks like this: factors_of_12 = 2*2*3.>> What * do I use then?> You must do something more (i.e. quote the * operation),> because one expects 2*2*3 to return 12.Oh, so what is the point of the overloaded * operation? Now youmust do something like create_tree(*,create_tree(*,2),2),3).So some of the operations you claim can be done with overloadedC++ operations don't work that way.> I don't have time for this. Just look around and see how CAS> are implemented, the answer is that there is not a prefered> language. >>The subject line says which is best. I know that there area variety of opinions. I am hoping for some way of testing.A survey of opinions is not testing!>> On the same basis, the most appropriate operating system for a>> desktop computer is something sold by Microsoft. Not convincing>> to me!> I did not speak of the most popular CAS, I spoke of how CAS are> Solaris, HP-UX, FreeBSD to your comparision.>> How far advanced would Maple and Mathematica be today if they didn't>> have to debug their C code, if they didn't have to figure out how>> they were leaking memory, etc.> You probably mean how far would they be if they had choosen Lisp?> We will never know! My guess is they would not be as good,> simply because the people who use C-like languages outperforms> the number of people who use Lisp-like languages and the percentage> of good programmers is probably not very different in any language.I am not sure I can parse your statement. If you are saying thatthere are more C programmers than Lisp programmers, that is true.If you say that they are equally productive, the only (limited)evidence I have seen is that some Lisp programmers are very productive, and attempts to compare them to C programmers usually ends up with Lisp being better. A search on google finds a few of these comparisons.Here's a nice essay by Paul Graham ...http://www.paulgraham.com/icad.html>> Here is one, implicit in your note:>> Write an implementation of gcdheu for polynomials (in one variable?)>> with integer coefficients. Or do you mean .. in any number of>> variables? How long does it take?> Well, we have two tests here:> one variable and any number of variables> Any other tests? === >>My experience is that programs written in C require extensive>re-porting to run in different environments. The use of a configure>script is an example of how much effort is required to make a>program in C run on every platform. Of course other programming>languages may need such help, but it is simply not true that a>program written in C or Java will run on an arbitrary platform.It is pretty amazing that low level Java (without GUI) does runproperly on several different platforms. It is extraordinary actuallyto have a CAS written in Java for JDK 1.1 running on severaldifferent PersonalJava implementations and now also runningproperly on J2ME CLDC/MIDP, the exact same code, nothingchanged or compensated at all; One String-based engine thatruns unmodified on any arbitrary Java implementation. Now theGUI on the other hard is simply chaotic and a disappointment,Java can do better and should do better.So to throw some wood in this fire, I would say that Java (for me)is a very good language to develop CAS software.Carlos. === > So to throw some wood in this fire, I would say that Java (for me)> is a very good language to develop CAS software.Glad to see that another CAS developer opinion reinforces mymain point: depending on the application youdevelop, you will choose one or another language, there isno prefered language to develop a CAS. === I think we don't live in the same world!> I just looked in a second algebra book on my shelf,> Birkhoff and MacLane, A Brief Survey of Modern Algebra.> Page 17. In fact it say> of the two possible g.c.d.'s +-d for a and b, the> positive one is often denoted by the symbol> .> (a , b)> ...> And here is another place..> http://mathworld.wolfram.com/GreatestCommonDivisor.html> I'm a mathematician, and again I can insure you I neversaw this notation before. Which means for me a coupleof (integers or polynomials). Maybe it's a local US notation.>> Mathematicians use the = notation and the meaning is clear from>> the context.> Since programmers rarely have the full context of the mathematics,> it seems to me to be better not to use =.> Lisp has setf for assignment> = for numeric equality> eq for identical equal addresses> equal for list structure> eql ...> C uses = for assignement and == for equality, that's areasonable choice, despite the fact that CAS users makemistakes because they write tests with =.>> Ask anyone who used a calculator what * means, you will get>> the answer: * clearly means multiplication.> My calculator has an X on it, not an asterisk (*).> Then buy yourself a more advanced calc that displays an historyof your calculations, you will see the * in the history.>> Yes (except I don't understand what 1.21387128086296d0 means),>> but that's too long, it's better to have an intermediate variable>> gen tmp= w * (z + w - 1.74598656881434d0) + 1.21387128086296d0;>> gen result=- 0.00420059d0 * (x * (x *tmp+ 9.4939615625424d0) - >> 94.9729157094598d0);> That is a double precision float. 1.23d0 means 1.23 X 10^0.The standard scientific notation is e not d between mantissa andexponent, we don't live in the same world!> I do not find infix arithmetic particularly compelling, and it> has the extra problem of requiring you to either understand> the precedence or put in extra parentheses.> The precedence of + and * in e.g. a+b*c is taught during highschool.It is therefore standard notation and it is more compact than(+ a (* b c))> That is because they are better, not because Lisp forces> you to use them!!!> You claim this, but I don't see any reason why.> The answer is in the next sentence:>> I don't have a personal experience in Lisp,> That's why.>> but in reverse>> polish lisp (RPL) where you use a stack and functions are>> applied to their arguments on the stack and return their>> arguments on the stack, for example gcd(a,b) would be>> a b gcd>> (i.e. the reverse of lisp, without parenthesis, which BTW>> requires a fixed number of arguments for every function).>> I have implemented a CAS in RPL and I'm implementing a CAS>> in C++, I can tell you that it's much much easier to do it>> in C++ (it would probably also be easier in Lisp than in RPL but>> both languages have more in common than C++ and RPL or Lisp>> hence my guess that it is in fact harder to write a CAS in Lisp>> than in C++).> Your assumption that RPL and Lisp have more in common than> Lisp and C++ is not reasonable. Regarding standard algebraic notation versus proprietary notationfor arithmetic it makes plain sense.> You should really learn> some Lisp. I suggest Paul Graham's ANSI Common Lisp.> This is a constant of your arguments, you say always learnLisp, then you will be enlightened and you will prefer Lisp.You don't give any argument why I should spend some timeto do so. And since I prefer algebraic notation, I don'tsee any good reason to learn Lisp.>> int egcd(int a,int b,int & u,int &v);> Yes, that is a similar situation.> In Lisp you could handle the return of some number of arguments> in a variety of ways, but one is this way:> (multiple-value-bind (u v) (egcd a b) ... compute with u, v ....)> where egcd would look like this...> (defun egcd(r s) ..... compute stuff..... (return (values c d)) ..)> So what? In fact the C like method allows you to modifyvalues in u and v (not very useful for egcd, but it isvery useful for example if you want to add some elementsto a vector), without any copy.>> This has nothing to do with clarity of an algorithm.> It means you can't debug a function f(a,b,c) in Maple> by typing in f(a,b,c). You must write a procedure to call> it if you want the same semantics.> I don't understand what you mean.>> I don't see why. As I said each language has its good points>> and weak points. I would probably use an interactive language for>> a quick test without much programming, but not for a complex task>> with many subroutines.> Why would you not use an interactive language for a complex task?> Sorry, I didn't mean an interactive language, I meant a scriptinglanguage like Maple/Mupad/... one, which are not standardizedand do not give real tools to write e.g. a 100,000 lines program.> My experience is that programs written in C require extensive> re-porting to run in different environments. The use of a configure> script is an example of how much effort is required to make a> program in C run on every platform. Of course other programming> languages may need such help, but it is simply not true that a> program written in C or Java will run on an arbitrary platform.> If you do this from the beginning, porting to another platformis not hard, sometimes just recompilation of some libraries.> Since you seem to look at GMP as an example, can you compare the> ease with which you can use GMP from Python, C++, Perl, Ruby, Java,> Lisp? Actually, I suspect that the obvious interface between C and> GMP leaks memory.> In a C++ program, as I said in my previous message, youuse it like the int type.> No, mpz_class and vector do the storage management, you can use>> them like a fixed-length data type in a C++ program.> If you have variables which point to mpz (gnu multiple-precision > integers), how do you know when the numbers can be erased? Perhaps> you are assuming no shared values, in which case an assignment> a=b must become mpz_deallocate(a); a=mpz_copy(b).> This is not a very good plan.> Allocating storage is easy. Deallocating storage is harder to> do correctly.> If I don't care, it will not be plain efficient, but it will workif I want to be efficient, I will use directly GMPor make myself a class around GMP to share numbers(that's exactly what I do for my C++ CAS).> Simple? is a product of two big numbers simple or not? A call to> a GMP routine? How about two rational numbers? Two complex numbers> whose real and imaginary parts are huge rational numbers? Does> a/b rationalize the denominator for complex a,b?> Yes to all. Maybe the * operation in GMP requires advancedarithmetic to be efficient but it is a simple operationif you don't think about efficiency and is thereforeexpected to be done. To the contrary, there is no reasonto believe that x^2-1 is better than (x+1)*(x-1), thereforemultiplying x+1 by x-1 should do the minimal operation.>> You must do something more (i.e. quote the * operation),>> because one expects 2*2*3 to return 12.> Oh, so what is the point of the overloaded * operation? Now you> must do something like create_tree(*,create_tree(*,2),2),3).> So some of the operations you claim can be done with overloaded> C++ operations don't work that way.> In a C++ program, I will never use a tree to store the integerfactor decompositions, I would use a vector. I will maybeneed to do it once for display purpose in an interactiveCAS session that's all. I use * many many times in my C++ code.Hence your counter-example does not prove that overloading* is not interesting.>> You probably mean how far would they be if they had choosen Lisp?>> We will never know! My guess is they would not be as good,>> simply because the people who use C-like languages outperforms>> the number of people who use Lisp-like languages and the percentage>> of good programmers is probably not very different in any language.> I am not sure I can parse your statement. If you are saying that> there are more C programmers than Lisp programmers, that is true.> If you say that they are equally productive, the only (limited)> evidence I have seen is that some Lisp programmers are very productive, > and attempts to compare them to C programmers usually ends up with Lisp > being better. A search on google finds a few of these comparisons.> I claim that even if there is a higher percentage of good Lispprogrammers than C/C++ programmers, but the number of C/C++programmers would more than compensate.> Here's a nice essay by Paul Graham ...> http://www.paulgraham.com/icad.html> I'm not sure he has collected objective arguments. === > The precedence of + and * in e.g. a+b*c is taught during highschool.> It is therefore standard notation and it is more compact than> (+ a (* b c))(* a b c (+ d e f)) vs a*b*c*(d+e+f)gives 12 tokens vs 13 tokens === >> The precedence of + and * in e.g. a+b*c is taught during highschool.>> It is therefore standard notation and it is more compact than>> (+ a (* b c))> (* a b c (+ d e f)) vs a*b*c*(d+e+f)> gives 12 tokens vs 13 tokens> Actually it is 19 vs 13 if I'm not wrong, you forgot the spaces. <2e971b12.0312090900.23f9e599@posting.google.com> <3FD6EFEF.8060007@tcs.inf.tu-dresden.de> <2e971b12.0312100926.4d5dc400@posting.google.com> <3FD9B18C.4080907@users.ch> === bernar >> (* a b c (+ d e f)) vs a*b*c*(d+e+f)bernar >> bernar >> gives 12 tokens vs 13 tokensbernar >> bernar >bernar >Actually it is 19 vs 13 if I'm not wrong, you forgot the spaces.To add up n 1-digit positive numbers in LISP, it requires:2n+3 characters.To add up n 1-digit positive numbers with infix notation, it requires:2n-1 characters.So you 'win' by 4 characters. Woo-hoo.But with LISP, you get elegant notation. Unless you get a thrillout of explicit '+' signs all over the place, it makes much more senseto put it in front.Honestly, both C++ and LISP give you the power to build your own infixoperators. But how often does one do that, rather than just building afunction which can take an arbitrary number of arguments, and thendistribute the operators? Honestly?Infix limits you to functions of two arguments. There's no suchlimitation with post- or prefix. ~Tomer === > To add up n 1-digit positive numbers in LISP, it requires:> 2n+3 characters.> To add up n 1-digit positive numbers with infix notation, it requires:> 2n-1 characters.> So you 'win' by 4 characters. Woo-hoo.> Yes, and that's not negligible since n should be kept small to keepreadability. Instead of long undecipherable expressions,I much prefer intermediate statements.> But with LISP, you get elegant notation. Unless you get a thrill> out of explicit '+' signs all over the place, it makes much more sense> to put it in front.> In a CAS, you are going to do arithmetic operationsoften, therefore I maintain that lisp notation is not as elegantas algebraic notation since algebraic notation is much morelike mathematical notation. Even maxima, a CAS programmed in Lisp,uses algebraic notation for its own proprietary language. === > In a CAS, you are going to do arithmetic operations> often,Perhaps surprising, this is likely to be false. CAS internalprograms tend not to evaluate numerical objects, but manipulatedata. Most of the arithmetic is likely to be in iterating overthe index of an array. In the whole program to multiply polynomials,you probably see one occurrence of multiplication of the coefficients,and one occurrence of addition of exponents. You see muchmore data allocation and checking. therefore I maintain that lisp notation is not as elegant> as algebraic notation since algebraic notation is much more> like mathematical notation. Even maxima, a CAS programmed in Lisp,> uses algebraic notation for its own proprietary language.Maxima, along with most CAS, has a user command language intended to mimic mathematical notation. It is loosely based on Algol 60. For Maxima, some internal programs are written in this language(translated into Lisp automatically). It doesn't give convenientaccess to all aspects of the data, but sometimes that doesn't matter.It makes interfacing with Maxima evaluation and simplificationmore automatic, and (especially for the novice) it indeed provides very generic operations of +, *, / ... in an infix notation.I think a better example may be Maple or Mathematica each of whichhas large portions of its system routines written in the userlanguage. Does that mean those languages are best for implementinga CAS? Probably not, because if that were the case, the Mathematicapeople would stop writing any more in C. Not the case. I don't knowabout Maple.. in fact they may refrain from writing in C except foruser-interface stuff. Maybe someone who knows can answer.> === > The precedence of + and * in e.g. a+b*c is taught during highschool.> It is therefore standard notation and it is more compact than> (+ a (* b c))>> (* a b c (+ d e f)) vs a*b*c*(d+e+f)>> gives 12 tokens vs 13 tokens> Actually it is 19 vs 13 if I'm not wrong, you forgot the spaces.> How much lexical analysis did you ever do ? Spaces aren't tokens. In any case, if what you mean is a measure of perceptive/cognitive load of parsing the two styles of expressions, then put a*b*c*(d+e+f) into the properly spaced, readable style, that will save the reader's nervous system from needlessly having to sort out from context, that the *'s and the +'s of the C expression shouldn't be interpreted as prefix or postfix operators. === >> The precedence of + and * in e.g. a+b*c is taught during highschool.> It is therefore standard notation and it is more compact than> (+ a (* b c))>> (* a b c (+ d e f)) vs a*b*c*(d+e+f)>> gives 12 tokens vs 13 tokens>> Actually it is 19 vs 13 if I'm not wrong, you forgot the spaces.> How much lexical analysis did you ever do ? Spaces aren't tokens. In any case,> if what you mean is a measure of perceptive/cognitive load of parsing the two> styles of expressions, then put a*b*c*(d+e+f) into the properly spaced,> readable style, that will save the reader's nervous system from needlessly> having to sort out from context, that the *'s and the +'s of the C expression> shouldn't be interpreted as prefix or postfix operators.For the compactness argument, it seems to me 19 characters vs 13 charactersas Parisse mentioned (spaces are not required in C/C++/Java whereas theyare in Lisp).Carlos. === The precedence of + and * in e.g. a+b*c is taught during highschool.>It is therefore standard notation and it is more compact than>(+ a (* b c))>>(* a b c (+ d e f)) vs a*b*c*(d+e+f)>>gives 12 tokens vs 13 tokens>>Actually it is 19 vs 13 if I'm not wrong, you forgot the spaces.>How much lexical analysis did you ever do ? Spaces aren't tokens. In any case,>>if what you mean is a measure of perceptive/cognitive load of parsing the two>>styles of expressions, then put a*b*c*(d+e+f) into the properly spaced,>>readable style, that will save the reader's nervous system from needlessly>>having to sort out from context, that the *'s and the +'s of the C expression>>shouldn't be interpreted as prefix or postfix operators.> For the compactness argument, it seems to me 19 characters vs 13 characters> as Parisse mentioned (spaces are not required in C/C++/Java whereas they> are in Lisp).If string length rather than token count was an appropriate measure of expression readability, then you shouldn't ever use identifiers longer than a character or two. Having suffered decades ago with Wang Basic that only allowed letter+digit as identifier, I can tell you this is a ridiculous notion. === >> Actually it is 19 vs 13 if I'm not wrong, you forgot the spaces.> How much lexical analysis did you ever do ? Spaces aren't tokens.If you insist on the rigorous definition, spaces might be token,it depends what you put in your lexer. Most of the time a lexerfile will contain something like[ t]+ /* skip whitespace */but there is no obligation to do that.I should better have spoken of number of keystrokes, somethingcalculator users find important.> In any > case, if what you mean is a measure of perceptive/cognitive load of > parsing the two styles of expressions, then put a*b*c*(d+e+f) into the > properly spaced, readable style, that will save the reader's nervous > system from needlessly having to sort out from context, that the *'s and > the +'s of the C expression shouldn't be interpreted as prefix or > postfix operators.> Sorry I don't understand (English is not my native language).If you want to say that spaces should be added in a*b*c*(d+e+f)to give a readable expression, then it's your choice, but I findit perfectly readable. I would add space before and after =for example, but not in that expression. === > Actually it is 19 vs 13 if I'm not wrong, you forgot the spaces.> How much lexical analysis did you ever do ? Spaces aren't tokens.> If you insist on the rigorous definition, spaces might be token,> it depends what you put in your lexer. Most of the time a lexer> file will contain something like> [ t]+ /* skip whitespace */> but there is no obligation to do that.Unless the language grammar creates a necessity for it by ascribing a non-standard role to spaces, doing it another way is simply incompetent.> I should better have spoken of number of keystrokes, something> calculator users find important.I thought we were discussing programming languages.>> In any case, if what you mean is a measure of perceptive/cognitive >> load of parsing the two styles of expressions, then put >> a*b*c*(d+e+f) into the properly spaced, readable style, that will >> save the reader's nervous system from needlessly having to sort out >> from context, that the *'s and the +'s of the C expression shouldn't >> be interpreted as prefix or postfix operators. Sorry I don't understand (English is not my native language).Translation : Si ce que vous voulez est une mesure compar.8ee de la charge cognitive/perceptive que comporte l'analyse des deux styles d'expressions, eh bien, .8ecrivez donc d'abord a*b*c*(d+e+f) en un style ad.8equatement a.8er.8e, qui va permettre au syst.8fme nerveux du lecteur l'.8economie d'avoir .88 .8etablir .88 partir du contexte, que les * et les + de l'expression en langage C ne se peuvent interpr.8eter comme des op.8erateurs pr.8efix.8es ou postfix.8es .> If you want to say that spaces should be added in a*b*c*(d+e+f)> to give a readable expression, then it's your choice, but I find> it perfectly readable. I would add space before and after => for example, but not in that expression.I did not say it was impossible to read, I did say that if you want to count spaces in the lisp expression as a measure of reading complexity, you should take into account that, while C expression syntax allows you to glue the expressions parts together without intervening spaces, this is an operation that fails to alleviate reading complexity : because it makes the burden of disambiguating operator characters all the more acute. === > Unless the language grammar creates a necessity for it by ascribing a > non-standard role to spaces, doing it another way is simply incompetent.> I agree. It's just that you take rigorous definitions whenI think it is not appropriate, so I decided to be fully rigorous.>> I should better have spoken of number of keystrokes, something>> calculator users find important.> I thought we were discussing programming languages.>No we are speaking of representations of mathematical expressionsin different programming languages.Sometimes spaces are mandatory, sometimes not.In your lisp expression, spaces are mandatory, thereforecounting tokens as in the rigorous definition is not adequate,I find the number of calculator keystrokes in conjunctionwith being near to the standard mathematical notation to bemuch more adequate.> Translation : Si ce que vous voulez est une mesure compar.8ee de la charge > cognitive/perceptive que comporte l'analyse des deux styles > d'expressions, eh bien, .8ecrivez donc d'abord a*b*c*(d+e+f) en un style > ad.8equatement a.8er.8e, qui va permettre au syst.8fme nerveux du lecteur > l'.8economie d'avoir .88 .8etablir .88 partir du contexte, que les * et les > + de l'expression en langage C ne se peuvent interpr.8eter comme des > op.8erateurs pr.8efix.8es ou postfix.8es .> Unfortunately the (probably automatic) translation) does notclarify anything.> I did not say it was impossible to read, I did say that if you want to > count spaces in the lisp expression as a measure of reading complexity, > you should take into account that, while C expression syntax allows you > to glue the expressions parts together without intervening spaces, this > is an operation that fails to alleviate reading complexity : because it > makes the burden of disambiguating operator characters all the more acute.> You are probably not programming frequently in C/C++/any languagethat use standard math notation for arithmetic. I can insure youthat I find a*b*c*(d+e+f) to be much more readable than anythingequivalent written with spaces. On the other hand, I would use spacebefore and after =. And of course I will try to uselocal variables identifiers that are 1 char long to help readability,like mathematicians who use always 1-letter symbols. === > Unfortunately the (probably automatic) translation) does not> clarify anything....> You are probably not programming frequently in C/C++/any language> that use standard math notation for arithmetic.Your presumptions are both totally wrong. Mais comme on dit, il n'y a pire sourd que celui qui ne veut pas entendre, et qui veut tuer son chien l'accuse de la rage. Je vous laisse .88 vos petits jeux d'autiste. Je me contenterai de vous mettre sous le nez que la syntaxe d'expression C est en fait, elle-m.90me, fort loin de la notation mathematique standard. === And of course I will try to use> local variables identifiers that are 1 char long to help readability,> like mathematicians who use always 1-letter symbols.This looks like a troll. Certainly this is a foolish argument.Given a common lisp system, you can load in the cgol software. Then youcan either run cgol in your lisp, or put #.(cgol) at the top of yourfile.Then you can do this.. define fib (n) ;if (n=0) then 0 else if (n=1) then 1 else fib(n-1)+fib(n-2) $ fib(4)$ define q(a,b,c); a+b*(c+b)$etc...You get responses like this.....(cgol(1)> define fib (n) ;if (n=0) then 0 else if (n=1) then 1 else fib(n-1)+fib(n-2) $ lisp> (defun fib (n) (cond ((= n 0) 0) ((= n 1) 1) (t (+ (fib (- n 1)) (fib (- n 2)))))) value> fibcgol(2)> fib(4)$ lisp> (fib 4) value> 3cgol(3)> define q(a,b,c); a+b*(c+b)$ lisp> (defun q (a b c) (+ a (* b (+ c b)))) value> qcgol(4)> q(1,2,3)$ lisp> (q 1 2 3) value> 11cgol(5)>> etc. This is all open source, and you can removethe various messages about lisp. etc.you can return to lisp syntax by typing $$The original CGOL paper and implementation is quite old,dating to 1973.The cgol software is available in various places, butwww.cs.berkeley.edu/~fateman/cgol/cgol.1 is one of them.Also 1.23d0 is like 1.23e0, except it specifiesdouble-precision. === > And of course I will try to use>> local variables identifiers that are 1 char long to help readability,>> like mathematicians who use always 1-letter symbols.> This looks like a troll. Certainly this is a foolish argument.Local variable are only relevant to a small area of a program(say 10 to 100 lines), I don't see why identifiers for localvariables should be more than 1 char. It's of course not thecase for global variables. That's exactly what mathematiciansdo, they use 1 letter symbols in demonstrations and theoremsbecause the symbols are in some sense local variables in thetheorem or demonstration.> Also 1.23d0 is like 1.23e0, except it specifies> double-precision. Well after some tries, it seems that d is used for floats (whichI never use) and e for doubles. But e is also recognized in e.g.mupad, d is not. Same for calculators. Therefore e is muchmore standard than d. === > That's exactly what mathematicians> do, they use 1 letter symbols in demonstrations and theorems> because the symbols are in some sense local variables in the> theorem or demonstration.No, mathematicians (tend to) use 1 *glyph* symbols, drawn from an arbitrary large alphabet of symbols that borrows from latin, greek, hebrew and adding customizations as necessary to make them sufficiently distinctive. Further, they combine them with a graphical syntax that is nearly 2-dimensional.Using only letters and linear strings, correct equivalents are many-letters identifiers like zeta, hbar or aleph. This goes as well for single-stroke calculator symbols like sin, cos or exp. === >> The precedence of + and * in e.g. a+b*c is taught during highschool.>> It is therefore standard notation and it is more compact than>> (+ a (* b c))> (* a b c (+ d e f)) vs a*b*c*(d+e+f)> gives 12 tokens vs 13 tokens> Depends on your definition of compact.(* (+ a b c) (+ d e f) (+ g h i) (+ j k l)) gives less tokens than(a+b+c) * (d+e+f) * (g+h+i) * (j+k+l), but the distance your eyes have to travel when you read it is smaller than the first one (you have to keep looking at the * at the beginning of the expression), unless you use more memory (in your mind), which again may take longer to read.This is a trivial example, but if you have multiple functions and multiple operators, and you have to keep counting brackets, it doesn't really matter how many tokens an expression consists of.One more example: many lisp systems allow you to end your expression with ))))))))))) even if there are too many )'s. That's because they acknowledge the problem of balancing parentheses and the time it takes human beings to do it. In C no such thing is needed - you hardly ever have a similar situation, and if anything it indicates bad style rather than a feature of the language.It is possible to argue that you can get used to any language (and that you can use a reasonable editor), but it's still less natural (given the educational system, of course) to read(/ m (sqrt (/ (* v v) (* c c))))thanm / sqrt((v*v)/(c*c))How many passes are required for your eyes to read the first? The second notation...sqrt 2 is irrational, because if sqrt 2 = / p q, then 2 = / * p p * q q. === =, it doesn't> really matter how many tokens an expression consists of.> One more example: many lisp systems allow you to end your expression > with ))))))))))) even if there are too many )'s.I am not familiar with any such lisp system. I have seen (old) lispsystems which allow you to type ] to close all open parens, orat least up to the last [. This was interlisp, last used in 1985 orso.Almost all editors provide parenthesis matching, flashing thebalancing parens as you type. If you are writing programs usingany variation of emacs, this is certainly the case. I do not findthis requires any intellectual effort, and my freshman studentsnever remark on this. I find the comment that Lisp has too manyparentheses to come from people who have only written Lisp witha pencil, and not actually written a program in a lisp environment. That's because they> acknowledge the problem of balancing parentheses and the time it takes > human beings to do it. In C no such thing is needed - you hardly ever > have a similar situation, and if anything it indicates bad style rather > than a feature of the language.> So you never have to think about parenthesis matching? Maybe you shouldlook at my earlier post. Can you write f(a+f(b+f(c+f(d+e)....) in C?Maybe it is your poor programming style? By composing functions, a verypowerful technique, you can write very concise and well-structuredcomputations. They tend to look like nested functions, and they tendto end with lots of ))))) !> It is possible to argue that you can get used to any language (and that > you can use a reasonable editor), but it's still less natural (given the > educational system, of course) to read> (/ m (sqrt (/ (* v v) (* c c))))> than> m / sqrt((v*v)/(c*c))It is also natural to do what a physics textbook of mine did, which wasto say1/2pi f(x) and mean1/(2* pi) * f(x) instead of(1/2) * pi * f(x) which is what a programmer might think.So what is natural is sometimes wrong.Also the precedence of * and + is not the only issue. you need to know the precedence and binding of ^. e.g. a^b^c. And you need toknow the precedence of == & | && || . Manyprogrammers do not know the precedence of operators. I think that inC there are 13 levels, and * occurs in 3 different ones, with differentmeanings. Confusion between = and == is a common source of seriouserrors.Do you, offhand, know if you need parentheses in a==b&c++ orp+qp+++qp+++++qHow many passes do you need to understand these, if in fact theymake sense?> How many passes are required for your eyes to read the first? The second > notation...> sqrt 2 is irrational, because if sqrt 2 = / p q, then 2 = / * p p * q q.This is not actually a difficult task.2 = (/ (* p p) (* q q))is, I think, pretty easy to read. For large expressions, such a layoutis a major improvement. It actually reflects the algebraic tree of theoperators, turned sideways.For small expressions you might want to have an infix reader installedin your lisp system, mentioned earlier, so you could write(setf z #.[p^2/q^2])or you could write a whole file of lisp beginning#.[ ....and ending ]so that your whole file is in infix. Actually, the parser forMacsyma, written in Lisp, can be embedded this way, so you caninsert arbitrary Macsyma expressions in Lisp source code.The Reduce system has had such a system (called, I think, Algebraic Mode?) of infix, for maybe 30 years. TheCGOL system is an Algol-like version of Lisp that has been around for30 years or so too.The syntax is not an issue for the vast majority of people who havetried lisp. It is that way because it is good. It is not that wayas a punishment, or because it is a negative consequence of thedesign. It is a benefit.> === > (* (+ a b c) (+ d e f) (+ g h i) (+ j k l)) gives less tokens than> (a+b+c) * (d+e+f) * (g+h+i) * (j+k+l), but the distance your eyes have > to travel when you read it is smaller than the first one (you have to > keep looking at the * at the beginning of the expression), unless you > use more memory (in your mind), which again may take longer to read.I don't buy this argument *at all*, since associativity and precedence rules of infix notation make the parse tree unstable with respect to substitution of operators.But frankly, I find the difference minute in any case. Don't read me wrong, I do like infix notation, but the experience of having to collaborate to a lisping team forced me to quickly acknowledge prefix-style as very competitive in practical readability.For instance, I see> (/ m (sqrt (/ (* v v) (* c c))))and> m / sqrt((v*v)/(c*c))as quite equivalent, with a slight advantage to the first form because of the double (( of the infix style. Imho the parsing cost of multiple opening parentheses is much higher than for closing parentheses : I invite you to check that to parse the first expression, it is sufficient to assume that the closing parens balance and not necessary to detail what each one balances, while in the case of the second form you do need to match the parens individually. === > I'm a mathematician, and again I can insure you I never> saw this notation before. Which means for me a couple> of (integers or polynomials). Maybe it's a local US notation.Sorry, parisse, I'm a (austrian-french) mathematician too, and I also know*only* (b,c) for gcd. Of course, I use it also for pairs and there are probablyother things I use it for too. I never saw the symbol ^ used for gcd though.You are not trolling, are you?Martin === >>I'm a mathematician, and again I can insure you I never>>saw this notation before. Which means for me a couple>>of (integers or polynomials). Maybe it's a local US notation.> Sorry, parisse, I'm a (austrian-french) mathematician too, and I also know> *only* (b,c) for gcd. Of course, I use it also for pairs and there are probably> other things I use it for too. I never saw the symbol ^ used for gcd though.> It's not the exponent symbol but the and symbol (i.e. move a littlebit ^ down). But as I said in my first or 2nd post in this thread,there is no standard mathematical notation for gcd, hence gcd(a,b)is the only reasonable notation.> You are not trolling, are you?Of course not.If you think so, you should ask yourself the same question seeingsome arguments in this thread... === I would like to make a secondary axis in MathCAD 2000 Professional. i.e. I want to plot two functions on thesame graph, but I want different scales for the two functions. Excelcan do this for the y-axis. I can't figure out whether MathCAD can doit at all. Ideally I'd likw to be able to do this for both axes.