#Functions

# Define a fourth order polynomial
#           p(x) = 18 x^4  + 69 x^3  - 40 x^2  - 124 x - 48

 p := x -> 18*x^4 + 69*x^3 - 40*x^2 - 124*x - 48;

# Think of the symbol -> as an arrow: it tells what to do with the input
# x, namely, produce the output 18*x^4 + 69*x^3 - 40*x^2 -124*x - 48. To
# understand the historical origins of this notation, read about lambda
# functions, a subject of interest to computer science areas. 

# Define a function with automatic substitutions

 q:=18*x^4 + 69*x^3 - 40*x^2 - 124*x - 48;
 p1:=x->q;         # A complete failure, does not define p(x)
 p2:=unapply(q,x); # How to fix that problem

# Define a function using a procedure

 p3:=proc(x)
  RETURN(18*x^4 + 69*x^3 - 40*x^2 - 124*x - 48);
 end proc;

# Computations
 p(2);         # prints 384
 p1(2);        # prints an expression in x, an error
 p2(2), p3(2); # prints 384
 p( 1/2 );
 p( a+b );
 simplify(%);

# Functions and expressions are different kinds of mathematical objects.
# Compare the results of the following.

 p;    # function, prints p
 p(x); # expression, prints polynomial in x
 p(y); # expression, prints polynomial in y
 p(3); # expression, prints 2541
 factor(p);               # Nothing returned
 factor( p(x) );          # Find 4 linear factors
 solve(p(x)=0,x);         # Find the 4 roots exactly.
 fsolve(p(x)=0,x);        # Find the 4 roots numerically
 plot( p, -2..2 );        # Plot a function
 plot( p(x), x = -2..2 ); # Plot an expression, same plot

# Functions of several variables.

 f := (x,y) -> exp(-x) * sin(y);
 f(1,2);
 g := unapply(alpha*exp(-k*x)*sin(w*y),(x,y));
 g(1,2);
 alpha := 2; k := 3; g(1,2);

 w := 3.5; g(1,2);
 alpha := 'alpha'; g(1,2);