Task

Create a list of ten functions, in the simplest manner possible   (anonymous functions are encouraged),   such that the function at index    i     (you may choose to start     i     from either    0    or    1),    when run, should return the square of the index,   that is,     i  2.

Display the result of running any but the last function, to demonstrate that the function indeed remembers its value.



Goal

Demonstrate how to create a series of independent closures based on the same template but maintain separate copies of the variable closed over.

In imperative languages, one would generally use a loop with a mutable counter variable.

For each function to maintain the correct number, it has to capture the value of the variable at the time it was created, rather than just a reference to the variable, which would have a different value by the time the function was run.

See also: Multiple distinct objects

with javascript_semantics
-- First some generic handling stuff, handles partial_args
-- of any mixture of any length and element types.
sequence closures = {}
function add_closure(integer rid, sequence partial_args)
    closures = append(closures,{rid,partial_args})
    return length(closures) -- (return an integer id)
end function
 
function call_closure(integer id, sequence args)
    {integer rid, sequence partial_args} = closures[id]
    return call_func(rid,partial_args&args)
end function
 
-- The test routine to be made into a closure, or ten
-- Note that all external references/captured variables must
-- be passed as arguments, and grouped together on the lhs
function square(integer i)
    return i*i
end function
 
-- Create the ten closures as asked for.
-- Here, cids is just {1,2,3,4,5,6,7,8,9,10}, however ids would be more
-- useful for a mixed bag of closures, possibly stored all over the shop.
-- Likewise add_closure could have been a procedure for this demo, but
-- you would probably want the function in a real-world application.
sequence cids = {}
for i=1 to 10 do
--for i=11 to 20 do -- alternative test
    cids &= add_closure(routine_id("square"),{i})
end for
-- And finally call em (this loop is blissfully unaware what function 
-- it is actually calling, and what partial_arguments it is passing)
for i=1 to 10 do
    printf(1," %d",call_closure(cids[i],{}))
end for
