That rule seems extremely restrictive to me. It would be very common, for example, to create a library of functions that operate on standard data types like numbers and arrays. I don't see that we can exclude that kind of use.
Also, printing a warning is not the key part of #4345. The important part is that you'd have to qualify names in that case, which is the same thing that would happen if `export`ing the names were disallowed. On Wed, Apr 22, 2015 at 8:47 AM, Michael Francis <[email protected]> wrote: > I read through the issues / threads ( and some others ) > > https://github.com/JuliaLang/julia/issues/2327 > https://github.com/JuliaLang/julia/issues/4345 > > I'm not sure that the either the SuperSecretBase or the warning are the > correct approach. I'd like to propose a counter which is a very simple rule. > > "You can only export functions from a module where they reference at least > one type defined in the module." > > There may have to be a slight tweak for Base, though it is not hard to argue > that the primitive types are defined in Base. > > so > > module Module1 > type Bar end > my( b::Bar ) = 1 > > export my # fine exports to the global space > end > > module Module2 > type Foo end > my() = 1 > > export my # ERROR exporting function which does not reference local > type > end > > module Module3 > type Wow end > my( w::Wow ) = 1 > my() = 1 > end > export my # Is an ERROR I can not export a function which does not > reference a local type > end > > So in the example provided my Mike above, multiple dispatch would do the > right thing. If I also want to define a function for value in my module it > would work consistently against the types I define. We don't have to perform > recursive exports and import usage should be reduced. > > If you want to define an empty function you can do so with a default arg > module Module4 > type Zee end > my( ::Type{Zee} = Zee ) = 1 > export my # Works, but I can select against it using multiple dispatch > by providing the last arg > end > > > I can't convince myself that exporting Types in general (nor macros) is a > good idea. > > A tweak may be to add C# like module alias syntax, which is just syntactic > sugar over what we have ( except that we would likely want the definition of > MY to be const in the scope. > > MY = using Foo.Bar.ReallyLongModuleName > t = MY.Type() > my( t ) > > > Thoughts ? > > > I'm sure there is something I have missed, but this simple rule would seem > to encourage multiple dispatch and support the development of modules. > > On Tuesday, April 21, 2015 at 1:07:40 PM UTC-4, Jeff Bezanson wrote: >> >> We're planning to do something about this: #4345. When `using` two >> modules with conflicting names, we should do something other than pick >> one depending on order. Most likely we will print a warning, and >> require uses of the name to be qualified. >> >> If the two modules really do want to define different methods for the >> same function, then either one has to import the other, or you have to >> use your SuperSecretBase approach. >> >> On Tue, Apr 21, 2015 at 9:37 AM, Michael Turok <[email protected]> >> wrote: >> > Note that this can be made to work by tearing a page from Base: we can >> > a >> > module (SuperSecretBase), that defines a stub value() function. We then >> > use >> > importall SuperSecretBase in each of Foo and Bar. But this means that >> > any >> > module we create would need to declare its functions into >> > SuperSecretBase. >> > >> > julia> workspace() ; include("mike.jl") >> > >> > julia> using Foo >> > >> > julia> using Bar >> > >> > julia> value(Bar.BarType()) >> > "Bar::value" >> > >> > julia> value(Foo.FooType()) >> > "Foo::value" >> > >> > julia> >> > >> > Modified code follows: >> > >> > module SuperSecretBase >> > value() = nothing >> > export value >> > end >> > >> > # ------------------------------ >> > >> > module Foo >> > >> > importall SuperSecretBase >> > >> > importall Base >> > type FooType end >> > >> > value(x::FooType) = "Foo::value" >> > get(x::FooType) = "Foo::get" >> > >> > export value >> > >> > end >> > >> > # ------------------------------ >> > >> > module Bar >> > >> > importall SuperSecretBase >> > >> > importall Base >> > >> > type BarType end >> > >> > value(x::BarType) = "Bar::value" >> > get(x::BarType) = "Bar::get" >> > >> > export value >> > >> > end >> > >> > >> > >> > >> > On Tuesday, April 21, 2015 at 9:26:01 AM UTC-4, Michael Turok wrote: >> >> >> >> Hi, >> >> >> >> What is the idiomatic way to create a function value() in different >> >> modules, dispatched on different arguments, without getting the >> >> warning/error about conflicting with an existing identifier? >> >> >> >> It seems like there is an order dependency with the example below. >> >> Seems >> >> like the 2nd module defines value(), unless you had already used >> >> value() >> >> prior to importing the 2nd module. >> >> >> >> Note that if I do the same with get() a function defined in Base, I >> >> don't >> >> get an error. >> >> >> >> Code and output from julia REPL below. >> >> >> >> Any help appreciated, >> >> Michael >> >> >> >> # this is mike.jl >> >> >> >> # ------------------------------ >> >> module Foo >> >> # ------------------------------ >> >> importall Base >> >> type FooType end >> >> >> >> value(x::FooType) = "Foo::value" >> >> get(x::FooType) = "Foo::get" >> >> >> >> export value >> >> >> >> end >> >> >> >> # ------------------------------ >> >> module Bar >> >> # ------------------------------ >> >> importall Base >> >> >> >> type BarType end >> >> >> >> value(x::BarType) = "Bar::value" >> >> get(x::BarType) = "Bar::get" >> >> >> >> export value >> >> >> >> end >> >> >> >> Using this in the REPL: >> >> julia> workspace() ; include("mike.jl") >> >> >> >> julia> using Foo >> >> >> >> julia> value(Foo.FooType()) >> >> "Foo::value" >> >> >> >> julia> using Bar >> >> Warning: using Bar.value in module Main conflicts with an existing >> >> identifier. >> >> >> >> julia> value(Bar.BarType()) >> >> ERROR: `value` has no method matching value(::BarType) >> >> >> >> # ----------------------------------------------------- >> >> >> >> julia> workspace() ; include("mike.jl") >> >> >> >> julia> using Foo >> >> >> >> julia> using Bar >> >> >> >> julia> value(Foo.FooType()) >> >> ERROR: `value` has no method matching value(::FooType) >> >> >> >> julia> value(Bar.BarType()) >> >> "Bar::value" >> >> >> >> # ----------------------------------------------------- >> >> >> >> julia> workspace() ; include("mike.jl") >> >> >> >> julia> using Bar >> >> >> >> julia> using Foo >> >> >> >> julia> value(Foo.FooType()) >> >> "Foo::value" >> >> >> >> julia> value(Bar.BarType()) >> >> ERROR: `value` has no method matching value(::BarType) >> >> >> >> julia>
