# How to conditionally add new features

**URL:** <https://discourse.julialang.org/t/how-to-conditionally-add-new-features/115335>\
**Category:** General Usage\
**Tags:** question, package\
**Created:** [June 7, 2024, 2:03pm UTC](https://discourse.julialang.org/t/how-to-conditionally-add-new-features/115335 "2024-06-07T14:03:51Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ohmsweetohm1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ohmsweetohm1/32/49126_2.png) [@ohmsweetohm1](https://discourse.julialang.org/u/ohmsweetohm1)\
**Post date:** [June 7, 2024, 2:03pm UTC](https://discourse.julialang.org/t/how-to-conditionally-add-new-features/115335/1 "2024-06-07T14:03:51Z")

</div>

Lets say i have a package with a type and methods

```julia
module Core
    abstract type AbstractInterfaceType end

    foo(a::AbstractType) = println("do interface stuff")

    struct MyBaseType <: AbstractInterfaceType end

    bar(a::MyBaseType) = println("do base stuff")
end

```

Now i want to add a new type that a user might use, but it comes with a heavy dependency.

```julia
import SomeHeavyPackage

struct MyExtType <: AbstractInterfaceType end

bar(a::MyExtType) = println("do ext stuff")
baz(a::MyExtType) = println("do more ext stuff")

```

How to do this correctly?

- I can add a `lib` folder and register it separately, this would introduce a new namespace.
- I think doing it via a package extension is not possible, since the `MyExtType` and `baz` are not extensions but actually new.
- Via [GitHub - JuliaPackaging/Requires.jl: Lazy code loading for Julia](https://github.com/JuliaPackaging/Requires.jl) - I’m not sure, however?

```julia
function __init__ ()
    @require SomeHeavyPackage="blablablabla" include("MyExtType.jl")
end

```

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [June 8, 2024, 2:21am UTC](https://discourse.julialang.org/t/how-to-conditionally-add-new-features/115335/2 "2024-06-08T02:21:46Z")

</div>

You can declare the functions in the main package and then implement them in the extension package.

In Core.jl

```julia
function bar end
function baz end

```

In the extension:

```julia
import SomeHeavyPackage
import Core: bar, baz

struct MyExtType <: AbstractInterfaceType end

bar(a::MyExtType) = println("do ext stuff")
baz(a::MyExtType) = println("do more ext stuff")

```

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 8, 2024, 5:07am UTC](https://discourse.julialang.org/t/how-to-conditionally-add-new-features/115335/3 "2024-06-08T05:07:47Z")

</div>

Requires technically allows names conditioned on multiple loaded packages, but extensions deliberately moved away from that messiness. Extensions aren’t much accessible and can’t be listed in import statements, and it’s ambiguous and disallowed to do `using Core, SomeHeavyPackage: MyExtType`. Your intuition is right, exposed names deserve an importable namespace, save extensions for extensions.

---

<div class="post-metadata">

**Author:** ![ohmsweetohm1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ohmsweetohm1/32/49126_2.png) [@ohmsweetohm1](https://discourse.julialang.org/u/ohmsweetohm1)\
**Post date:** [June 8, 2024, 5:50am UTC](https://discourse.julialang.org/t/how-to-conditionally-add-new-features/115335/4 "2024-06-08T05:50:07Z")

</div>

But is the new type accessable?

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [June 8, 2024, 6:50am UTC](https://discourse.julialang.org/t/how-to-conditionally-add-new-features/115335/5 "2024-06-08T06:50:47Z")

</div>

Yes because it’s part of your main package. You just can’t do some things with it until the extension defining appropriate methods is loaded

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 8, 2024, 1:08pm UTC](https://discourse.julialang.org/t/how-to-conditionally-add-new-features/115335/6 "2024-06-08T13:08:56Z")

</div>

I think he might be asking if the type’s name `MyExtType` would be accessible from outside the extension, and it’s not in the way mkitti structured it. You can get at the type in various ways (`get_extension` is the most general) but not import the name. The type could be defined in either of the packages instead of the extension, just unimplemented besides the constructors.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [June 8, 2024, 2:03pm UTC](https://discourse.julialang.org/t/how-to-conditionally-add-new-features/115335/7 "2024-06-08T14:03:04Z")

</div>

Depending on the setup, it could also make sense to add something like

```julia
# Core
export get_interface_implementation
get_interface_implementation(pkg) = get_interface_implementation(Val(pkg))
get_interface_implementation(::Val{M}) = error("No interface extension implemented for $M")

# SomeHeavyPackage extension to Core
import SomeHeavyPackage
struct MyExtType <: AbstractInterfaceType end
get_interface_implementation(::Val{SomeHeavyPackage}) = MyExtType

```

That is, you could define `get_interface_implementation` in Core and add methods in each extension in order to provide access to the types. So if the user does `using Core, SomeHeavyPackage` then they can do `T = get_interface_implementation(SomeHeavyPackage)` to get the type.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [June 9, 2024, 5:05am UTC](https://discourse.julialang.org/t/how-to-conditionally-add-new-features/115335/8 "2024-06-09T05:05:52Z")

</div>

> [@Benny](#):
>
> I think he might be asking if the type’s name `MyExtType` would be accessible from outside the extension, and it’s not in the way mkitti structured it.

Oh yes my bad, I didn’t even look in detail. Since extensions are hard to access, the usual recommendation would be to define everything that external users need _inside_ of the main package, both types and functions, hence my hasty answer.
