Setting variable used by multiple functions in a module

I’m trying to find the Julian way to replace the following OOP functionality: if a variable is set when an object is instantiated, then all functions in that instance have access to the variable.

It seems like closures are the correct “Julian” way to reproduce this. Is there a way to mimic instantiation and set a variable once, or should I expect to call set_a each time I use module functions which access that variable?

module foo
export set_a

function set_a(a)
    f1(x) = a + x
    f2(x) = a * x
    return f1,f2
end

function bar(x)
    f1,f2 = set_a(42)
    return f1(x) + f2(x)
end

end

Thanks! I hope this isn’t duplicating another existing question.

I am not sure I fully understand what you are trying to do. If you just need a callable that has state, perhaps just make a mutable struct callable:

mutable struct HasState{T}
    a::T
end

(A::HasState)(x) = A.a + x

etc.

Sorry for the confusing wording (and delayed response).

I am trying to pass arguments by closure to multiple functions (the “in a module” part of the question was unnecessary). I am doing so by manually adding functions to the closure and return list, e.g.,

function close_args(A)
    foo1(x) = A*x
    foo2(x) = x+A*x
    foo3(x) = 2*x+A*x
    return foo1,foo2,foo3
end

foo1,foo2,foo3 = close_args(A)

This seems a little cumbersome if I keep adding new functions. Is there a way to avoid this (for example, by passing a function into close_args instead of defining it inside)?

I am still not sure what you are trying to do, but

let A = B
    x -> A*x,  x -> x+A*x, x -> 2*x+A*x
end

would be equivalent to close_args(B).

Thanks for the reply!

How do you extract functions from the let block? That seems pretty close to what I’d like to do - in pseudocode, something like

# define variables
A = rand(10,10)

# define a bunch of functions which inherit A thru closure
let A=A
     foo1(x) = A*x
     foo2(x) = ...
     foo3(x) = ...
     #...etc,etc
end

# call those functions outside the let block
b = foo1(rand(10))

They are just the value of the let block, eg

foo1, foo2, foo3 = let ... end

That said, I would really recommend defining a (mutable) struct and make it callable. Your future self working with this code will thank you.

1 Like

Thanks. I’ll try rewriting things around a callable state.

FWIW, I was originally trying to use closures to pass variables, so that I could avoid long lists of input arguments. The let blocks and function closures work for this, I just wanted to see if I could avoid having to explicitly listing all the closed functions as output values.