Clear[a,b,c,d,e,f]

f[x_]:=x^2

f        function name
x_     argument  (pattern)
:=     delayed assignment
x^2  definition

f[3]

f[a]

f[{1,2,3}]

??Power

f[3,b]

?f

A quick note on syntax

fun[argument]
fun@argument
argument//fun

fun[arg1,arg2]
arg1~fun~arg2 
Apply[fun,{arg1,arg2}]
fun@@{arg1,arg2}

sol=Integrate[Sin[2 x] Cos[x/2], {x, 0, 1}]

N[sol]
sol//N
N@sol

Table[Sin[(i+j)^-1],{i,4},{j,3}]//MatrixForm

(Sqrt[Table[Sin[(i+j)^-1],{i,4},{j,3}][[2]]]//N)[[3]]

How to define a function for different datatypes?

g on real numbers :  identity function 
g on integers : factorial
g on lists : Length

?Switch

Head[{3,4,5}]

FullForm[{3,4,5}]

Head[Pi]

Clear[g]

g[x_]:=
Switch[ Head[x],
Integer, x!,
Real, x,
List, Length[x],
_, Print["something else"]; (* Abort[] ?  Hold[g[x]] *)
]

g[3.1415]

g[Pi]

g[5]

g[{1,2,{3,4},{}}]

g["s"]

?x

g[x]

Patterns with data type

Clear[g]

g[x_Real]:=x

g[x_Integer]:= x!

g[x_List]:= Length[x]

g[x]

g[Pi]

g[N[Pi]]

Types: Integer, Real, Complex, Symbol, List

Clear[f]

f[x_]:=Sin[x]/x

Plot[f[x],{x,-5,5}]

f[0]

?f

f[0]:=1;

First@Limit[Sin[x]/x,{x->0}]

Clear[f]

f[0]:=First@Limit[Sin[x]/x,{x->0}]

f[0]

?f

f[0]

Better idea?
:= vs =

f[0]=Limit[Sin[x]/x,{x->0}][[1]]

More examples

Clear[h]

h[x_,y_]:=x+y

{h[1,2],
h[2,2],
h[2,{2}],
h[Pi,{1,2}],
h[{Pi},{1,2}],
h[{1,2},{1,2}],
h[Pi,E,1,2]
}

h[x_,x_]:=x

?h

{h[1,2],
h[2,2],
h[2,{2}],
h[Pi,{1,2}],
h[{Pi},{1,2}],
h[{1,2},{1,2}],
h[Pi,E,1,2]
}

?h

h[x_,{1,2}]:=  {1,2}[[Random[Integer]+1]]

?h

{h[1,2],
h[2,2],
h[2,{2}],
h[Pi,{1,2}],
h[{Pi},{1,2}],
h[{1,2},{1,2}],
h[Pi,E,1,2]
}

?h

Clear[g]

g[x_,{1,2}]:=  {1,2}[[Random[Integer]+1]]

g[x_,x_]:=x

?g

g[{1,2},{1,2}]

NOTE: The order and the generality of the definitions is crucial. The more specific a definition, the earlier is tested: a definition for x_Integer is tested before a definition for x_.

ff[x_]:=x^2

ff[x_Integer]:=x

?ff

ff[4]

gg[x_Integer]:=x

gg[x_]:=x^2

gg[4]

For overlapping definitions with the same level of generality, the earlier the definition is evaluated the earlier it gets tested.

Clear[ff,gg]

ff[x_/;x<4]:=x

ff[x_/;x>2]:=x^2

Plot[ff[t],{t,0,6}]

ff[4]

gg[x_/;x>2]:=x^2

gg[x_/;x<4]:=x

Plot[{gg[t],ff[t]},{t,0,6}]

gg[2]

?ff

?gg

Back to h

?d

?h

{h[{d[1],d[2],d[3],d[4],d[5]},{1,2}],  
h[y,y],
h[,{1,2}]}

x=2+a;
{h[x,x], h[2+a,x]}

h[{x_}] := -1

?h

{h[d],h[{1,2}]}

{h[{d}],h[{{1,2,3}}],h[{{{1,2},{3,4}}}]}

How to define functions that accept a variable number of arguments?

Clear[h]

Definitions of h for one and two arguments

h[x_]:= x + x

h[x_,y_]:= {y,x}

{h[3],h[{{{1}}},"second argument"],h[1,2,3]}

The double underscore matches any NONEMPTY list of arguments

?h

h[l__]:=Reverse[{l}]

{h[1,2,3],
h[{1},{2},{3},{4},5,6,7,8],
h[{1,2,3}],
h[]}

hh[l__/;Length[{l}]≥2]:={l}[[2]]

hh[1,2,3]

The triple underscore matches ANY list of arguments, including the empty list

h[l___]:=Length[{l}]

h[]

?h

Clear[h]

It is possible to assign a name to structures comprising several patterns.

h[x_,{1,2}]:=  {1,2}[[Random[Integer]+1]]

h[off_,pair:{_,_}]:= pair[[Random[Integer]+1]]+off

h[off_,{v1_,v2_}]:= {v1,v2}[[Random[Integer]+1]]+off

h[off_,pair_/;Length[pair]==2]:= pair[[Random[Integer]+1]]+off

h[10,{7,6}]

Clear[f]

f[x:_^_]:=p[x]

{f[2^3],f[Pi^2],f[a^b]}

f[x:_^e_]:=p[x,e]

{f[2^3],f[Pi^2],f[a^b]}

?f

h[x_]:=x^3

Clear[h]

f[h[_],h[_]]:=q

{f[h[4],h[5]], f[h[Pi],h[Pi]]}

Clear[ff]

ff[x_,x:h[_]]:=r[x]

{ff[h[4],h[5]], ff[h[Pi],h[Pi]]}

Clear[f]

f[m:{{a_, 0},{b_, c_}}]:=  m[[2]]

or alternatively

f[m:{{_, 0},{_, _}}]:=  m [[2]]

but also

f[{{_,0},m:{_,_}}]:=m

f[{{a_,b_},{c_,d_}}] :=  a d - b c

f[
{{1,2},
{2,3}}
]

now what?

?f

f[
{{1,0},
{a,b}}
]

f[
{{exp1, 1},
{exp1, exp1}}
]

More about patterns. Tests and constraints on a pattern can be specified through ? and /; after the underscore.
f [ x_ ? testFunction ] := ...
x is matched only if testFunction[ x ] returns True.
f [ x_?EvenQ ] only matches even numbers.
f [ {x_, y_} /; condition( x, y ) ] only matches the pairs {x, y} that satisfy the condition.

Factorial
n Integer & Positive :  n!
n Integer & Negative : (-n)!
x Real &Positive: floor(x)!
x Real &Negative: ceiling(x)!

?If

Quit[]

fact[n_]:=
If[n==0, 1,
If[n>0,n*fact[n-1],fact[-n]]
]

myfact[0]=1;
myfact[n_Integer?Positive]:=n myfact[n-1]

myfact[n_Integer?Negative]:=myfact[-n]

myfact[x_Real/;x>0]:=myfact[Floor[x]]

myfact[x_Real?Negative]:=myfact[Ceiling[x]]

myfact[0]

?myfact

h[x_,2x_]:=x^2-3

{h[3,6],h[Pi,2Pi],h[x,2 x],h[Sin[x], 2 Sin[x]]}

Clear[h]

h[x_,y_]/;y==2 x:= x^2-3

{h[3,6],h[{Pi,2Pi}],h[x,2 x],h[Sin[x], 2 Sin[x]],h[0,0]}

Clear[g]

g[ {x_, y_,l___}/; x+y == 4 ]:= {l}

g[{3,1,2,2,4,1}]

g[g[{3,1,2,2,4,1}]]

g[g[g[{3,1,2,2,4,1}]]]

g[x_/;x>2]:= Sin[x]
g[x_Real]:=x^2
g[x_Complex]:=Exp[-x]
g[x_Integer]:=Prime[x]

Plot[g[x],{x,-1,6}]

what does the following pattern match?

t[f_[a_,b_]]:={f,a,b}

t[g[a,b]]

t[Sin[x,y]]

t[Sin[x+y]]

t[Sin[3+Pi]]

Sin[3+Pi]

FullForm[Sin[3+Pi]]

t[f_[_,b_]_]:=(Print["match!"];{f,b})

FullForm[f_[_,b_]_]

k=t[3 myfun[3,exp]]

Optional arguments

Clear[f,M]

f[a_, b_, c_,mode_:"Lower"]:=
Which[
 mode == "Lower", 
{{a, 0},
{b,c}},
mode=="Upper",
{{a,b},
{0,c}},
True,
Print["mode error in function f"];Abort[]
]

f[M[1],M[2],M[3],"Upper"]//MatrixForm

f[M[1],M[2],M[3],"Lower"]//MatrixForm

f[M[1],M[2],M[3]]//MatrixForm

f[TL,BL,BR,"Symmetric"]//MatrixForm

Clear[f]

f[a_^b_]:={a,b}

{f[1^2],f[2^1],f[Pi^(t+y)],f[(t+y)]}

ff[a_^(b_:1)]:={a,b}

{ff[1^2],ff[2^1],ff[Pi^(t+y)],ff[(t+y)]}

Recap

f[x_]:= (* general function definition *)

f[x_List]:= (* restricting the type of the arguments *)

f[x_,y_]:= (* multiple arguments *)

f[x_,"a"]:= (* fixing one of the arguments *)

f[x_/?NumberQ[x]]:= (* test on argument x *)

f[x_,y_,z_/;condition[z]]:= (* condition on argument z *)

f[x_,y_,z_]/;condition[x,y,z]:=(* condition on arguments *)

f[a_,b__,l___]:=
(* matching one element, a non-empty list of elements, any list  *)

f[a_,b__,l___]:={l}

f[a_+b_]:=(* specifying the form of the argument *)

f[{{a_,b_},___}]:=(* again, specifying the shape of the argument *)

f[m:{_^b_}]:=Power[m,-b]:=(* assigning names to parts of a pattern *)

f[a_,b_:Pi]:=Sin[a+b]:= (* default arguments *)

replacement rules and patterns

simplification

log[a b c d]//FullForm

log[a b c d]/.{log[x_, y_]->log[x]+log[y]}

log[a b c d]//.{log[Times[a_, b_]]->log[a]+log[b]}

the solutions of equations are provided in the form of replacement rules

p[x_]:=x^3-Pi x^2-Pi^2 x-3

Plot[p[x],{x,-Pi/2,3/2Pi}]

sol=Solve[p'[x]==0,x]

p'[x]/.sol

p[x]/.sol

p[x]/.sol//N

options to Mathematica functions

ParametricPlot[
{Sin[u]u ,Cos[u]u}, 
{u,0,100}
]

Options[ParametricPlot]

ParametricPlot[
{Sin[u]u ,Cos[u]u}, 
{u,0,100},
PlotPoints->125,
Axes->False,
ColorFunction->(ColorData["Rainbow"][#3]&),
MaxRecursion->0,
PlotStyle->Thick
]

a program that accepts replacement rules as optional arguments

options[program]={opt1->val1, opt2->val2};

program[x_,y_,opt___]:=
definition/.{opt}/.options[program]

Sorting anyone?

l=RandomInteger[20,{8}]

l/.{a_,b_}/;a>b->{b,a}

l/.{___,a_,b_,___}/;a>b->{b,a}

l

l//.
{left___,a_,b_,right___}/;a>b->{left,b,a,right}

A little bit of list analysis. Are there two successive entries (a, b) such that b is 2+a?

l={1,3,4,6,8}

l/.{a_,b_}/;b==a+2->b

{1,3,4,6,8}/.{l1___,l2_,l3_,l4___}/;l3==l2+2->{l3,l4}

Only one result. How to get all the possible results?

ReplaceList[
{3,1,5,2,8,6},
{l1___,l2_,l3_,l4___}/;l2>l3->{l3,l2}
]

Very useful for debugging

ReplaceList[
{1,3,4,6,8},
{l1___,l2_,l3_,l4___}->{{l1},l2,l3,{l4}}
]//ColumnForm

Again, list analysis. Finding all the sequences whose left and right elements add up to 6

ReplaceList[
{3,6,-1,4,3,2,1,0,3,6},
{l1_,ll___,l2_}/;l1+l2==6->{ll}
]

ReplaceList[
{3,6,-1,4,3,2,1,0,3,6},
{___,l1_,l2__,l3_,___}/;l1+l3==6->{l1,l2,l3}
]//ColumnForm

Example: Encoding

How to transform a list {a,a,a,a,b,b,a} to{{a,4},{b,2},{a,1}} ?

randL[n_]:=
Table[
If[Random[]>.5,a,b],
{n}]

Clear[randL]

l=randL[15]

Another way of generating a random list of a's and b's (* ignore for now, just use it *)

randL[n_]:=
{a,b}[[#]]&/@(1+RandomInteger[1,{n}])

IDEA: {...{a,n},{a,m},...}->{...{a,n+m},...}

ll=Map[{#,1}&,l]

a

l

ll//.{left___,{x_,n_},{x_,m_},right___}->{left,{x,n+m},right}

replacement rules?
ll

Map[{#,1}&,l]//.{left__,{c_,v1_},{c_,v2_},r__}->{left,{c,v1+v2},r}

Map[{#,1}&,l]//.{left___,{c_,v1_},{c_,v2_},r___}->{left,{c,v1+v2},r}

Pure Functions

Other function definitions:  "Function"  and  "# &"

Function[{x},x^2] is the definition.   [3] is the argument.

Function[{x},x^2]

Function[{x},x^2][3]

f1=Function[{x,y},Sin[x^2+y^2]/Sqrt[(x^2+y^2)]];

Plot3D[f1[x,y],
{x,0,Pi},
{y,0,Pi}
]

As before, #^2 & is the function definition,  [3] is the argument.

#^2&[3]

a

#^3-#^2&[a]

#2 refers to the second input argument

#2&[2,3]

#2&[3]

## catches the entire list of arguments

2{##}&[2,3]

Plot3D[Cos[#1]+Sin[#1 #2]&[x,y],{x,0,Pi},{y,0,Pi}]

Plot3D[Cos[x]+Sin[x y],{x,0,Pi},{y,0,Pi}]

h[f_,k_Integer]:=f[#]^k&

h[Sin,3]

{h[Sin,2][1.3],Sin[1.3]^2}

Plot[{
h[# Sin[#]&,1][x],
h[#Sin[#]&,2][x],
h[#Sin[#]&,3][x]
},
{x,-2,3},
AspectRatio->Automatic]

Plot[
Table[
h[# Sin[#]&,i][x],
{i,3}],
{x,-2,3}]