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>

Reply via email to