1

I want to generate an array of functions programmatically, with a loop so that each successive function depends on the previous.

For example in pseudo-code:

f_array = [f1, f2, f3]
with:
f1(x) = x
f2(x) = 3 * f1(x)
f3(x) = 3 * f2(x)

so that I could call:
f_array[3](x)
and get the result of f3(x)

Here is what I have tried:

  # create simple function just to initialize
  f(x)=x
  
  # initialize array of functions
  N = 3
  f_array = fill(f, N)
  
  # now we update each function
  for i in 2:N
    f_array[i] = (f(x)= 3 * f_array[i-1](x))
  end

I get an error:

ERROR: MethodError: Cannot convert an object of type getfield(Main, Symbol("#f#15")){Int64} to an object of type typeof(f)

I cannot find a solution at the moment. Any help would be appreciated.

3 Answers 3

2

When you use fill with f it sets expected type for the elements of f_array to f, in the code below I am switching to abstract type to make it possible to have any function in the array

  # create simple function just to initialize
  f(x)=x
  
  # initialize array of functions
  N = 3
  f_array = Array{Function}(undef, N);
  f_array[1] = f;

  # now we update each function
  for i in 2:N
    f_array[i] = x -> 3 * f_array[i-1](x)
  end

  print(f_array[3](2))

which produces a value of 18

Sign up to request clarification or add additional context in comments.

Comments

1

In the mean time, I also found a way using metaprogramming. I post this here as it could be useful for others:

f1(x) = x

for i in 2:N
  prog = "f$i(x) = 3 * f$(i-1)(x)"
  exp = Meta.parse(prog)
  eval(exp)
end

f3(2)
# 18

1 Comment

Don't use a string and parse use :(f$i(x)... quote.
1

I'd write Yegor's answer as

f_array = Function[identity]
for i in 2:3
     push!(f_array, x -> 3f_array[i-1](x))
end

But more importantly, this is a well known pattern: iterated function application. And it is already implemented, not in Base, but for example in IterTools.jl, by which you should be able to write:

f_array(start, N) = collect(Iterators.take(iterated(x -> 3x, start), N))

(I didn't test this, though.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.