Razen Documentation

Learn how to use the Razen Programming Language.

Advanced Functions

# Advanced Functions This guide covers advanced function concepts in Razen, including higher-order functions, closures, and function composition. ## Higher-Order Functions In Razen, functions are first-class citizens, which means they can be: - Assigned to variables - Passed as arguments to other functions - Returned from other functions ### Functions as Arguments You can pass functions as arguments to other functions: ```razen // Define a function that takes another function as an argument function applyTwice(func, value) { return func(func(value)) } // Define a simple function to double a number function double(x) { return x * 2 } // Use applyTwice with the double function let result = applyTwice(double, 3) // 12 (double applied twice: 3 → 6 → 12) print(result) ``` ### Returning Functions Functions can also return other functions: ```razen // Define a function that returns a function function createMultiplier(factor) { // Return a function that multiplies its argument by factor return function(x) { return x * factor } } // Create a function that multiplies by 5 let multiplyByFive = createMultiplier(5) // Use the created function print(multiplyByFive(3)) // 15 print(multiplyByFive(10)) // 50 ``` ## Closures A closure is a function that remembers the environment in which it was created, including any local variables that were in scope at the time: ```razen function createCounter() { let count = 0 return function() { count += 1 return count } } let counter = createCounter() print(counter()) // 1 print(counter()) // 2 print(counter()) // 3 // Create a new counter let counter2 = createCounter() print(counter2()) // 1 (independent of the first counter) ``` In this example, each counter function maintains its own `count` variable, even though the `createCounter` function has finished executing. ## Function Composition Function composition is the process of combining two or more functions to create a new function: ```razen // Define two simple functions function addOne(x) { return x + 1 } function double(x) { return x * 2 } // Compose these functions function compose(f, g) { return function(x) { return f(g(x)) } } // Create a new function that doubles and then adds one let doubleAndAddOne = compose(addOne, double) print(doubleAndAddOne(3)) // 7 (double 3 to get 6, then add 1) // Create a new function that adds one and then doubles let addOneAndDouble = compose(double, addOne) print(addOneAndDouble(3)) // 8 (add 1 to 3 to get 4, then double) ``` ## Recursive Functions Recursive functions are functions that call themselves: ```razen // Calculate factorial using recursion function factorial(n) { if (n <= 1) { return 1 } else { return n * factorial(n - 1) } } print(factorial(5)) // 120 (5 * 4 * 3 * 2 * 1) ``` ## Function Currying Currying is the technique of converting a function that takes multiple arguments into a sequence of functions that each take a single argument: ```razen // A function that takes three arguments function add(a, b, c) { return a + b + c } // A curried version of the add function function curriedAdd(a) { return function(b) { return function(c) { return a + b + c } } } // Using the curried function let result1 = curriedAdd(1)(2)(3) // 6 print(result1) // Partial application let addOne = curriedAdd(1) let addOneAndTwo = addOne(2) let result2 = addOneAndTwo(3) // 6 print(result2) ``` ## Anonymous Functions (Lambdas) Razen supports anonymous functions, also known as lambda functions: ```razen // Using an anonymous function with map let numbers = [1, 2, 3, 4, 5] let doubled = map(numbers, function(x) { return x * 2 }) print(doubled) // [2, 4, 6, 8, 10] // Shorter syntax for anonymous functions let squared = map(numbers, x => x * x) print(squared) // [1, 4, 9, 16, 25] ``` ## Next Steps Now that you've mastered advanced function concepts in Razen, explore [Object-Oriented Programming](/docs/advanced-topics/object-oriented.mdx) to learn about classes and objects in Razen.