Functions · 14
Functions
Bundle work under a name, take values and return a result — plus recursion.
A function is a named block of code.
It takes values (parameters) and returns a result.
The example below defines a function that squares a number and a factorial function that calls itself.
def square(x): return x * x def factorial(n): if n <= 1: return 1 return n * factorial(n - 1) n = int(input())print(square(n))print(factorial(n))function square(x) { return x * x;} function factorial(n) { if (n <= 1) return 1; return n * factorial(n - 1);} const n = Number(require("fs").readFileSync(0, "utf8"));console.log(square(n));console.log(factorial(n));import { readFileSync } from "node:fs"; function square(x: number): number { return x * x;} function factorial(n: number): number { if (n <= 1) return 1; return n * factorial(n - 1);} const n: number = Number(readFileSync(0, "utf8"));console.log(square(n));console.log(factorial(n));import java.util.Scanner; public class Main { static int square(int x) { return x * x; } static long factorial(int n) { if (n <= 1) return 1; return n * factorial(n - 1); } public static void main(String[] args) { int n = new Scanner(System.in).nextInt(); System.out.println(square(n)); System.out.println(factorial(n)); }}using System; class Program{ static int Square(int x) => x * x; static long Factorial(int n) { if (n <= 1) return 1; return n * Factorial(n - 1); } static void Main() { int n = int.Parse(Console.ReadLine()); Console.WriteLine(Square(n)); Console.WriteLine(Factorial(n)); }}#include <iostream> int square(int x) { return x * x;} long long factorial(int n) { if (n <= 1) return 1; return n * factorial(n - 1);} int main() { int n; std::cin >> n; std::cout << square(n) << '\n'; std::cout << factorial(n) << '\n';}#include <stdio.h> int square(int x) { return x * x;} long long factorial(int n) { if (n <= 1) return 1; return n * factorial(n - 1);} int main(void) { int n; scanf("%d", &n); printf("%d\n", square(n)); printf("%lld\n", factorial(n)); return 0;}square(x){ return x * x;} factorial(n){ if (n <= 1) { return 1; } return n * factorial(n - 1);} n = Console.ReadLine().ToNumber();Console.WriteLine(square(n));Console.WriteLine(factorial(n));4
16 24
Key points
- Wrap code in a function when the same calculation is needed in several places, or to break a long solution into small pieces.
- When
returnruns, the function ends right there.
The lines below it do not run. - Passing a number copies the value.
Changing it withx = 9inside the function leaves the caller's variable alone. - Passing a list shares the same list.
Adding to it inside the function changes it outside too (a C++vectoris copied when passed). - Recursion is a function calling itself.
It shrinks a big problem into a smaller one of the same shape, and it must have a stopping case (n <= 1gives1). - Without a stopping case, or when it goes too deep, the program stops with an error or crashes, depending on the language.
How each language writes it
| Python | def square(x): plus indentation.Without return it returns None.You can only call it after the def has run (earlier is a NameError).Recursion stops at about 1,000 levels with RecursionError |
|---|---|
| JavaScript | function square(x) { return x * x; } or const square = (x) => x * x;.Without return it returns undefined.A function declaration may sit below the call.Too deep: RangeError: Maximum call stack size exceeded |
| TypeScript | JavaScript plus types: function square(x: number): number.The type checker catches a wrong number of arguments |
| Java | static int square(int x) inside a class; void when nothing is returned.It can be anywhere in the class. Too deep: StackOverflowError |
| C# | Like Java: static int Square(int x) inside a class, void when nothing is returned.Too deep a recursion crashes the whole program |
| C++ | Return type first, as in int square(int x); void when nothing is returned.Define it above its use, or declare it first with int square(int x);.Too deep a recursion crashes the program |
| C | Same as C++ |
| Craykon | No keyword: square(x) { return x * x; }.It may sit below the call. After a few thousand levels it stops and says the function was called too deeply |
Common mistakes
Calling with a missing argumentJavaScript
function square(x) { return x * x; }
console.log(square());→ NaN — the missing x is quietly filled with undefined
Pass the right number of values.
Python (TypeError), Java, C#, C, C++, TypeScript (compile error) and Craykon ("2 values are needed but 1 was given") all tell you.
No stopping case
def factorial(n):
return n * factorial(n - 1)→ It calls itself forever and stops with RecursionError. Other languages overflow the stack and stop or crash
Put a stopping case first, such as if n <= 1: return 1.
Changed inside the function, but the original is unchangedC++
void add(std::vector<int> v) { v.push_back(9); }
std::vector<int> a = {1};
add(a);→ a is still {1} — the value went into a copy
To change the original, add &: std::vector<int>& v.
Factorials grow fast.
A 32-bit
int holds only up to 12! (computing 13! with int in Java silently gives 1932053504), so the Java, C#, C and C++ examples return 64-bit long/long long (good up to 20!), while Python has no size limit and JavaScript and Craykon may be inexact beyond 2^53.