Modules, import and export

470 views
Skip to first unread message

Alessandro "Jake" Andrioni

unread,
Dec 6, 2012, 1:56:59 PM12/6/12
to julia...@googlegroups.com
Hello,

Two questions:
1) All functions I imported from Base in my module are automatically
exported (i.e. the methods I defined are added to them), even without
'using ModuleName'. Is this WAD?
Example: I define a new method for 'reverse' in my module. If there's
a 'import Base.reverse' line in the module, my method is added as soon
as the file is loaded, even if I didn't 'export reverse'.

2) If I export a function with the same name as one in Base, but which
I didn't import in the module, and do 'using ModuleName' before using
that function, it gets redefined, but not if I used it before.
Example:
Say I define a + function in my module as:
module ModuleName
type MyType; end
export +
+(a::MyType, b::MyType) = a
end

In the REPL the following happens:

julia> using ModuleName
julia> +
Methods for generic function +
+(MyType,MyType) at /home/jake/workspace/modulename.jl:4

i.e. it overwrites the + function. But if I use it before the "using
ModuleName", it doesn't:

julia> 1 + 2
3
julia> using ModuleName
julia> +
Methods for generic function +
+(Real,Range{T<:Real}) at range.jl:137
+(Real,Range1{T<:Real}) at range.jl:138
+(Ranges{T<:Real},Real) at range.jl:139
etc

I hope it's not too confusing, but I can provide the files to clarify
if needed. I'm using commit 94c33495ef.

Thanks,
Alessandro

Stefan Karpinski

unread,
Dec 6, 2012, 2:04:04 PM12/6/12
to Julia Users
On Thu, Dec 6, 2012 at 1:56 PM, Alessandro "Jake" Andrioni <jake...@gmail.com> wrote:
Hello,

Two questions:
1) All functions I imported from Base in my module are automatically
exported (i.e. the methods I defined are added to them), even without
'using ModuleName'. Is this WAD?
Example: I define a new method for 'reverse' in my module. If there's
a 'import Base.reverse' line in the module, my method is added as soon
as the file is loaded, even if I didn't 'export reverse'.

Export controls what names in your module get seen when some other module does "using Foo". When you add methods to something from Base, you are modifying that function object, and export has no effect on who sees that – anyone using that function will be affected, regardless of how they got it. (I don't know what WAD means.)
Yes, that's the intended behavior. If you use + before using ModuleName statement, then you must intend to use Base's + so that's the one you get.

Alessandro "Jake" Andrioni

unread,
Dec 6, 2012, 2:12:22 PM12/6/12
to julia...@googlegroups.com
On 6 December 2012 17:04, Stefan Karpinski <ste...@karpinski.org> wrote:
> Export controls what names in your module get seen when some other module
> does "using Foo". When you add methods to something from Base, you are
> modifying that function object, and export has no effect on who sees that –
> anyone using that function will be affected, regardless of how they got it.
> (I don't know what WAD means.)

It means Working As Designed, thanks.

> Yes, that's the intended behavior. If you use + before using ModuleName
> statement, then you must intend to use Base's + so that's the one you get.

Thanks again, it just felt weird to see a function overwritten or not
based on previous use. (I found this when using another method in the
module which depended on +(Int64, Int64), and so didn't work, as + was
overwritten). I guess one should never export functions from Base you
want to just extend, not overwrite.

Stefan Karpinski

unread,
Dec 6, 2012, 2:18:24 PM12/6/12
to Julia Users
On Thu, Dec 6, 2012 at 2:12 PM, Alessandro "Jake" Andrioni <jake...@gmail.com> wrote:

Thanks again, it just felt weird to see a function overwritten or not based on previous use. (I found this when using another method in the module which depended on +(Int64, Int64), and so didn't work, as + was overwritten).

There's a natural intuition that operators are global whereas names can be local. To accommodate that intuition, we've talked about making modules automatically import all operators, including +. That way all normal modules would share Base's operators but can have their own named functions easily. If you want to make your own operators, you can, but you have to use baremodule to do it.

I guess one should never export functions from Base you want to just extend, not overwrite.

I'm not quite sure how you mean, but if you only want to add methods to a generic function from somewhere else, then yes, you typically don't want or need to export it.
Reply all
Reply to author
Forward
0 new messages