Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defining module in more than one file #1222

Closed
staticfloat opened this issue Aug 27, 2012 · 15 comments
Closed

Defining module in more than one file #1222

staticfloat opened this issue Aug 27, 2012 · 15 comments

Comments

@staticfloat
Copy link
Member

I'm writing my first "module", and I know that documentation is pretty sparse on this topic so I thought I would ask some questions that have been nagging at me and that the mailing list posts have only partially answered:

  • What is the difference between import, include, load and require? Do we need to load before we import?
  • Is it possible/encouraged to "extend" a module in Base? For instance, I'm writing some signal processing routines and so I made a file window.jl:
module DSP
import Base.*
...
end # module DSP

However this gives a warning that because Base already has a DSP inside it, it conflicts with the current module and is thus not imported. How then, do we import the rest of the module we're defining?

@kmsquire
Copy link
Member

Might want to bring this up on julia-dev.

@staticfloat
Copy link
Member Author

My hope is that if I get good discussion here, this can turn into a wiki
page. I'm not really a fan of searching through discussion list archives
for info.

On Mon, Aug 27, 2012 at 3:03 PM, Kevin Squire [email protected]:

Might want to bring this up on julia-dev.


Reply to this email directly or view it on GitHubhttps://github.com//issues/1222#issuecomment-8072585.

@johnmyleswhite
Copy link
Member

We should really add the original e-mail describing modules to the wiki, then add pieces from this conversation as well.

-- John

On Aug 27, 2012, at 6:16 PM, Elliot Saba wrote:

My hope is that if I get good discussion here, this can turn into a wiki
page. I'm not really a fan of searching through discussion list archives
for info.

On Mon, Aug 27, 2012 at 3:03 PM, Kevin Squire [email protected]:

Might want to bring this up on julia-dev.


Reply to this email directly or view it on GitHubhttps://github.com//issues/1222#issuecomment-8072585.


Reply to this email directly or view it on GitHub.

@kmsquire
Copy link
Member

Original email: https://groups.google.com/d/msg/julia-dev/Rj1xkrZkgcw/yb9ZlEAoKzUJ

Doesn't answer all questions, but cut-and-paste should be able to turn it into a wiki, or with a little editing, an RST document that lives under doc/manual.

@JeffBezanson
Copy link
Member

Our current thinking is that modules are specific sets of definitions that are not generally modified. So it's not the case that, for example, all future DSP-related functions should put themselves in DSP, unless the code is pushed to that package.

import is currently just a name binding operation that doesn't touch the filesystem. That might change soon.

include is a primitive function that simply evaluates a series of expressions in a file.

load and require can actually be merged; I will do that soon. They are basically include plus bells and whistles: using a search path, loading on all processes, and not reloading files that haven't changed.

@toivoh
Copy link
Contributor

toivoh commented Aug 31, 2012

I think the bells and whistles of require seem to be incompatible with how modules work, see
https://groups.google.com/d/msg/julia-dev/-RFEwnlAbcg/ez4gqiEuDc0J.
Perhaps too soon to get rid of the old load?

@staticfloat
Copy link
Member Author

Thanks for the info on the loading functions Jeff, but if this is the case,
how do you effect the "mixins" that are talked about in the email thread
linked to above by Keno?

-E
On Aug 29, 2012 9:34 PM, "Jeff Bezanson" [email protected] wrote:

Our current thinking is that modules are specific sets of definitions that
are not generally modified. So it's not the case that, for example, all
future DSP-related functions should put themselves in DSP, unless the
code is pushed to that package.

import is currently just a name binding operation that doesn't touch the
filesystem. That might change soon.

include is a primitive function that simply evaluates a series of
expressions in a file.

load and require can actually be merged; I will do that soon. They are
basically include plus bells and whistles: using a search path, loading
on all processes, and not reloading files that haven't changed.


Reply to this email directly or view it on GitHubhttps://github.com//issues/1222#issuecomment-8149177.

@Keno
Copy link
Member

Keno commented Aug 31, 2012

@staticfloat I think you meant Kevin. I'm Keno ;)

@staticfloat
Copy link
Member Author

@loladiro; hahaha, indeed. Sorry about that.

@staticfloat
Copy link
Member Author

@JeffBezanson; Given all the above information, can you point me to an example of a "mixin"? E.g. defining a module over more than one file?

@nolta
Copy link
Member

nolta commented Sep 10, 2012

This seems to work:

julia> module DSP
       import Base.*
       xyz(a) = 2*a
       end
Warning: import of Base.DSP into DSP conflicts with an existing identifier; ignored.

julia> import DSP

julia> DSP.xyz(4)
8

@vtjnash
Copy link
Member

vtjnash commented Sep 10, 2012

If you are the one defining the module, you can include many files to live inside the module (recursively if you want). Modules are un-affected by file boundaries. So you can write something like:

module DSP
    import Base.*
    export base_dsp_stuff, more_dsp_stuff
    include("dsp-function1.jl")
    include("dsp-function2.jl")
end

And it will all end up defined in DSP.

If you are adding functionality to a module, you just make a new module. Importing DSP.* will merge your function definitions with previous ones.

module DSP_extensions
    import Base.*
    import DSP.*
    export new_stuff, more_new_stuff
    include("more_dsp_stuff.jl")
end

Then someone can import your code and the DSP code (since exports are not recursive, but you might want to play around with this some to discover finer points of the rules) to use both.

import DSP.*
import DSP_extensions.*

Note that this is merging the exported function definitions, even before module B is imported into the current module (we could have declare a to be a global in module B to override this behavior):

julia> module A
       export a
       a(::Int) = 1
       end

julia> module B
       import A.*
       a(::Symbol) = 2
       end

julia> import A

julia> A.a(:a)
2

julia> A.a(1)
1

julia> B
B not defined

julia> import B

julia> B.a(1)
1

julia> B.a(:a)
2

@staticfloat
Copy link
Member Author

How silly of me; I thought the warning meant that it was not importing
Base.DSP into DSP's workspace, but it does. I should double-check that
something actually doesn't work before assuming it doesn't. :P

On Tue, Sep 11, 2012 at 12:01 AM, Mike Nolta [email protected]:

This seems to work:

julia> module DSP
import Base.*
xyz(a) = 2*a
end
Warning: import of Base.DSP into DSP conflicts with an existing identifier; ignored.

julia> import DSP

julia> DSP.xyz(4)
8


Reply to this email directly or view it on GitHubhttps://github.com//issues/1222#issuecomment-8440150.

@nolta
Copy link
Member

nolta commented Sep 11, 2012

(we could have declared a to be a global in module B to override this behavior)

If people want to try this, note that the global statement position matters:

julia> module B
       global a
       import A.*
       a(::Symbol) = 2
       end

julia> import B

julia> B.a
Methods for generic function a
a(Int64,) at none:3
a(Symbol,) at none:4
julia> module B
       import A.*
       global a
       a(::Symbol) = 2
       end

julia> import B

julia> B.a
Methods for generic function a
a(Symbol,) at none:4
julia> module B
       import A.*
       a(::Symbol) = 2
       global a
       end

julia> import B

julia> B.a
a not defined

@staticfloat
Copy link
Member Author

I believe that this wraps up this discussion, if anyone has more comments, feel free to bring them up and I'll reopen.

KristofferC added a commit that referenced this issue Feb 25, 2025
)

Stdlib: LinearAlgebra
URL: https://github.com/JuliaLang/LinearAlgebra.jl.git
Stdlib branch: master
Julia branch: master
Old commit: e7da19f
New commit: f781708
Julia version: 1.13.0-DEV
LinearAlgebra version: 1.12.0(Does not match)
Bump invoked by: @KristofferC
Powered by:
[BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl)

Diff:
JuliaLang/LinearAlgebra.jl@e7da19f...f781708

```
$ git log --oneline e7da19f..f781708
f781708 use the custom sysimage when running documentation (and doctests) as well (#1226)
8fdbfd5 Add `getindex` for `SymTridiagonal` using a `BandIndex` (#1223)
91b8845 Use `BandIndex` directly in `diagzero` call in `getindex` (#1222)
ef7ef3a Restrict triangular type aliases to `AbstractMatrix`es (#1220)
af7a9ac Use `BandIndex` directly in `diagzero` call in `getindex` for banded matrices
579b5f7 Specialize Diagonal * Adjoint (#1207)
5cf41c4 Indirection in matrix multiplication to avoid ambiguities (#1210)
0a9c164 Remove specialized `issymmetric`/`ishermitian` for `Diagonal{<:Number}` (#1213)
ff5648a Make unitary matrices in `svd`/`eigen` of `Diagonal` be unitless (#1155)
e096a03 Don't mutate arrays in symmetric trig functions (#1206)
c234bed Loop over `diagind` in `diag` for banded matrices (#1211)
57785c7 More resizing for truncating return values from LAPACK (#1190)
b464203 Materialize adjoint in mul with `HermOrSym` (#1191)
16d9d61 Restrict Diagonal sqrt branch to positive diag (#1203)
baa48b7 Verbose `showerror` for `SingularException` (#1204)
e0b59a7 Remove `LinearAlgebra` qualifications in `cholesky.jl` (#1209)
95d009b Remove `LinearAlgebra` qualifications in `cholesky.jl`
c550974 change to pivot
ed35a37 Add fast path in generic matmul (#1202)
8c7fe68 Detailed `showerror` for `SingularException`
2a1696a Explicitly declare type constructor imports (#1196)
101f766 Added note to BLAS.[g|s]et_num_threads about Apple Accelerate not supporting it  (#1195)
5aca26f Simplify `getproperty` for `Cholesky*` (#1197)
924dda4 remove copy-allocation on accessing `cholesky` factors (`.L`, `.U`) (#1186)
6f02532 Use `BLAS.trsm!` instead of `LAPACK.trtrs!` in left-triangular solves (#1194)
```

Co-authored-by: KristofferC <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants