I have a function which is straightforward to implement in both the ado scripting language and mata. Let's call it func.

Currently, I have written func.ado which allows for the function to be used across my various .do and .ado files.

A problem has arisen. In another file (func2.ado), I have a bit of code where I define a mata associative array, then have a for loop, then change the associative array using results from the loop. In the loop, I would need to use the func.

It looks something like

mata
//1 define associative array
//2 loop
//3 use matrix info from loop to change associative array
end

As such, I have a mata loop which needs to use func. I am not sure how it would be best to resolve this. Here are my considered approaches:

1) Define func once more using mata. If I do this, is there a way I could do it once, and then use that definition across various files? Duplicating code is very bad practice, yet I am not sure if it is possible to avoid this problem for pure mata functions.
2) Call the ado version of func in the mata loop. I know it is possible to call mata while in the ado scripting language by coding "mata: XYZ" — is it possible to do something like the opposite?
3) Split up 1,2,3 as such:
mata
//1 define associative array
end
//2 loop
mata
//3 change associative array
end
by "sending" the associative array to STATA and then reimporting it in the second mata block. The analogy for matrices would be defining matrix m and invoking st_matrix("a",m) in the first block and then invoking m = st_matrix("m") in the second mata block. Is there a way to do this for associative arrays?

In the worst case, I can define func in mata in func2.ado and possibly again in other funcx.ado files if needed (duplicating code). However, if there is a way to resolve this issue more cleanly (via 1,2,3 or another method), I would be very grateful to implement this method.