Since modules are not tied to files, you can nest modules easily to achieve
the split that you describe below, using `import` and `using` at the right
places:

module Top
  import A
  import B
  module UseA
    using ..Top
    using A
    import B
  end
end

I rather suspect that this style might become a "best practice", such that
at most one module is fully imported in any given module scope. I don't
think this style is currently used much however .

this is also quite similar to creating "conditional modules" (
https://github.com/JuliaLang/julia/pull/6884)

> If I want to use f() from mymodule in the current module I can just do f(x)
= mymodule.f(x).

While valid (and I use this style definitions sometimes in my code), the
semantics of this are very different from the current behavior. In the
current behavior, defining a new method also makes that method available to
all users of that original function. This is what makes `Base.convert`,
`Base.call`, `Base.+`, `Base.start`, etc. very general. I use the
alternative style definition when I have some reason that I want to
significantly alter the method dispatch order.


On Fri Jan 02 2015 at 8:50:28 PM samoconnor <samocon...@mac.com> wrote:

> I've been trying to learn a bit about Julia's internals in the hopes of
> understanding enough to be able to make some sensible suggestions on module
> semantics. So far I've been buried in libuv land as a learning exercise...
> https://github.com/JuliaLang/julia/pull/9450.
>
> It occurs to me is that it's nice to have a simple succinct semantic that
> is immediately understandable, and to make sure that any convenience syntax
> (or macros) that sit on top of that have no hidden magic. (I come from an
> odd place called Tcl where there are only 12 rules
> http://wiki.tcl.tk/10259)
> Please excuse me if any of the following is obvious to those in the know,
> or is silly in the context of Julia... these ideas are not fully thought
> out yet...
>
> e.g. what if the only way to call a function in a different module was by
> it's full name mymodule.f() and there is no using or import.
> If I want to use f() from mymodule in the current module I can just do f(x)
> = mymodule.f(x).
> If I already have a function f(), then the semantics of how the
> mymodule.f()'s methods get merged in are clearly defined by the existing
> dispatch rules, no special module rules are needed.
>
> On top of that you could have functions or macros for "using" and
> "import", but they would just be for convenience, no new rules.
>
> An example I've considered is a GUI toolkit or a plotting library where
> you have possibly hundreds of functions and you don't want to be saying
> FooBarGraphicsLibrary.display(my_window) all over the place, you'd rather
> just say display(my_window).  However, there is a problem with possible
> unexpected dispatch results if you just splat all
> of FooBarGraphicsLibrary's functions/methods into the current scope. Maybe
> a good pattern is to have a macro that says @prefix "fbg_"
> "FooBarGraphicsLibrary.* that does fbg_display(x...)
> = FooBarGraphicsLibrary.display(x...) etc.. for all the functions in the
> module. That way all the GUI toolkit functions names have an unambiguous
> name prefix but they are not as long and unwieldy as using the full path
> name.
>
> I think that importing large utility APIs is a very different use case to
> e.g. importing a mathematical type API. If you import an API for imaginary
> numbers, you want all the usual math functions to just work by the magic of
> multiple dispatch. However, with something like a web-services API, or any
> number of  other system-programmng API's you probably want to avoid
> ambiguous dispatch possibilities as much as possible and make it clear to
> the reader of the code that "this is a call into wrapper library foo".
>
> There seems to be a tradeoff between on one hand having dynamically
> loadable modules that are independently QAed and are guaranteed to have
> certain behaviour; and on the other hand being able to import modules in a
> way that gives rich interaction of types and dispatch (and the possibility
> of full system optimisation etc...). Maybe these two use cases should have
> different rules...
>

Reply via email to