# Difference between a Computer Algebra System and a typical programming language

## An equation is just an equation

We can name and re-use an equation. But otherwise an equation is is just an equation as an equation in your notebook would be, not something that immediately has an effect:

eq0:a=b;

pyth:a^2+b^2=c^2;

## If a variable isn't declared nor defined that is OK.

The following equation contains an unknown "x" and an unknown "y".

eq1:x^2+(y+2)*x+3=0;

If we solve that equation without defining y first maxima won't issue an error. Instead the indicator that maxima doesn't know the value of "y" is that the solution contains an "y".

solve(eq1,x);

## Lists

Most maxima commands accept lists. These can be created ad-hoc by enclosing a bunch of comma-separated values in square brackets:

list1:[1,2,a,b,c];

One can create lists according to a rule:

list2:makelist(i*2,i,list1);
list3:makelist(i^2,i,1,10);

Lists can easily be manipulated:

list4:append(list1,list2,list3);

But just assigning the nth element of a list a value doesn't create that list, but a hash:

a[4]:10;
a[qdwqd]:30;
a["qdwqd"]:45;

a;

arrayinfo(a);

## A CAS has many types of Numbers

### Exact rational numbers

Maxima supports many types of numbers:

1/10*π*sqrt(2);

is exactly 1/10*π*sqrt(2).

### Floating-point numbers

0.1*π;

is a floating-point number of the type the machine's floating-point processor uses. These numbers are accurate enough for most uses. But since maxima was developed for symbolic computations not all of the maxima's algorithms deal with the rounding errors floating-point numbers introduce.

### Arbitrary-precision floats

0.1b-1*sqrt(2);

is a floating-point number whose precision can be changed by customizing the variable fpprec. It is way slower than machine floats. But it allows to look what happens if the precision is increased.

## Handling of knowledge

### Storing actual values in a list

Maxima is very good at symbolical maths. That means that if you don't immediately assign variables whose value you know a value the result often is an equation that provides you with additional knowledge about the problem. The actual values can be kept in a list, instead, and be introduced into the equation whenever needed:

vals:[b=3,c=2];

subst(vals,pyth);

### Hard assignments

If we assign a value to an variable that means  that knowledge is used for new equations:

b:3;

pyth2:a^2+b^c=c^2;

vals2:[b=3];

That knowledgie isn't automatically applied to existing equations, though:

pyth;

Two single quote marks make maxima interpret an known equation as one that just has been typed in, though:

''pyth;

If we mean the variable name, not its contents we can tell this maxima by preceding the variable name by a single quote

'b=b;

## Is(a=b) can be evaluated before the real result is known

Even if we might know that we will assign a and c values lateron maxima doesn't know so currently  a≠c:

eq2:a=c;
is(eq2);

If we assign c the value "a" that knowledge isn't immediately used for already-defined equations:

c:a;
is(eq2);

If we tell Maxima to act as if eq2 were typed in right now maxima knows that a=c

is(''eq2);

## Defining functions

If you just want a storage for an equation it often is better to actually keep it in an equation. For example an equation can be solved for x, a function cannot.

If you actually want a mathematical function similar to sin(x) or store a complete program in a function you can do that, though.

### Storing a program in a function

If you don't need any local variables nor the possibility to issue a return() in the middle of a function just put parenthesis around comma-separated commands - and that program will return what the last command will return.

A naive "sum of all numbers up to x" program for increasing x would therefore be:

last_num:0;
last_sum:0;
my_sum(x):=(
    for i:last_num + 1 thru x do last_sum:last_sum + i,
    last_num:x,
    last_sum
);

my_sum(10);

my_sum(11);

If you local variables or a premature return() is needed one needs a block() command:

my_sum(x):=block([result:0],
    for i:1 thru x do
        result:result+i,
    result
);

my_sum(11);

### Functions and variables can have the same name

Normally that is an easy-to-use feature. But when defining a function it makes a difference: Local variables are declared using block(), local functions by the local() command

### Optional arguments

f(x,[y]):=(disp(sconcat(length(y)," optional arguments")),x);

f(a);

f(a,1,2,3);

### return() returns from the current block, not from the whole function

f(x):=block(block(return(test)),return(test2));

f(2);

## Maxima doesn't try hard to hide numerical errors

1/10 is an exact 1/10. But 0.1 is a floating-point variable of the type that your machine uses and is fast in - but that cannot represent an exact 1/10. This is true for all programming languages.

rationalize(0.1);

Maxima's output routine rounds that floating-point number to 0.1, by default. But it doesn't try hard to hide rounding errors if they accumulate:

.1;

%*.1;

%*.1;

%*.1;

%*.1;