# What does \`export Foo\` do when there are multiple \`Foo\`'s?

**URL:** <https://discourse.julialang.org/t/what-does-export-foo-do-when-there-are-multiple-foo-s/86579>\
**Category:** General Usage\
**Created:** [August 31, 2022, 1:27am UTC](https://discourse.julialang.org/t/what-does-export-foo-do-when-there-are-multiple-foo-s/86579 "2022-08-31T01:27:25Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ross\_Boylan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ross_boylan/32/9210_2.png) [@Ross\_Boylan](https://discourse.julialang.org/u/Ross_Boylan)\
**Post date:** [August 31, 2022, 1:27am UTC](https://discourse.julialang.org/t/what-does-export-foo-do-when-there-are-multiple-foo-s/86579/1 "2022-08-31T01:27:25Z")

</div>

`export` works on names, but sometimes there are several objects with the same name. Which of them are exported? I’m wondering about this because I have `struct Foo` and a constructor `function Foo`.

The [discussion of keywords](https://docs.julialang.org/en/v1/base/base/#export) says

> `export` is used within modules to tell Julia which functions should be made available to the user.

Taken literally, this means only the constructor is exported.

But the [Modules documentation](https://docs.julialang.org/en/v1/manual/modules/#modules) says

> Names (referring to functions, types, global variables, and constants) can be added to the _export list_ of a module with `export`.

and the subsequent examples make clear that `export` is not limited to functions.

My guess is that even if I only define `struct Foo`, a default constructor is created anyway, and so the function/type distinction would remain relevant.

Further, one function may have many methods, raising again the issue of what is exported. Although the documentation in Modules mentions only functions, not methods, and so maybe thinking about exporting individual methods is a mistake.

My guess is that _everything_ with the indicated names is exported. Can anyone confirm that, or tell me what the truth is if it’s something else?

BTW, if I want to explicitly get a particular binding of a name, how would I do that? This is just general curiosity; currently all I need is that `Foo(a, b, c)` gets the function `Foo`, and that seems to be working fine.

Thanks.

---

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [August 31, 2022, 1:39am UTC](https://discourse.julialang.org/t/what-does-export-foo-do-when-there-are-multiple-foo-s/86579/2 "2022-08-31T01:39:35Z")

</div>

I believe it’s the _name_ to be exported, so _all_ the object that share that name.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [August 31, 2022, 3:18am UTC](https://discourse.julialang.org/t/what-does-export-foo-do-when-there-are-multiple-foo-s/86579/3 "2022-08-31T03:18:31Z")

</div>

The first two sections below contain my first attempt at an explanation, and the third section contains a correction which I think gives a better and more correct explanation.

## 1) Semantics

### Functions

If you have `export foo`, where `foo` is a function with multiple methods, you are exporting one object: the generic function `foo`. When you declare new methods for `foo`, you are extending the definition of the function `foo`—you are not adding new objects called “methods”. In other words, new extensions to a function are called “methods”, but they are not new objects, they are extensions to the object `foo`.

Evidence for this point of view can be seen from the output of `typeof(foo)`:

```julia
julia> typeof(foo)
typeof(foo) (singleton type of function foo, subtype of Function)

```

The type `typeof(foo)` is a singleton type, of which `foo` is the only instance. In other words, the various methods do not have their own object instances (except perhaps as hidden implementation details).

### Constructors

If you have `export A`, where `A` is a type, you are exporting two objects:

- The type `A`.
- The (constructor) function `A`.

## 2) Implementation Details

The following details may provide some insight, but I think they are considered to be implementation details rather than semantic guarantees of the language.

The constructors for a type are implemented by making the type object [callable](https://docs.julialang.org/en/v1/manual/methods/#Function-like-objects). You can even do this by hand. For example:

```julia
julia> struct A end

julia> (::Type{A})(x) = A()

julia> methods(A)
# 2 methods for type constructor:
[1] A() in Main at REPL[1]:1
[2] A(x) in Main at REPL[2]:1

julia> A(42)
A()

```

So when you write `export A`, in practice you’re really just exporting the type object `A`, and the constructors come along for free, since the type object `A` is callable.

The situation for functions is similar. We can add methods to `foo` by making objects of type `typeof(foo)` callable:

```julia
julia> foo(x) = 2x
foo (generic function with 1 method)

julia> (::typeof(foo))(x, y) = x + y

julia> methods(foo)
# 2 methods for generic function "foo":
[1] foo(x) in Main at REPL[1]:1
[2] foo(x, y) in Main at REPL[2]:1

julia> foo(1, 2)
3

```

So when you write `export foo`, in practice you’re really just exporting the function object `foo`, and the methods come along for free, since the function object `foo` is callable.

## 3) Corrections / clarifications

I think my explanation above is more of a post-hoc justification. It really comes down to the passage from the docs that you quoted:

> [@Ross\_Boylan](#):
>
> But the [Modules documentation](https://docs.julialang.org/en/v1/manual/modules/#modules) says
> 
> > Names (referring to functions, types, global variables, and constants) can be added to the _export list_ of a module with `export`.

So, all that `export` really does is take a variable binding in a module and make it available in another module when you `using` the first module. A variable can only be bound to one value (object). In the case of types and functions, there are multiple ways of calling that object, but it is still only one object. And the fact that types are callable really is a language guarantee, rather than an implementation detail as I wrote above.

---

<div class="post-metadata">

**Author:** ![Ross\_Boylan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ross_boylan/32/9210_2.png) [@Ross\_Boylan](https://discourse.julialang.org/u/Ross_Boylan)\
**Post date:** [September 4, 2022, 4:20am UTC](https://discourse.julialang.org/t/what-does-export-foo-do-when-there-are-multiple-foo-s/86579/4 "2022-09-04T04:20:57Z")

</div>

I appreciate your taking the time to respond, but your response has lots of statements that sound like statements of fact that I think are only speculation (and you kind of flag them as such). Quite a number of them seem incorrect. For example,

> When you declare new methods for `foo`, you are extending the definition of the function `foo`—you are not adding new objects called “methods”. In other words, new extensions to a function are called “methods”, but they are not new objects, they are extensions to the object `foo`.

But the [julia docs](https://docs.julialang.org/en/v1/manual/types/) say

> all values in Julia are true objects

and, as you show in part 2, one can retrieve the individual methods. The documentation for [which](https://docs.julialang.org/en/v1/base/base/#Base.which-Tuple%7BAny,%20Any%7D) even refers explicitly to `Method` objects. So method objects exist _and_ they can extend existing function objects.

In part 3 you say

> all that `export` really does is take a variable binding

That differs from the quoted passage from the Modules documentation, which refers to _names_ not variable bindings. The same name may be bound to different things depending on usage, e.g., `Foo(a, b, c)` binds `Foo` to my constructor function, while `new` in an inner constructor implicitly references the type. The reason for my question was uncertainty about how such situations are handled.

Part of the justification for this is the argument that the type and the constructor are the same thing, perhaps buttressed by identification in part 2 of a way to make a constructor from the type. Aside from my doubts that you know how (implicit) constructors are “really” created (I certainly don’t know), even the mechanism you outline does create a function or method, which is not the same as a type even if it has the same name.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [September 4, 2022, 5:57am UTC](https://discourse.julialang.org/t/what-does-export-foo-do-when-there-are-multiple-foo-s/86579/5 "2022-09-04T05:57:09Z")

</div>

> [@Ross\_Boylan](#):
>
> as you show in part 2, one can retrieve the individual methods. The documentation for [which](https://docs.julialang.org/en/v1/base/base/#Base.which-Tuple%7BAny,%20Any%7D) even refers explicitly to `Method` objects. So method objects exist _and_ they can extend existing function objects.

The confusion here is because much of Julia is implemented in Julia. You might have overlooked this part of my comment:

> [@CameronBieganek](#):
>
> the various methods do not have their own object instances _(except perhaps as hidden implementation details)_.

[emphasis added]

Yes, `Method` objects exist, but only as an implementation detail—they are not part of the Base Julia interface, because they do not have a docstring (and a docstring entry in the manual):

```julia
help?> Method
search: Method methods MethodError methodswith hasmethod

  No documentation found.

```

Furthermore, look at what happens if we look at the value of a constructor definition:

```julia
julia> struct A end

julia> a = function A(x)
           @show x
           A()
       end
A

julia> a
A

julia> typeof(a)
DataType

```

So, we see that the value returned by a constructor definition for the type `A` is literally just the type `A`. So a constructor really just is a callable type. And this is documented in the manual (albeit sparsely) in the section on [Function-like objects](https://docs.julialang.org/en/v1/manual/methods/#Function-like-objects):

> This mechanism is also the key to how type constructors and closures (inner functions that refer to their surrounding environment) work in Julia.

There is a little more detail on this in the [old v0.6 docs](https://docs.julialang.org/en/v0.6/manual/constructors/#constructors-and-conversion-1):

> Constructors `T(args...)` in Julia are implemented like other callable objects: methods are added to their types. The type of a type is `Type`, so all constructor methods are stored in the method table for the `Type` type. This means that you can declare more flexible constructors, e.g. constructors for abstract types, by explicitly defining methods for the appropriate types.

These same arguments carry over to methods of generic functions. Consider this example where we look at the values of method definitions:

```julia
julia> f = function foo(x::Int)
           1
       end
foo (generic function with 1 method)

julia> g = function foo(x::Float64)
           2
       end
foo (generic function with 2 methods)

julia> typeof(f)
typeof(foo) (singleton type of function foo, subtype of Function)

julia> typeof(g)
typeof(foo) (singleton type of function foo, subtype of Function)

julia> f === g
true

```

We see here that the value of a method definition for the function `foo` is simply the function `foo` itself. In other words, the concept of a `Method` object does not exist in Julia unless you reach into the Julia internals. (Don’t do that.)

> [@Ross\_Boylan](#):
>
> That differs from the quoted passage from the Modules documentation, which refers to _names_ not variable bindings.

I was a little loose with my language there. My reasoning was that within a particular scope, a name/variable is always bound to exactly one value/object at a time. Hence, I used “variable binding” interchangeably with “name”. I’ll think about how to rewrite that in a more accurate way, since there is some distinction between “names” and “variables”.

> [@Ross\_Boylan](#):
>
> The same name may be bound to different things depending on usage, e.g., `Foo(a, b, c)` binds `Foo` to my constructor function

No, only the assignment operator, `=`, binds variables to values, and the value associated with a name does not change based on your usage of that name.

> [@Ross\_Boylan](#):
>
> while `new` in an inner constructor implicitly references the type

I don’t see how the special `new` function is relevant—it has nothing to do with names or bindings.

---

<div class="post-metadata">

**Author:** ![Ross\_Boylan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ross_boylan/32/9210_2.png) [@Ross\_Boylan](https://discourse.julialang.org/u/Ross_Boylan)\
**Post date:** [September 15, 2022, 4:25am UTC](https://discourse.julialang.org/t/what-does-export-foo-do-when-there-are-multiple-foo-s/86579/6 "2022-09-15T04:25:16Z")

</div>

I don’t know why you are mystifying something simple: methods are objects. Neither you nor I originally said anything about them being part of `Base` or having docstrings, or being implemented in `julia` or `C`. None of those things matter. So explaining how they work by saying they are not objects or not “real” objects is not going to work.

> [@CameronBieganek](#):
>
> No, only the assignment operator, `=`, binds variables to values, and the value associated with a name does not change based on your usage of that name.

Any time a name occurs in a program the program must associate it with a value. That is a binding too, albeit not necessarily a long-lived one.

> [@CameronBieganek](#):
>
> > [@Ross\_Boylan](#):
> >
> > while `new` in an inner constructor implicitly references the type
> 
> I don’t see how the special `new` function is relevant—it has nothing to do with names or bindings.

`new` instantiates a type, and so it needs to know what type it is instantiating. That is the type within which the new appears, and so is an implicit reference to the type and its name. Functions with the same name may exist, but I presume `new` will not call them.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [September 18, 2022, 4:18pm UTC](https://discourse.julialang.org/t/what-does-export-foo-do-when-there-are-multiple-foo-s/86579/7 "2022-09-18T16:18:48Z")

</div>

> [@Ross\_Boylan](#):
>
> I don’t know why you are mystifying something simple: methods are objects. Neither you nor I originally said anything about them being part of `Base` or having docstrings, or being implemented in `julia` or `C`. None of those things matter. So explaining how they work by saying they are not objects or not “real” objects is not going to work.

It’s not clear to me if you understand the difference between the semantics of a language and the implementation details of a language. The semantics of a language are the logical rules for what the language means and how to use it. As a user of a language, you should only be concerned with the semantics, not the implementation details. In fact, you should actively ignore the implementation details, since they can change at any time.

Parts of the Julia runtime are implemented in C. Does that mean that the intermediate C objects have a semantic meaning in the Julia language? No, it does not. The Julia parser is written in femtolisp. Does that mean that the intermediate femtolisp objects have a semantic meaning in the Julia language? No, it does not. Parts of the Julia language are implemented in Julia itself. Does that mean that the intermediate Julia objects have a semantic meaning in the Julia language? No, it does not.

The FAQ [has the following](https://docs.julialang.org/en/v1/manual/faq/#How-does-Julia-define-its-public-API?) to say about the public API for Julia:

> ### How does Julia define its public API?
> 
> The only interfaces that are stable with respect to SemVer of `julia` version are the Julia `Base` and standard libraries interfaces described in the documentation and not marked as unstable (e.g., experimental and internal). Functions, types, and constants are not part of the public API if they are not included in the documentation, _even if they have docstrings_.

The `Method` type is _not_ in the documentation, therefore it is _not_ part of the public API for Julia. This is really not a disputable fact. There is no way to access or create a `Method` object without relying on internal implementation details of the Julia language.

In my previous post, I gave an example that demonstrated that the value of a method definition expression for the function `foo` is _not_ a `Method` object, it is simply the generic function `foo`. If you can’t believe the evidence of your own eyes, then there is nothing I can do for you.
