# Handling of package inter-dependency

**URL:** <https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568>\
**Category:** New to Julia\
**Tags:** package, argument\
**Created:** [July 13, 2021, 1:12pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568 "2021-07-13T13:12:55Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [July 13, 2021, 1:12pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/1 "2021-07-13T13:12:56Z")

</div>

# Introduction

Hello. I am currently developing a software involving

1. A GUI in C# / [vb.net](http://vb.net)
2. A computation kernel in julia

To handle to communication business I am using [Json.net](http://Json.net) for the C# part and the BSON package in julia. The communication itself is performed over named Pipes as everything runs on the same local machine.

In my julia program, I have developed

- a _scientific_ package (let’s call it `SCI`) that handles the whole computation–heavy stuff, that can also be run autonomously
- a _server_ package (`COM`) that handles all the communication stuff including (de-)serialization, argument checking and so on. Once started, this server waits for instruction over the pipe, and calls some kind of `compute` command, or assigns values to variables when required.

Each upper-level function of `SCI` takes one or multiple arguments and returns only one.  
Each of these functions has a specific return argument type (which is hence only used once).

Currently the process is the following:

1. A message is received
2. This message is converted to a `struct` based on types defined in `SCI` or an `Instruction` type defined in `COM`.
3. Two cases :
  - If the object retrieved is a `SCI`-defined `struct` :
    - It is checked against a list of authorized types defined in `COM` based on knowledge of `SCI`
    - it is stored in the field of a `mutable struct` (`Container`) that is currently defined in `COM`

  - If the object is an instruction :
    - It is checked against a list of authorized instructions known from `SCI`
    - It is passed as an argument to a `compute` function that call function from `SCI` and store the result in `Container`
    - Special cases :
      - The instruction is `exit`, the server stops
      - The instruction is `return_X`, the server returns the value of variable `X`

The authorized types and authorized instructions are obtained from SCI thanks to the following bit of code in `COM`

```julia-auto
using SCI
const auth_funs = filter(n -> eval(getfield(SCI, n)) isa Function, names(SCI))
const auth_types = filter(n -> getfield(SCI, n) isa Type, names(SCI))

```

The container type itself is defined manually.

# My real question starts here

Obviously, if I were to only use these two packages, this state of development would be totally enough.  
However, the `COM` package feels too much tied to the `SCI` package.  
What if I wanted to use the same server, with another `SCI2` package ?

What `COM` really requires is

- To be able to load some package
- To detect some properties of this package
- To ensure that this package defines a `compute` function taking the appropriate arguments, and potentially a `Container` type

A very naive idea would then be to call something like `using COM(SCI)`, however this is not possible.

So my question (finally) is : How to handle such dependency of one package versus another, dependency that is known at compile time (I believe,correct me if I’m wrong), but that would depend on some parameter defined in a `const` for instance, by the user.

The goal would be to make `COM` as much agnostic as possible to `SCI` so that `COM` does not depend on it. This point is kind of another question: if `COM` loads `SCI`, shouldn’t `SCI` be `add`ed to the environment of `COM` ? (which it is in my current implementation).

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [July 13, 2021, 1:20pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/2 "2021-07-13T13:20:54Z")

</div>

> [@BambOoxX](#):
>
> What if I wanted to use the same server, with another `SCI2` package ?

Is this a real concern or are you trying to account for some possible future use case that you’re not yet sure will actually occur in practice? If so, I’d make `COM` and `SCI` totally unaware of one another and create a third package/module/piece of code that ties these two together.

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [July 13, 2021, 1:27pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/3 "2021-07-13T13:27:29Z")

</div>

> [@Sukera](#):
>
> Is this a real concern or are you trying to account for some possible future use case that you’re not yet sure will actually occur in practice?

Well, this is a real concern ^^. I am not sure when it will happen, but I am sure it will happen at some point, so I’d like to be prepared when it happens.

> [@Sukera](#):
>
> If so, I’d make `COM` and `SCI` totally unaware of one another and create a third package/module/piece of code that ties these two together.

The goal is indeed to make `COM` and `SCI` unaware of one another, but I’d rather not add another package, otherwise this defeats a bit the purpose of making `SCI` unaware of `COM`.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [July 13, 2021, 1:37pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/4 "2021-07-13T13:37:02Z")

</div>

If you want to keep `COM` generic enough to not have to change it when adding a new `SIC2` to the mix, I don’t think there’s a better alternative available. If you make `SIC` aware of `COM`, you’ll have to make `SIC2` aware of `COM` as well. If you make `COM` aware of `SIC`, you’ll have to make it aware of `SIC2` as well, and on top of that have to make sure that it doesn’t break compatibility with `SIC` when adding `SIC2`. That’s why I think the cleanest solution is to make sure `COM` is taking care of communication (and only communication) and have `SIC` take care of the calculation (and only the calculation). The way to connect the two would be through a third package, which you can extend and modify at will, when you have to add `SIC2`, without worrying about breaking the core functionality of either `SIC` or `COM` by accident.

I have to admit though, it feels kind of wrong to define structs on the fly based on messages from some remote process, perhaps there’s a better abstraction to be found here?

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [July 13, 2021, 1:49pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/5 "2021-07-13T13:49:58Z")

</div>

My first idea beyond the `using COM(SCI)` was to:

- define a globale variable, say `const SciPackage = :SCI`
- add an ` __init__ ` function to `COM` that would use `SciPackage` to load `SCI` and define the relevant authorization lists upon `using COM`

but I don’t know if this is a relevant strategy.

Supposing I manage to make `COM` and `SCI` unaware of each other. I still need to perform my computations between communication steps, so somewhere inside `COM` functions, I need a `compute` call that is very `SCI`-dependent… i don’t see how I can avoid this.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [July 13, 2021, 2:02pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/6 "2021-07-13T14:02:09Z")

</div>

> [@BambOoxX](#):
>
> add an ` __init__ ` function to `COM` that would use `SciPackage` to load `SCI` and define the relevant authorization lists upon `using COM`

That sounds a lot like [Requires.jl](https://juliahub.com/ui/Packages/Requires/IyxeS/1.1.3).

> [@BambOoxX](#):
>
> Supposing I manage to make `COM` and `SCI` unaware of each other. I still need to perform my computations between communication steps, so somewhere inside `COM` functions, I need a `compute` call that is very `SCI` -dependent… i don’t see how I can avoid this.

I think this is the point where more information about your true code structure is necessary for more help from my side. I’m still not sure I understood you correctly - are you really generating new structs (new types) at runtime based on messages from a remote process? Or are you only _instantiating_ instances of existing structs?

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [July 13, 2021, 2:32pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/7 "2021-07-13T14:32:00Z")

</div>

> [@Sukera](#):
>
> are you really generating new structs (new types) at runtime based on messages from a remote process? Or are you only _instantiating_ instances of existing structs?

At runtime I am only instanciating types already declared. Basically, if the server receives something that can be deserialized to an authorized (and declared of course) type, it mutates the appropriate field of a `Container` instance (the single one instantiated actually), that is of the same type.

Another way to see this is that I’d like to have an overall structure of code as

```julia
using SCI
const SciPackage = SCI
using COM
<some code>

```

where `SCI` defines a `compute` function and somewhere inside `COM` I have a line calling `SciPackage.compute`.

Then what I would need for `SCI` (as well as a potential `SCI2`) is to define some types like `Container` in addition to their standard types, as well as the `compute` function. In some way, that they define their interface to `COM`.

_This is what I would like, but I am really not sure that works in julia_

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [July 13, 2021, 4:48pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/8 "2021-07-13T16:48:56Z")

</div>

@Sukera

> [@Sukera](#):
>
> I have to admit though, it feels kind of wrong to define structs on the fly based on messages from some remote process, perhaps there’s a better abstraction to be found here?

Sorry, I missed this part at first…

Just to be clear, the target types are already defined, I am just modifying instances here. If the data source were not trustworthy, that would be bad indeed, but this is not the case here, as everything happens locally. And anything that is not an authorized type/instruction is discarded.

Regarding the `Container` this choice is based on previous discussions, though I can’t recall where, probably on Slack (edit: it was there ["Locally global" variable? - #19 by BambOoxX](https://discourse.julialang.org/t/locally-global-variable/60471/19))… It was advertised as the most appropriate choice for this kind of stuff. What would you have in mind instead ?

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [July 13, 2021, 5:46pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/9 "2021-07-13T17:46:05Z")

</div>

> [@Sukera](#):
>
> That sounds a lot like [Requires.jl](https://juliahub.com/ui/Packages/Requires/IyxeS/1.1.3).

After reading thoroughly the documentation of `Requires`, this seems to be the case indeed… that would still make `COM` somewhat aware of `SCI`, but in a very limited fashion.  
Also as `SCI` would then be under `COM.SCI` this would allow to use things like `const compute = SCI.compute` so that I can keep using the same implementation in `COM`.

Some remark I made to myself earlier regarding your comment

> [@Sukera](#):
>
> If you want to keep `COM` generic enough to not have to change it when adding a new `SIC2` to the mix, I don’t think there’s a better alternative available. If you make `SIC` aware of `COM` , you’ll have to make `SIC2` aware of `COM` as well. If you make `COM` aware of `SIC` , you’ll have to make it aware of `SIC2` as well, and on top of that have to make sure that it doesn’t break compatibility with `SIC` when adding `SIC2` . That’s why I think the cleanest solution is to make sure `COM` is taking care of communication (and only communication) and have `SIC` take care of the calculation (and only the calculation). The way to connect the two would be through a third package, which you can extend and modify at will, when you have to add `SIC2` , without worrying about breaking the core functionality of either `SIC` or `COM` by accident.

I feel like it is better to make `SCI` aware of `COM` rather than the other way around:

- If `SCI` defines some unnecessary stuff sometimes it’s not that important.
- If `SCI` is not ready to handle stuff passed by `COM`, it seems fairly easy to detect (check the presence of a `Container` type and of `compute` function or else when firing up `COM`)
- In terms of maintenance, if I modify the functions/types in `SCI` I will surely need to modify the container, but probably not what `COM` does so modifications are performed in the same package (and git repo for the matter).

Do you agree with this ?

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [July 14, 2021, 5:56am UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/10 "2021-07-14T05:56:24Z")

</div>

> [@BambOoxX](#):
>
> Do you agree with this ?

Yes, that sounds like a good idea - I didn’t suggest it because it seemed like you wanted to keep `SCI` computation-only 🙂 In general, roughly following something like the OSI model when designing software is a good idea (i.e., the innermost layer is infrastructure/communications/libraries, wrapped by application logic and UI). In your case, you really have two applications - the frontend UI in C# and the backend in julia. Applying the above logic to the julia code is why I suggested having `SCI` and `COM` be oblivious of each other and instead have some glue package that takes care of plugging things together (e.g. by `using` both `SCI` and `COM`, passing `compute` to `COM` etc. We have higher order functions after all, so there’s no need for `COM` to know about `SCI` beforehand).

---

<div class="post-metadata">

**Author:** ![genkuroki](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/genkuroki/32/18030_2.png) [@genkuroki](https://discourse.julialang.org/u/genkuroki)\
**Post date:** [July 14, 2021, 8:41am UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/11 "2021-07-14T08:41:39Z")

</div>

Since there is no minimal working example (MWE), I could not figure out what you really wanted to do. ([Please read: make it easier to help you](https://discourse.julialang.org/t/please-read-make-it-easier-to-help-you/14757))

However, I thought that possibly you would like to do something like this. Please take a look at the MWE below.

Input:

```julia
module SCI

export Problem, Algorithm_A, Algorithm_B, solve

abstract type AbstractProblem end
struct Problem{T} <: AbstractProblem x::T end

abstract type AbstractAlgorithm end
Base.@kwdef struct Algorithm_A{T} <: AbstractAlgorithm a::T = 2.0 end
Base.@kwdef struct Algorithm_B{T} <: AbstractAlgorithm a::T = 3.0 end
default_algorithm(prob::Problem) = Algorithm_A()

struct Solution{R, P<:AbstractProblem, A<:AbstractAlgorithm} result::R; prob::P; alg::A end
solve(prob::AbstractProblem) = solve(prob, default_algorithm(prob))
solve(prob::AbstractProblem, alg::AbstractAlgorithm) = Solution(alg.a * prob.x, prob, alg)

"""
Here, `Base` module plays the role of `COM` package.
SCI module can define the method of 
`Base.show` (≈ `COM.show`) function for `SCI.Solution` type.
"""
function Base.show(io::IO, sol::Solution)
    result = """
    Problem: $(sol.prob)
    Algorithm: $(sol.alg)
    Result: $(sol.result)
    """
    print(io, result)
end

end

using .SCI
@show prob = Problem(1.5)
println()
println(solve(prob))
println(solve(prob, Algorithm_B()))

```

Output:

```julia
prob = Problem(1.5) = Problem{Float64}(1.5)

Problem: Problem{Float64}(1.5)
Algorithm: Algorithm_A{Float64}(2.0)
Result: 3.0

Problem: Problem{Float64}(1.5)
Algorithm: Algorithm_B{Float64}(3.0)
Result: 4.5

```

Additional input:

```julia
module SCI2 # extension of SCI module

export Problem2, Algorithm_C

using ..SCI: SCI, AbstractProblem, AbstractAlgorithm, Solution

struct Problem2{T} <: AbstractProblem x::T; y::T end
Base.@kwdef struct Algorithm_C{T} <: AbstractAlgorithm a::T = 2.0; b = 3.0 end
SCI.default_algorithm(prob::Problem2) = Algorithm_C()
SCI.solve(prob::Problem2, alg::Algorithm_C) = Solution(alg.a * prob.x + alg.b * prob.y, prob, alg)

end

using .SCI2
@show prob2 = Problem2(10.0, 1.0)
println()
println(solve(prob2))

```

Output:

```julia
prob2 = Problem2(10.0, 1.0) = Problem2{Float64}(10.0, 1.0)

Problem: Problem2{Float64}(10.0, 1.0)
Algorithm: Algorithm_C{Float64}(2.0, 3.0)
Result: 23.0

```

In the above example I don’t define `AbstractSolution` type, nor did I make `Solution` a subtype of it. But you can define it, and then define another Solution type as a subtype of it in `SCI2` module, and also define how to display objects of another Solution type. Many other extensions are also possible.

See also [Function depending on the global variable inside module - #10 by genkuroki](https://discourse.julialang.org/t/function-depending-on-the-global-variable-inside-module/64322/10)

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [July 14, 2021, 12:00pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/12 "2021-07-14T12:00:48Z")

</div>

> [@genkuroki](#):
>
> Since there is no minimal working example (MWE), I could not figure out what you really wanted to do. ([Please read: make it easier to help you](https://discourse.julialang.org/t/please-read-make-it-easier-to-help-you/14757))

I actually did not put an MWE, because I felt my question was somewhat abstract, and I did not want to introduce _bias_ in the answers by forcing to be close to my current implementation.

Some comments about your MWE.

- AFAICT you define the `SCI` package such that it patches the `COM` package is this right ? If so :  
What would happen if `COM` is not loaded prior to `SC`. There is probably a way to circumvent this issue by detecting the existence of `Main.COM` but still… (that looks like what Requires.jl handles as mentioned by Sukera)
- In my my original post, I do not think I state that `SCI2` is an extension of `SCI`, only that I would like to reuse the same communication functionalities of `COM` for both `SCI` (for which `COM` was initially designed) and `SCI2`

Anyway, I thank you for your effort.

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [July 14, 2021, 12:22pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/13 "2021-07-14T12:22:55Z")

</div>

> [@Sukera](#):
>
> I didn’t suggest it because it seemed like you wanted to keep `SCI` computation-only 🙂

Let’s say that I want it to remain computation-_mostly_ ^^. `SCI` defines and exports some function for the user that themselves call the base unexported functions, so I figure it’s not that weird to define and interface for another package too…

> [@Sukera](#):
>
> roughly following something like the OSI model when designing software is a good idea

As an excuse for my current developments, I am not a software engineer, I am an engineer that does some software (among other things). So keeping things as simple as possible is crucial 🙂

I think I will

- move anything that is currently `SCI`-specific inside `COM` to `SCI`
- use Require (or something close) to make `COM` `SCI`-aware
- setup some tests to ensure that `SCI` is _communication ready_

Thanks for the help !

---

<div class="post-metadata">

**Author:** ![genkuroki](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/genkuroki/32/18030_2.png) [@genkuroki](https://discourse.julialang.org/u/genkuroki)\
**Post date:** [July 14, 2021, 2:09pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/14 "2021-07-14T14:09:58Z")

</div>

> [@BambOoxX](#):
>
> you define the `SCI` package such that it patches the `COM` package is this right ?

Yes. It is a standard pattern.

> [@BambOoxX](#):
>
> If so : What would happen if `COM` is not loaded prior to `SCI` .

Assume that, unlike the MWE I have shown above, both COM and SCI are packaged and can be loaded with `using COM` and `using SCI`. Then the result of `using SCI; using COM` and the result of `using COM; using SCI` will be the same.

In the following example, `COM` package has a function `prettify(x)` whose methods can be defined for user-defined types, and a function `prettyprint(x)` that uses `prettify(x)`. `SCI` package makes use of them.

**src/COM.jl of COM package:**

```julia
"""
`COM.prettyprint(x)` prints nicely the object `x` for which `COM.prettify(x)` method is defined.
"""
module COM
prettify(x) = sprint(io -> show(io, "text/plain", x))
prettyprint(io::IO, x) = print(io, prettify(x))
prettyprint(x) = prettyprint(stdout, x)
end

```

**Example of COM**

```julia
using COM
COM.prettyprint([π, 2π])

```

**Output:**

```julia
2-element Vector{Float64}:
 3.141592653589793
 6.283185307179586

```

**src/SCI.jl of SCI package (with deps COM):**

```julia
"""A scirntific module (calculate exp(x))"""
module SCI

abstract type AbstractProblem end
struct Problem{T} <: AbstractProblem x::T end

abstract type AbstractAlgorithm end
struct Builtin <: AbstractAlgorithm end
Base.@kwdef struct Taylor <: AbstractAlgorithm n::Int = 10 end
default_algorithm(prob::Problem) = Builtin()

struct Solution{R, P<:AbstractProblem, A<:AbstractAlgorithm} result::R; prob::P; alg::A end
solve(prob::AbstractProblem) = solve(prob, default_algorithm(prob))
solve(prob::AbstractProblem, alg::Builtin) = Solution(exp(prob.x), prob, alg)
solve(prob::AbstractProblem, alg::Taylor) = Solution(sum(prob.x^k/factorial(k) for k in 0:alg.n), prob, alg)

using COM

COM.prettify(sol::Solution{R, P, A}) where {R, P<:AbstractProblem, A<:Builtin} = """
Problem: x = $(sol.prob.x)
Algorithm: builtin exp(x)
Result: $(sol.result)
"""

COM.prettify(sol::Solution{R, P, A}) where {R, P<:AbstractProblem, A<:Taylor} = """
Problem: x = $(sol.prob.x)
Algorithm: Taylor series of exp(x) upto degree $(sol.alg.n)
Result: $(sol.result)
"""

end

```

**Code to run:**

```julia
# The order of the following two lines may be reversed.
using SCI
using COM

prob = SCI.Problem(1)
COM.prettyprint(SCI.solve(prob))
println()
COM.prettyprint(SCI.solve(prob, SCI.Taylor()))

```

**Output:**

```julia
Problem: x = 1
Algorithm: builtin exp(x)
Result: 2.718281828459045

Problem: x = 1
Algorithm: Taylor series of exp(x) upto degree 10
Result: 2.7182818011463845

```

In this way, you can use the pretty printing functions provided by `COM` package in any other package without changing any code in `COM` package.

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [July 15, 2021, 12:51pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/15 "2021-07-15T12:51:34Z")

</div>

A quick question about patching a module from another module.  
I think that you can add some `methods` to an existing `function`, but you cannot add a `function`.

For instance when doing

```julia
module COM
    compute() = println("nothing to compute")
    showsomething() = println("something")
end

module SCI
    abstract type MyAbstractType end
    struct MyIntType <: MyAbstractType 
        val::Int64
    end
    using Main.COM
    COM.compute(mi::MyIntType) = 2*mi.val
end

using .COM
using .SCI

```

Calling `methods(COM.compute)` returns

> # 2 methods for generic function “compute”:  
> [1] compute() in [Main.COM](http://Main.COM) at REPL[1]:2  
> [2] compute(mi::Main.SCI.MyIntType) in Main.SCI at REPL[2]

But if the `compute` in `COM` is absent, I get

> ERROR: UndefVarError: compute not defined  
> Stacktrace:  
> [1] getproperty(x::Module, f::Symbol)  
> @ Base .\Base.jl:26  
> [2] top-level scope  
> @ REPL[9]:7

Can you confirm this ?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [July 15, 2021, 1:00pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/16 "2021-07-15T13:00:25Z")

</div>

why would you want to add a function. If `COM` doesn’t have `compute` in itself, it wont call `COM.compute` anyway, so what’s the point of “adding” a `compute` into COM afterwards?

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [July 15, 2021, 1:24pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/17 "2021-07-15T13:24:18Z")

</div>

Before this discussion I would have said “Sure, there is no point doing that”. However, given that you can add methods, I really don’t see why you could not add functions.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [July 15, 2021, 1:28pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/18 "2021-07-15T13:28:47Z")

</div>

you’re not adding methods BACK to `COM`, you’re adding methods to the “method table” (in this session, let’s say) which does not belong to `COM` like a function would.

this is similar to asking “why can I modify a field of `mutable struct` but can’t add field?” because they are different kind of “modification”

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [July 15, 2021, 1:33pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/19 "2021-07-15T13:33:28Z")

</div>

You can add functions, but that involves `eval` (which is almost always a very bad idea indeed) to force your code into the existing module (i.e. evaluate it in the context of the other module). If you’re thinking about doing this, you’re very likely on a not-good-not-happy path (especially since you’re basically parsing some input received from another process).

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [July 15, 2021, 1:37pm UTC](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568/20 "2021-07-15T13:37:43Z")

</div>

So if I undestand corrently, the idea is to setup a _blank_ `compute` function that would only serve as a default result provider.

Then whenever I have to integrate `COM` in some `SCI` package, I just add some methods to update what `compute` actually does based on that context.

Is that it ?

[Next page](https://discourse.julialang.org/t/handling-of-package-inter-dependency/64568.md?page=2)
