From f92661980deac22b54e79cd44c25caba17910c95 Mon Sep 17 00:00:00 2001 From: Louis Pilfold Date: Thu, 18 Jan 2024 16:44:27 +0000 Subject: Last of the content! --- .../lesson02_tail_calls/code.gleam | 21 ++++++++++++++++++++ .../lesson02_tail_calls/text.html | 23 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/content/chapter1_functions/lesson02_tail_calls/code.gleam create mode 100644 src/content/chapter1_functions/lesson02_tail_calls/text.html (limited to 'src/content/chapter1_functions/lesson02_tail_calls') diff --git a/src/content/chapter1_functions/lesson02_tail_calls/code.gleam b/src/content/chapter1_functions/lesson02_tail_calls/code.gleam new file mode 100644 index 0000000..d823eec --- /dev/null +++ b/src/content/chapter1_functions/lesson02_tail_calls/code.gleam @@ -0,0 +1,21 @@ +import gleam/io + +pub fn main() { + io.debug(factorial(5)) + io.debug(factorial(7)) +} + +pub fn factorial(x: Int) -> Int { + // The public function calls the private tail recursive function + factorial_loop(x, 1) +} + +fn factorial_loop(x: Int, accumulator: Int) -> Int { + case x { + 1 -> accumulator + + // The last thing this function does is call itself + // In the previous lesson the last thing it did was multiple two ints + _ -> factorial_loop(x - 1, accumulator * x) + } +} diff --git a/src/content/chapter1_functions/lesson02_tail_calls/text.html b/src/content/chapter1_functions/lesson02_tail_calls/text.html new file mode 100644 index 0000000..ec39cda --- /dev/null +++ b/src/content/chapter1_functions/lesson02_tail_calls/text.html @@ -0,0 +1,23 @@ +

+ When a function is called a new stack frame is created in memory to store the + arguments and local variables of the function. If lots of these frames are + created during recursion then the program would use a large amount of memory, + or even crash the program if some limit is hit. +

+

+ To avoid this problem Gleam supports tail call optimisation, which + allows the compiler to reuse the stack frame for the current function if a + function call is the last thing the function does, removing the memory cost. +

+ +

+ Unoptimised recursive functions can often be rewritten into tail call + optimised functions by using an accumulator. An accumulator is a variable that + is passed along in addition to the data, similar to a mutable variable in a + language with while loops. +

+

+ Accumulators should be hidden away from the users of your code, they are + internal implementation details. To do this write a public function that calls + a recursive private function with the initial accumulator value. +

-- cgit v1.2.3