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]
> <javascript:>> 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>
>