Chapter 25: R Nested Functions
Part 1: What Are Nested Functions?
A nested function is simply a function defined inside another function. The inner function is only visible and accessible within the outer function, creating a private workspace that can’t be accessed from the outside.
The Basic Structure
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
outer_function <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Outer function code</span> inner_function <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Inner function code</span> return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Can call inner_function here</span> final_result <span class="token operator"><-</span> inner_function<span class="token punctuation">(</span>x<span class="token punctuation">)</span> return<span class="token punctuation">(</span>final_result<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
A Simple Example
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<span class="token comment"># A function that contains a nested helper function</span> calculate_power <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>base<span class="token punctuation">,</span> exponent<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Nested helper function</span> multiply_by_self <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>num<span class="token punctuation">,</span> times<span class="token punctuation">)</span> <span class="token punctuation">{</span> result <span class="token operator"><-</span> <span class="token number">1</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token keyword">in</span> <span class="token number">1</span><span class="token operator">:</span>times<span class="token punctuation">)</span> <span class="token punctuation">{</span> result <span class="token operator"><-</span> result <span class="token operator">*</span> num <span class="token punctuation">}</span> return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Use the nested function</span> answer <span class="token operator"><-</span> multiply_by_self<span class="token punctuation">(</span>base<span class="token punctuation">,</span> exponent<span class="token punctuation">)</span> return<span class="token punctuation">(</span>answer<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Call the outer function</span> print<span class="token punctuation">(</span>calculate_power<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 8</span> print<span class="token punctuation">(</span>calculate_power<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 625</span> <span class="token comment"># This would cause an error:</span> <span class="token comment"># print(multiply_by_self(2, 3)) # Error: object 'multiply_by_self' not found</span> |
Part 2: Why Use Nested Functions?
1. Encapsulation and Information Hiding
Nested functions keep helper functions private, preventing them from cluttering the global namespace:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<span class="token comment"># Without nesting - helper function is global</span> clean_data_global <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Global helper - accessible everywhere</span> return<span class="token punctuation">(</span>data<span class="token punctuation">[</span><span class="token operator">!</span>is.na<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> calculate_stats_global <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token punctuation">{</span> clean_data_global<span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token comment"># Can call the helper</span> <span class="token comment"># ... calculate stats</span> <span class="token punctuation">}</span> <span class="token comment"># With nesting - helper is private</span> calculate_stats_nested <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Private helper - only visible inside</span> clean_data_local <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>d<span class="token punctuation">[</span><span class="token operator">!</span>is.na<span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> cleaned <span class="token operator"><-</span> clean_data_local<span class="token punctuation">(</span>data<span class="token punctuation">)</span> mean_val <span class="token operator"><-</span> mean<span class="token punctuation">(</span>cleaned<span class="token punctuation">)</span> sd_val <span class="token operator"><-</span> sd<span class="token punctuation">(</span>cleaned<span class="token punctuation">)</span> return<span class="token punctuation">(</span>list<span class="token punctuation">(</span>mean <span class="token operator">=</span> mean_val<span class="token punctuation">,</span> sd <span class="token operator">=</span> sd_val<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># The helper function doesn't exist in the global environment</span> <span class="token comment"># clean_data_local(c(1,2,NA,4)) # Error!</span> |
2. Creating Function Factories
Nested functions can create and return other functions:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<span class="token comment"># Function factory - creates specialized functions</span> create_power_function <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>power<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Nested function to be returned</span> power_function <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>x<span class="token operator">^</span>power<span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>power_function<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Create specific power functions</span> square <span class="token operator"><-</span> create_power_function<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> cube <span class="token operator"><-</span> create_power_function<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> fourth_power <span class="token operator"><-</span> create_power_function<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span> <span class="token comment"># Use them</span> numbers <span class="token operator"><-</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">5</span> print<span class="token punctuation">(</span>square<span class="token punctuation">(</span>numbers<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 1 4 9 16 25</span> print<span class="token punctuation">(</span>cube<span class="token punctuation">(</span>numbers<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 1 8 27 64 125</span> print<span class="token punctuation">(</span>fourth_power<span class="token punctuation">(</span>numbers<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 1 16 81 256 625</span> |
3. Creating Closures – Functions That Remember
When a nested function references variables from the outer function, it creates a closure – the inner function “remembers” the environment where it was created:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<span class="token comment"># Create a counter factory</span> create_counter <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>start <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> count <span class="token operator"><-</span> start <span class="token comment"># Inner function that "closes over" count</span> counter <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> count <span class="token operator"><<-</span> count <span class="token operator">+</span> <span class="token number">1</span> <span class="token comment"># <<- modifies the count in the outer scope</span> return<span class="token punctuation">(</span>count<span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>counter<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Create counters</span> counter1 <span class="token operator"><-</span> create_counter<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span> counter2 <span class="token operator"><-</span> create_counter<span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span> <span class="token comment"># Each counter maintains its own state</span> print<span class="token punctuation">(</span>counter1<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 11</span> print<span class="token punctuation">(</span>counter1<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 12</span> print<span class="token punctuation">(</span>counter1<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 13</span> print<span class="token punctuation">(</span>counter2<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 101</span> print<span class="token punctuation">(</span>counter2<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 102</span> <span class="token comment"># The counters are independent</span> print<span class="token punctuation">(</span>counter1<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 14</span> |
4. Creating Specialized Functions with Preset Parameters
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<span class="token comment"># Create a greeting function factory</span> create_greeter <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>greeting <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> punctuation <span class="token operator">=</span> <span class="token string">"!"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Inner function that uses the preset values</span> greeter <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>paste0<span class="token punctuation">(</span>greeting<span class="token punctuation">,</span> <span class="token string">", "</span><span class="token punctuation">,</span> name<span class="token punctuation">,</span> punctuation<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>greeter<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Create different greeters</span> friendly_greet <span class="token operator"><-</span> create_greeter<span class="token punctuation">(</span><span class="token string">"Hi"</span><span class="token punctuation">,</span> <span class="token string">" :)"</span><span class="token punctuation">)</span> formal_greet <span class="token operator"><-</span> create_greeter<span class="token punctuation">(</span><span class="token string">"Good day"</span><span class="token punctuation">,</span> <span class="token string">"."</span><span class="token punctuation">)</span> excited_greet <span class="token operator"><-</span> create_greeter<span class="token punctuation">(</span><span class="token string">"HELLO"</span><span class="token punctuation">,</span> <span class="token string">"!!!"</span><span class="token punctuation">)</span> <span class="token comment"># Use them</span> print<span class="token punctuation">(</span>friendly_greet<span class="token punctuation">(</span><span class="token string">"Alice"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># "Hi, Alice :)"</span> print<span class="token punctuation">(</span>formal_greet<span class="token punctuation">(</span><span class="token string">"Mr. Smith"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># "Good day, Mr. Smith."</span> print<span class="token punctuation">(</span>excited_greet<span class="token punctuation">(</span><span class="token string">"WORLD"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># "HELLO, WORLD!!!"</span> |
Part 3: Variable Scope in Nested Functions
Understanding scope is crucial when working with nested functions.
Lexical Scoping
R uses lexical scoping, meaning that inner functions look for variables in the environment where they were defined, not where they’re called:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<span class="token comment"># Demonstrate lexical scoping</span> outer <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> y <span class="token operator"><-</span> <span class="token number">10</span> inner <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>z<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Can access x and y from outer function</span> return<span class="token punctuation">(</span>x <span class="token operator">+</span> y <span class="token operator">+</span> z<span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>inner<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span>outer<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 3 + 10 + 5 = 18</span> |
The Search Path
When looking for a variable, R searches:
-
The inner function’s local environment
-
The outer function’s environment
-
The global environment
-
Loaded packages
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
z <span class="token operator"><-</span> <span class="token number">100</span> <span class="token comment"># Global variable</span> test_scope <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> y <span class="token operator"><-</span> <span class="token number">50</span> <span class="token comment"># Outer variable</span> inner <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> x <span class="token operator"><-</span> <span class="token number">10</span> <span class="token comment"># Local variable</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"x (local):"</span><span class="token punctuation">,</span> x<span class="token punctuation">)</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"y (outer):"</span><span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"z (global):"</span><span class="token punctuation">,</span> z<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> inner<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> test_scope<span class="token punctuation">(</span><span class="token punctuation">)</span> |
Modifying Outer Variables with <<-
The super assignment operator <<- allows inner functions to modify variables in the outer function’s scope:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
create_accumulator <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> total <span class="token operator"><-</span> <span class="token number">0</span> accumulator <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> total <span class="token operator"><<-</span> total <span class="token operator">+</span> x <span class="token comment"># Modify the outer total</span> return<span class="token punctuation">(</span>total<span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>accumulator<span class="token punctuation">)</span> <span class="token punctuation">}</span> acc <span class="token operator"><-</span> create_accumulator<span class="token punctuation">(</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>acc<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 5</span> print<span class="token punctuation">(</span>acc<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 8</span> print<span class="token punctuation">(</span>acc<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 18</span> |
Part 4: Practical Examples
Example 1: Data Processing Pipeline
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
<span class="token comment"># Create a data processing function with nested helpers</span> process_sales_data <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span> remove_outliers <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">,</span> standardize <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Nested function 1: Clean data</span> clean_data <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>df<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Remove rows with missing values</span> df <span class="token operator"><-</span> df<span class="token punctuation">[</span>complete.cases<span class="token punctuation">(</span>df<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token comment"># Remove negative values (likely errors)</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>col <span class="token keyword">in</span> names<span class="token punctuation">(</span>df<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>is.numeric<span class="token punctuation">(</span>df<span class="token punctuation">[</span><span class="token punctuation">[</span>col<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> df <span class="token operator"><-</span> df<span class="token punctuation">[</span>df<span class="token punctuation">[</span><span class="token punctuation">[</span>col<span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>df<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Nested function 2: Remove outliers</span> remove_outliers_iqr <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>vec<span class="token punctuation">)</span> <span class="token punctuation">{</span> q1 <span class="token operator"><-</span> quantile<span class="token punctuation">(</span>vec<span class="token punctuation">,</span> <span class="token number">0.25</span><span class="token punctuation">)</span> q3 <span class="token operator"><-</span> quantile<span class="token punctuation">(</span>vec<span class="token punctuation">,</span> <span class="token number">0.75</span><span class="token punctuation">)</span> iqr <span class="token operator"><-</span> q3 <span class="token operator">-</span> q1 lower <span class="token operator"><-</span> q1 <span class="token operator">-</span> <span class="token number">1.5</span> <span class="token operator">*</span> iqr upper <span class="token operator"><-</span> q3 <span class="token operator">+</span> <span class="token number">1.5</span> <span class="token operator">*</span> iqr return<span class="token punctuation">(</span>vec<span class="token punctuation">[</span>vec <span class="token operator">>=</span> lower <span class="token operator">&</span> vec <span class="token operator"><=</span> upper<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Nested function 3: Standardize</span> standardize_values <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>vec<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span><span class="token punctuation">(</span>vec <span class="token operator">-</span> mean<span class="token punctuation">(</span>vec<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">/</span> sd<span class="token punctuation">(</span>vec<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Nested function 4: Calculate statistics</span> calculate_stats <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>vec<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>list<span class="token punctuation">(</span> mean <span class="token operator">=</span> mean<span class="token punctuation">(</span>vec<span class="token punctuation">)</span><span class="token punctuation">,</span> median <span class="token operator">=</span> median<span class="token punctuation">(</span>vec<span class="token punctuation">)</span><span class="token punctuation">,</span> sd <span class="token operator">=</span> sd<span class="token punctuation">(</span>vec<span class="token punctuation">)</span><span class="token punctuation">,</span> min <span class="token operator">=</span> min<span class="token punctuation">(</span>vec<span class="token punctuation">)</span><span class="token punctuation">,</span> max <span class="token operator">=</span> max<span class="token punctuation">(</span>vec<span class="token punctuation">)</span><span class="token punctuation">,</span> n <span class="token operator">=</span> length<span class="token punctuation">(</span>vec<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Main processing pipeline</span> cat<span class="token punctuation">(</span><span class="token string">"Step 1: Cleaning data...\n"</span><span class="token punctuation">)</span> data <span class="token operator"><-</span> clean_data<span class="token punctuation">(</span>data<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Rows after cleaning:"</span><span class="token punctuation">,</span> nrow<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> results <span class="token operator"><-</span> list<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>col <span class="token keyword">in</span> names<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>is.numeric<span class="token punctuation">(</span>data<span class="token punctuation">[</span><span class="token punctuation">[</span>col<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> cat<span class="token punctuation">(</span><span class="token string">"\nProcessing column:"</span><span class="token punctuation">,</span> col<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> <span class="token comment"># Extract column</span> values <span class="token operator"><-</span> data<span class="token punctuation">[</span><span class="token punctuation">[</span>col<span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token comment"># Step 2: Remove outliers if requested</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>remove_outliers<span class="token punctuation">)</span> <span class="token punctuation">{</span> orig_len <span class="token operator"><-</span> length<span class="token punctuation">(</span>values<span class="token punctuation">)</span> values <span class="token operator"><-</span> remove_outliers_iqr<span class="token punctuation">(</span>values<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">" Removed"</span><span class="token punctuation">,</span> orig_len <span class="token operator">-</span> length<span class="token punctuation">(</span>values<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"outliers\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Step 3: Standardize if requested</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>standardize<span class="token punctuation">)</span> <span class="token punctuation">{</span> values <span class="token operator"><-</span> standardize_values<span class="token punctuation">(</span>values<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">" Standardized values\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Step 4: Calculate statistics</span> stats <span class="token operator"><-</span> calculate_stats<span class="token punctuation">(</span>values<span class="token punctuation">)</span> results<span class="token punctuation">[</span><span class="token punctuation">[</span>col<span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator"><-</span> stats <span class="token punctuation">}</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>results<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Test the function</span> set.seed<span class="token punctuation">(</span><span class="token number">123</span><span class="token punctuation">)</span> test_data <span class="token operator"><-</span> data.frame<span class="token punctuation">(</span> sales <span class="token operator">=</span> c<span class="token punctuation">(</span>rnorm<span class="token punctuation">(</span><span class="token number">95</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">500</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment"># With outliers</span> customers <span class="token operator">=</span> c<span class="token punctuation">(</span>sample<span class="token punctuation">(</span><span class="token number">10</span><span class="token operator">:</span><span class="token number">50</span><span class="token punctuation">,</span> <span class="token number">98</span><span class="token punctuation">,</span> replace <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">NA</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">,</span> satisfaction <span class="token operator">=</span> runif<span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">,</span> stringsAsFactors <span class="token operator">=</span> <span class="token boolean">FALSE</span> <span class="token punctuation">)</span> results <span class="token operator"><-</span> process_sales_data<span class="token punctuation">(</span>test_data<span class="token punctuation">)</span> print<span class="token punctuation">(</span>results<span class="token punctuation">)</span> |
Example 2: Mathematical Function Analyzer
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
<span class="token comment"># Create a function that analyzes mathematical functions</span> create_function_analyzer <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>func<span class="token punctuation">,</span> domain <span class="token operator">=</span> c<span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Nested function 1: Evaluate at points</span> evaluate_at_points <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>n_points <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> x_vals <span class="token operator"><-</span> seq<span class="token punctuation">(</span>domain<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> domain<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> length.out <span class="token operator">=</span> n_points<span class="token punctuation">)</span> y_vals <span class="token operator"><-</span> sapply<span class="token punctuation">(</span>x_vals<span class="token punctuation">,</span> func<span class="token punctuation">)</span> return<span class="token punctuation">(</span>data.frame<span class="token punctuation">(</span>x <span class="token operator">=</span> x_vals<span class="token punctuation">,</span> y <span class="token operator">=</span> y_vals<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Nested function 2: Find roots</span> find_roots <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>tolerance <span class="token operator">=</span> <span class="token number">0.001</span><span class="token punctuation">,</span> max_iter <span class="token operator">=</span> <span class="token number">1000</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> x_vals <span class="token operator"><-</span> seq<span class="token punctuation">(</span>domain<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> domain<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> length.out <span class="token operator">=</span> <span class="token number">1000</span><span class="token punctuation">)</span> y_vals <span class="token operator"><-</span> sapply<span class="token punctuation">(</span>x_vals<span class="token punctuation">,</span> func<span class="token punctuation">)</span> roots <span class="token operator"><-</span> c<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token keyword">in</span> <span class="token number">1</span><span class="token operator">:</span><span class="token punctuation">(</span>length<span class="token punctuation">(</span>x_vals<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>y_vals<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">*</span> y_vals<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator"><=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Root in this interval - use bisection</span> a <span class="token operator"><-</span> x_vals<span class="token punctuation">[</span>i<span class="token punctuation">]</span> b <span class="token operator"><-</span> x_vals<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>iter <span class="token keyword">in</span> <span class="token number">1</span><span class="token operator">:</span>max_iter<span class="token punctuation">)</span> <span class="token punctuation">{</span> mid <span class="token operator"><-</span> <span class="token punctuation">(</span>a <span class="token operator">+</span> b<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span> f_mid <span class="token operator"><-</span> func<span class="token punctuation">(</span>mid<span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>abs<span class="token punctuation">(</span>f_mid<span class="token punctuation">)</span> <span class="token operator"><</span> tolerance<span class="token punctuation">)</span> <span class="token punctuation">{</span> roots <span class="token operator"><-</span> c<span class="token punctuation">(</span>roots<span class="token punctuation">,</span> mid<span class="token punctuation">)</span> <span class="token keyword">break</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>func<span class="token punctuation">(</span>a<span class="token punctuation">)</span> <span class="token operator">*</span> f_mid <span class="token operator"><=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> b <span class="token operator"><-</span> mid <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> a <span class="token operator"><-</span> mid <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>unique<span class="token punctuation">(</span>roots<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Nested function 3: Find extrema</span> find_extrema <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> df <span class="token operator"><-</span> evaluate_at_points<span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span> <span class="token comment"># Find where derivative changes sign (simplified)</span> dy <span class="token operator"><-</span> diff<span class="token punctuation">(</span>df<span class="token operator">$</span>y<span class="token punctuation">)</span> maxima <span class="token operator"><-</span> c<span class="token punctuation">(</span><span class="token punctuation">)</span> minima <span class="token operator"><-</span> c<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token keyword">in</span> <span class="token number">2</span><span class="token operator">:</span><span class="token punctuation">(</span>length<span class="token punctuation">(</span>dy<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>dy<span class="token punctuation">[</span>i<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">></span> <span class="token number">0</span> <span class="token operator">&&</span> dy<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> maxima <span class="token operator"><-</span> c<span class="token punctuation">(</span>maxima<span class="token punctuation">,</span> df<span class="token operator">$</span>x<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>dy<span class="token punctuation">[</span>i<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator"><</span> <span class="token number">0</span> <span class="token operator">&&</span> dy<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> minima <span class="token operator"><-</span> c<span class="token punctuation">(</span>minima<span class="token punctuation">,</span> df<span class="token operator">$</span>x<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>list<span class="token punctuation">(</span>maxima <span class="token operator">=</span> maxima<span class="token punctuation">,</span> minima <span class="token operator">=</span> minima<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Nested function 4: Calculate integral</span> calculate_integral <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>n_intervals <span class="token operator">=</span> <span class="token number">1000</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> x_vals <span class="token operator"><-</span> seq<span class="token punctuation">(</span>domain<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> domain<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> length.out <span class="token operator">=</span> n_intervals <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> y_vals <span class="token operator"><-</span> sapply<span class="token punctuation">(</span>x_vals<span class="token punctuation">,</span> func<span class="token punctuation">)</span> <span class="token comment"># Trapezoidal rule</span> integral <span class="token operator"><-</span> sum<span class="token punctuation">(</span><span class="token punctuation">(</span>y_vals<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">+</span> y_vals<span class="token punctuation">[</span><span class="token operator">-</span>length<span class="token punctuation">(</span>y_vals<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token punctuation">(</span>x_vals<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">-</span> x_vals<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>integral<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Return a list of all analyzer functions</span> return<span class="token punctuation">(</span>list<span class="token punctuation">(</span> evaluate <span class="token operator">=</span> evaluate_at_points<span class="token punctuation">,</span> roots <span class="token operator">=</span> find_roots<span class="token punctuation">,</span> extrema <span class="token operator">=</span> find_extrema<span class="token punctuation">,</span> integral <span class="token operator">=</span> calculate_integral<span class="token punctuation">,</span> domain <span class="token operator">=</span> domain<span class="token punctuation">,</span> func <span class="token operator">=</span> func <span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Create an analyzer for a specific function</span> f <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> x<span class="token operator">^</span><span class="token number">3</span> <span class="token operator">-</span> <span class="token number">6</span><span class="token operator">*</span>x<span class="token operator">^</span><span class="token number">2</span> <span class="token operator">+</span> <span class="token number">11</span><span class="token operator">*</span>x <span class="token operator">-</span> <span class="token number">6</span> <span class="token comment"># Roots at 1, 2, 3</span> analyzer <span class="token operator"><-</span> create_function_analyzer<span class="token punctuation">(</span>f<span class="token punctuation">,</span> domain <span class="token operator">=</span> c<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Use the analyzer</span> roots <span class="token operator"><-</span> analyzer<span class="token operator">$</span>roots<span class="token punctuation">(</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Roots found:"</span><span class="token punctuation">,</span> paste<span class="token punctuation">(</span>round<span class="token punctuation">(</span>roots<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> collapse <span class="token operator">=</span> <span class="token string">", "</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> extrema <span class="token operator"><-</span> analyzer<span class="token operator">$</span>extrema<span class="token punctuation">(</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Maxima at:"</span><span class="token punctuation">,</span> paste<span class="token punctuation">(</span>round<span class="token punctuation">(</span>extrema<span class="token operator">$</span>maxima<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> collapse <span class="token operator">=</span> <span class="token string">", "</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Minima at:"</span><span class="token punctuation">,</span> paste<span class="token punctuation">(</span>round<span class="token punctuation">(</span>extrema<span class="token operator">$</span>minima<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> collapse <span class="token operator">=</span> <span class="token string">", "</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> integral <span class="token operator"><-</span> analyzer<span class="token operator">$</span>integral<span class="token punctuation">(</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Definite integral from 0 to 4:"</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>integral<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Evaluate at specific points</span> points <span class="token operator"><-</span> analyzer<span class="token operator">$</span>evaluate<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>head<span class="token punctuation">(</span>points<span class="token punctuation">)</span><span class="token punctuation">)</span> |
Example 3: Cache System with Nested Functions
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
<span class="token comment"># Create a caching system for expensive computations</span> create_cache <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Private cache storage</span> cache <span class="token operator"><-</span> list<span class="token punctuation">(</span><span class="token punctuation">)</span> hits <span class="token operator"><-</span> <span class="token number">0</span> misses <span class="token operator"><-</span> <span class="token number">0</span> <span class="token comment"># Nested function 1: Generate cache key</span> make_key <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>paste<span class="token punctuation">(</span>deparse<span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">,</span> collapse <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Nested function 2: Check if result is cached</span> is_cached <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>key <span class="token percent-operator operator">%in%</span> names<span class="token punctuation">(</span>cache<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Nested function 3: Get from cache</span> get_from_cache <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>is_cached<span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> hits <span class="token operator"><<-</span> hits <span class="token operator">+</span> <span class="token number">1</span> return<span class="token punctuation">(</span>cache<span class="token punctuation">[</span><span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> misses <span class="token operator"><<-</span> misses <span class="token operator">+</span> <span class="token number">1</span> return<span class="token punctuation">(</span><span class="token keyword">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment"># Nested function 4: Add to cache</span> add_to_cache <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> value<span class="token punctuation">)</span> <span class="token punctuation">{</span> cache<span class="token punctuation">[</span><span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator"><<-</span> value return<span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Nested function 5: Compute with caching</span> compute <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>func<span class="token punctuation">,</span> <span class="token ellipsis">...</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> args <span class="token operator"><-</span> list<span class="token punctuation">(</span><span class="token ellipsis">...</span><span class="token punctuation">)</span> key <span class="token operator"><-</span> make_key<span class="token punctuation">(</span>args<span class="token punctuation">)</span> cached_result <span class="token operator"><-</span> get_from_cache<span class="token punctuation">(</span>key<span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>is.null<span class="token punctuation">(</span>cached_result<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> cat<span class="token punctuation">(</span><span class="token string">"Cache hit for key:"</span><span class="token punctuation">,</span> key<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>cached_result<span class="token punctuation">)</span> <span class="token punctuation">}</span> cat<span class="token punctuation">(</span><span class="token string">"Cache miss - computing for:"</span><span class="token punctuation">,</span> key<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> result <span class="token operator"><-</span> func<span class="token punctuation">(</span><span class="token ellipsis">...</span><span class="token punctuation">)</span> add_to_cache<span class="token punctuation">(</span>key<span class="token punctuation">,</span> result<span class="token punctuation">)</span> return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Nested function 6: Get statistics</span> get_stats <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>list<span class="token punctuation">(</span> cache_size <span class="token operator">=</span> length<span class="token punctuation">(</span>cache<span class="token punctuation">)</span><span class="token punctuation">,</span> hits <span class="token operator">=</span> hits<span class="token punctuation">,</span> misses <span class="token operator">=</span> misses<span class="token punctuation">,</span> hit_rate <span class="token operator">=</span> hits <span class="token operator">/</span> <span class="token punctuation">(</span>hits <span class="token operator">+</span> misses<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Nested function 7: Clear cache</span> clear_cache <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> cache <span class="token operator"><<-</span> list<span class="token punctuation">(</span><span class="token punctuation">)</span> hits <span class="token operator"><<-</span> <span class="token number">0</span> misses <span class="token operator"><<-</span> <span class="token number">0</span> cat<span class="token punctuation">(</span><span class="token string">"Cache cleared\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Return public interface</span> return<span class="token punctuation">(</span>list<span class="token punctuation">(</span> compute <span class="token operator">=</span> compute<span class="token punctuation">,</span> stats <span class="token operator">=</span> get_stats<span class="token punctuation">,</span> clear <span class="token operator">=</span> clear_cache <span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Expensive computation function</span> expensive_calculation <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>n<span class="token punctuation">,</span> multiplier <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> Sys.sleep<span class="token punctuation">(</span><span class="token number">0.5</span><span class="token punctuation">)</span> <span class="token comment"># Simulate heavy computation</span> result <span class="token operator"><-</span> sum<span class="token punctuation">(</span>sapply<span class="token punctuation">(</span><span class="token number">1</span><span class="token operator">:</span>n<span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> x<span class="token operator">^</span>multiplier<span class="token punctuation">)</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Create cache</span> cache <span class="token operator"><-</span> create_cache<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># Use cached computations</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token keyword">in</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> cat<span class="token punctuation">(</span><span class="token string">"\nIteration"</span><span class="token punctuation">,</span> i<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> result1 <span class="token operator"><-</span> cache<span class="token operator">$</span>compute<span class="token punctuation">(</span>expensive_calculation<span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">,</span> multiplier <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">)</span> result2 <span class="token operator"><-</span> cache<span class="token operator">$</span>compute<span class="token punctuation">(</span>expensive_calculation<span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">,</span> multiplier <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">)</span> result3 <span class="token operator"><-</span> cache<span class="token operator">$</span>compute<span class="token punctuation">(</span>expensive_calculation<span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">,</span> multiplier <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment"># Should be cached</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span>cache<span class="token operator">$</span>stats<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> |
Part 5: Advanced Patterns
Pattern 1: Currying with Nested Functions
Currying transforms a function that takes multiple arguments into a chain of functions, each taking a single argument:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<span class="token comment"># Traditional function</span> add_three_numbers <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> c<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>a <span class="token operator">+</span> b <span class="token operator">+</span> c<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Curried version</span> curried_add <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>a <span class="token operator">+</span> b <span class="token operator">+</span> c<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Use curried function</span> result <span class="token operator"><-</span> curried_add<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token comment"># 18</span> <span class="token comment"># Create specialized functions</span> add5 <span class="token operator"><-</span> curried_add<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> add5and10 <span class="token operator"><-</span> add5<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>add5and10<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 18</span> print<span class="token punctuation">(</span>add5and10<span class="token punctuation">(</span><span class="token number">7</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 22</span> |
Pattern 2: Memoization with Nested Functions
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<span class="token comment"># Create a memoized version of any function</span> memoize <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span> <span class="token punctuation">{</span> cache <span class="token operator"><-</span> list<span class="token punctuation">(</span><span class="token punctuation">)</span> memoized <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token ellipsis">...</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Create a key from arguments</span> key <span class="token operator"><-</span> paste<span class="token punctuation">(</span>list<span class="token punctuation">(</span><span class="token ellipsis">...</span><span class="token punctuation">)</span><span class="token punctuation">,</span> collapse <span class="token operator">=</span> <span class="token string">"_"</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>key <span class="token percent-operator operator">%in%</span> names<span class="token punctuation">(</span>cache<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> cat<span class="token punctuation">(</span><span class="token string">"Returning cached result for:"</span><span class="token punctuation">,</span> key<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>cache<span class="token punctuation">[</span><span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> cat<span class="token punctuation">(</span><span class="token string">"Computing new result for:"</span><span class="token punctuation">,</span> key<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> result <span class="token operator"><-</span> f<span class="token punctuation">(</span><span class="token ellipsis">...</span><span class="token punctuation">)</span> cache<span class="token punctuation">[</span><span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator"><<-</span> result return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>memoized<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Expensive Fibonacci (inefficient version)</span> fib_slow <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator"><=</span> <span class="token number">1</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>n<span class="token punctuation">)</span> return<span class="token punctuation">(</span>fib_slow<span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span> fib_slow<span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Create memoized version</span> fib_fast <span class="token operator"><-</span> memoize<span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator"><=</span> <span class="token number">1</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>n<span class="token punctuation">)</span> return<span class="token punctuation">(</span>fib_fast<span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span> fib_fast<span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment"># Compare performance</span> system.time<span class="token punctuation">(</span>print<span class="token punctuation">(</span>fib_slow<span class="token punctuation">(</span><span class="token number">35</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Slow</span> system.time<span class="token punctuation">(</span>print<span class="token punctuation">(</span>fib_fast<span class="token punctuation">(</span><span class="token number">35</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Fast (after first computation)</span> |
Pattern 3: Decorator Pattern
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
<span class="token comment"># Create function decorators</span> add_logging <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span> <span class="token punctuation">{</span> logged_function <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token ellipsis">...</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> cat<span class="token punctuation">(</span><span class="token string">"Calling function at"</span><span class="token punctuation">,</span> Sys.time<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> result <span class="token operator"><-</span> f<span class="token punctuation">(</span><span class="token ellipsis">...</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Function returned:"</span><span class="token punctuation">,</span> result<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>logged_function<span class="token punctuation">)</span> <span class="token punctuation">}</span> add_timing <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span> <span class="token punctuation">{</span> timed_function <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token ellipsis">...</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> start <span class="token operator"><-</span> Sys.time<span class="token punctuation">(</span><span class="token punctuation">)</span> result <span class="token operator"><-</span> f<span class="token punctuation">(</span><span class="token ellipsis">...</span><span class="token punctuation">)</span> end <span class="token operator"><-</span> Sys.time<span class="token punctuation">(</span><span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Execution time:"</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>end <span class="token operator">-</span> start<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"seconds\n"</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>timed_function<span class="token punctuation">)</span> <span class="token punctuation">}</span> add_validation <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>f<span class="token punctuation">,</span> min_val <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">Inf</span><span class="token punctuation">,</span> max_val <span class="token operator">=</span> <span class="token number">Inf</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> validated_function <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator"><</span> min_val <span class="token operator">||</span> x <span class="token operator">></span> max_val<span class="token punctuation">)</span> <span class="token punctuation">{</span> stop<span class="token punctuation">(</span><span class="token string">"Input out of valid range"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>f<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>validated_function<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Create a simple function</span> square <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> x<span class="token operator">^</span><span class="token number">2</span> <span class="token comment"># Decorate it</span> square_with_logging <span class="token operator"><-</span> add_logging<span class="token punctuation">(</span>square<span class="token punctuation">)</span> square_with_timing <span class="token operator"><-</span> add_timing<span class="token punctuation">(</span>square<span class="token punctuation">)</span> square_validated <span class="token operator"><-</span> add_validation<span class="token punctuation">(</span>square<span class="token punctuation">,</span> min_val <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> max_val <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">)</span> <span class="token comment"># Combine decorators</span> square_fully_loaded <span class="token operator"><-</span> add_logging<span class="token punctuation">(</span>add_timing<span class="token punctuation">(</span>add_validation<span class="token punctuation">(</span>square<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Test</span> square_with_logging<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> square_with_timing<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token comment"># square_validated(-5) # Error!</span> square_fully_loaded<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> |
Part 6: Common Pitfalls and Solutions
Pitfall 1: Forgetting the Return Value
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<span class="token comment"># ❌ Inner function doesn't return anything</span> outer_bad <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> inner <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span> <span class="token punctuation">{</span> z <span class="token operator"><-</span> y <span class="token operator">*</span> <span class="token number">2</span> <span class="token comment"># No return!</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>inner<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span>outer_bad<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># NULL</span> <span class="token comment"># ✅ Always return from inner functions</span> outer_good <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> inner <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span> <span class="token punctuation">{</span> z <span class="token operator"><-</span> y <span class="token operator">*</span> <span class="token number">2</span> return<span class="token punctuation">(</span>z<span class="token punctuation">)</span> <span class="token comment"># Explicit return</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>inner<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span>outer_good<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 10</span> |
Pitfall 2: Confusing = and <- in Function Calls
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<span class="token comment"># ❌ Using assignment inside function call</span> outer <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> inner <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span> z <span class="token operator"><-</span> y <span class="token operator">*</span> <span class="token number">2</span> <span class="token comment"># This creates z but doesn't return it!</span> return<span class="token punctuation">(</span>inner<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># ✅ Use explicit return or ensure last expression is the result</span> outer <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> inner <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>y <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>inner<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Pitfall 3: Modifying Outer Variables Without <<-
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<span class="token comment"># ❌ This doesn't modify the outer counter</span> create_counter_bad <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> count <span class="token operator"><-</span> <span class="token number">0</span> increment <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> count <span class="token operator"><-</span> count <span class="token operator">+</span> <span class="token number">1</span> <span class="token comment"># Creates local count, doesn't modify outer</span> return<span class="token punctuation">(</span>count<span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>increment<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># ✅ Use <<- to modify outer variable</span> create_counter_good <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> count <span class="token operator"><-</span> <span class="token number">0</span> increment <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> count <span class="token operator"><<-</span> count <span class="token operator">+</span> <span class="token number">1</span> <span class="token comment"># Modifies outer count</span> return<span class="token punctuation">(</span>count<span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>increment<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Pitfall 4: Creating Functions in Loops
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<span class="token comment"># ❌ All functions will use the last value of i</span> funcs <span class="token operator"><-</span> list<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token keyword">in</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> funcs<span class="token punctuation">[</span><span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> i <span class="token punctuation">}</span> print<span class="token punctuation">(</span>funcs<span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 3, not 1!</span> <span class="token comment"># ✅ Force evaluation with local scope</span> funcs <span class="token operator"><-</span> list<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token keyword">in</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> funcs<span class="token punctuation">[</span><span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator"><-</span> local<span class="token punctuation">(</span><span class="token punctuation">{</span> j <span class="token operator"><-</span> i <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> j <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span>funcs<span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 1</span> |
Part 7: Debugging Nested Functions
Using browser() in Nested Functions
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
complex_nested <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> step1 <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span> <span class="token punctuation">{</span> step2 <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span> <span class="token punctuation">{</span> step3 <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Insert breakpoint</span> browser<span class="token punctuation">(</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>c <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>step3<span class="token punctuation">(</span>b <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>step2<span class="token punctuation">(</span>a <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> result <span class="token operator"><-</span> step1<span class="token punctuation">(</span>x<span class="token punctuation">)</span> return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Uncomment to debug</span> <span class="token comment"># result <- complex_nested(5)</span> |
Printing Trace Information
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
nested_with_trace <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> verbose <span class="token operator">=</span> <span class="token boolean">FALSE</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> inner1 <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>verbose<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Inner1 received:"</span><span class="token punctuation">,</span> a<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> b <span class="token operator"><-</span> a <span class="token operator">*</span> <span class="token number">2</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>verbose<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Inner1 returning:"</span><span class="token punctuation">,</span> b<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>b<span class="token punctuation">)</span> <span class="token punctuation">}</span> inner2 <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>verbose<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Inner2 received:"</span><span class="token punctuation">,</span> b<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> c <span class="token operator"><-</span> b <span class="token operator">+</span> <span class="token number">10</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>verbose<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Inner2 returning:"</span><span class="token punctuation">,</span> c<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>c<span class="token punctuation">)</span> <span class="token punctuation">}</span> inner3 <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>verbose<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Inner3 received:"</span><span class="token punctuation">,</span> c<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> result <span class="token operator"><-</span> c <span class="token operator">/</span> <span class="token number">2</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>verbose<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Inner3 returning:"</span><span class="token punctuation">,</span> result<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>verbose<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Starting with x ="</span><span class="token punctuation">,</span> x<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> a <span class="token operator"><-</span> inner1<span class="token punctuation">(</span>x<span class="token punctuation">)</span> b <span class="token operator"><-</span> inner2<span class="token punctuation">(</span>a<span class="token punctuation">)</span> c <span class="token operator"><-</span> inner3<span class="token punctuation">(</span>b<span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>verbose<span class="token punctuation">)</span> cat<span class="token punctuation">(</span><span class="token string">"Final result:"</span><span class="token punctuation">,</span> c<span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>c<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Run with tracing</span> nested_with_trace<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span> verbose <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">)</span> |
Summary: The Nested Function Philosophy
Nested functions are your tool for creating private helpers, building closures, and generating specialized functions. Master these patterns:
-
Encapsulation – Hide helper functions from global scope
-
Closures – Functions that remember their creation environment
-
Function factories – Functions that create other functions
-
Caching/memoization – Store results for repeated calls
-
Decorators – Add functionality to existing functions
Key concepts:
-
Inner functions have access to outer function’s variables
-
Use
<<-to modify outer variables -
Lexical scoping means functions look where they’re defined, not called
-
Closures preserve the environment where they were created
-
Nested functions are private by default
Best practices:
-
Keep nesting depth reasonable (2-3 levels max)
-
Document what each nested function does
-
Use meaningful names for nested functions
-
Consider whether a nested function should really be separate
-
Be careful with variable modification in nested scopes
When to use nested functions:
-
Creating private helper functions
-
Building function factories
-
Implementing caching/memoization
-
Creating decorators
-
When you need to capture the current environment
Nested functions transform you from a linear programmer into someone who can create sophisticated, self-contained functional units. They’re the difference between writing simple scripts and building complex, maintainable systems.
Would you like me to elaborate on any specific aspect of nested functions or explore more advanced patterns?
