Skip to content
AgileLogics
6 min read

Defining Functions

Prerequisites: Loops and iteration

square[x_] := x^2
square[4]
square[a + b]
16
(a + b)^2
  • x_ (with an underscore) is a pattern that matches any argument and names it x.
  • := evaluates the right side each time the function is called.
  • The function works on symbols too.

Several arguments and defaults

area[w_, h_] := w h
area[3, 4]

greet[name_: "world"] := "Hello, " <> name <> "!"
greet[]
greet["Ada"]
12
Hello, world!
Hello, Ada!

name_: "world" gives a default value.

Restricting arguments

half[n_Integer] := n/2
half[7]
half[2.5]
7/2
half[2.5]

n_Integer only matches integers. When no definition matches, the call is simply returned unevaluated — no error.

Several definitions

A function can have several definitions; the most specific one wins:

fact[0] = 1;
fact[n_Integer?Positive] := n fact[n - 1]
fact[5]
fact[-1]
120
fact[-1]

?Positive adds a test to the pattern. fact[-1] matches neither definition, so it stays as it is instead of recursing forever.

Local variables with Module

sumOfSquares[n_] := Module[{total = 0},
  Do[total += i^2, {i, n}];
  total
]
sumOfSquares[3]
14

Module[{vars}, body] creates local variables that don't clash with anything outside. Statements are separated by ;, and the last one is the result.

?sumOfSquares shows a function's definitions; Clear[sumOfSquares] removes them.

Common mistakes

  • Forgetting the underscore: f[x] := x^2 defines f only for the literal symbol x, so f[3] stays f[3].
  • Using = instead of := — the right side is evaluated at definition time:
x = 5;
g[x_] = x^2;
g[3]
25

x^2 was evaluated to 25 when g was defined, because x had a value. With := you get 9.

Practice

Define bmi[weightKg_, heightM_] that returns the body-mass index (weight divided by height squared), rounded to one decimal, and try it with 70 kg and 1.75 m.

Show solution
bmi[weightKg_, heightM_] := Round[weightKg/heightM^2, 0.1]
bmi[70, 1.75]
22.9