I think dropping generic functions which clash is the safest way, as Stefan suggests in 4345. Consider
In someone elses package: module OtherDev export foo foo(x::String) = 1 end In my package: module MyMod export foo foo(x::Number) = 2 end Some 3rd person uses both in her code: using OtherDev using MyMod a = foo(4.59) Sometime later OtherDev decides to update his module: module OtherDev export foo foo(x::String) = 1 foo(x::Float64) = 3 end This would be a hard bug for person 3 to find. Thus person 3 should be forced to write his code: using OtherDev using MyMod a = MyMod.foo(4.59) On Tue, 2015-01-13 at 21:28, Petr Krysl <[email protected]> wrote: > I think your explanation makes sense. But: > > Consider that the two modules may be due to two independent developers. A > third guy (me) wishes to use both modules. Why should it be prohibited to > have the two "using" define a single generic function foo with two methods > (provided they can be disambiguated)? > > I think the discussion at 4345 was about the tricky nature of "merging" the > definitions of the generic functions. But it seems to me it is only tricky > when the arguments do not allow for the compiler to distinguish between > them. In that case the compiler should complain or reject the definitions > (whichever is practicable), but otherwise it should be done for uniformity. > > See, when A defines a foo, and B and C import A.foo and re-export it, there > are no guarantees that the foo's are somehow related. They could still > implement entirely different (separate) concepts, which could both be > different from the concept that the original foo was designed to handle. > > P > > On Tuesday, January 13, 2015 at 12:06:47 PM UTC-8, Mauro wrote: >> >> Is this problem not more related to issue >> https://github.com/JuliaLang/julia/issues/2327 ? >> >> The way it works is thus: If you make a method in a module, say >> >> module A >> export foo >> foo() = 1 >> end >> >> This will create a new generic function foo with one method in it. >> Now do the same in another module: >> >> module B >> export foo >> foo(x) = x >> end >> >> This defines another generic function, of the same name foo, with a >> method in it. Now doing >> >> using A >> using B >> >> Will result in the generic function foo from module B being 'used', >> i.e. the binding of the symbol foo points to B.foo and not to A.foo >> anymore. So, essentially generic functions do not get merged which is >> what I think you expect to happen. >> >> The way to solve your problem is to define foo in some other module and >> import it to A and B >> >> module U >> export foo >> foo() = error("to be specified later") >> >> module A >> import ..U >> U.foo() = 1 >> end >> module B >> import ..U >> U.foo(x) = x >> end >> >> end >> >> using U >> methods(foo) >> >> now shows both methods: >> >> # 2 methods for generic function "foo": >> foo() at none:7 >> foo(x) at none:11 >> >> >> On Tue, 2015-01-13 at 17:22, Petr Krysl <[email protected] <javascript:>> >> wrote: >> > I have a trouble following the reasoning in the 4345 issues trail. >> > >> > If a module defines a method (let us say "count") and brings in into an >> > environment that already has a method for the function count(), both are >> > available provided there signatures allow for the compiler to >> distinguish >> > between them to decide which one to call. >> > >> > I already have a situation like this in my code: I have two modules that >> > define the function count(), and they export that function count() >> and >> > in the main there are already two methods count().. >> > >> > julia> methods(count) >> > # 4 methods for generic function "count": >> > count(pred::Union(Function,Func{1}),a::AbstractArray{T,N}) at >> reduce.jl:436 >> > count(pred::Union(Function,Func{1}),itr) at reduce.jl:426 >> > count{T<:FESet}(me::T<:FESet) at >> > C:\Users\pkrysl\Documents\GitHub\JFinEALE.jl\src\FESetModule.jl:32 >> > count(self::FENodeSet) at >> > C:\Users\pkrysl\Documents\GitHub\JFinEALE.jl\src\FENodeSetModule.jl:47 >> > >> > The two methods that failed to get both exported are (it appears) in >> > precisely the same situation, except that the main module does not >> have >> > any definition of a method with the same name: >> > >> > julia> methods(JFinEALE.HeatDiffusionAlgorithmModule.steadystate) >> > # 1 method for generic function "steadystate": >> > >> steadystate(algo::HeatDiffusionAlgorithm,modeldata::Dict{ASCIIString,Any}) >> > at C:\Users\pkrysl\Documents\GitHub >> > \JFinEALE.jl\src\HeatDiffusionAlgorithmModule.jl:83 >> > >> > julia> methods(JFinEALE.AcousticsAlgorithmModule.steadystate) >> > # 1 method for generic function "steadystate": >> > steadystate(algo::AcousticsAlgorithm,modeldata::Dict{ASCIIString,Any}) >> at >> > C:\Users\pkrysl\Documents\GitHub\JFi >> > nEALE.jl\src\AcousticsAlgorithmModule.jl:85 >> > >> > As you can see, the compiler should be able to decide which of these >> > methods to call as they get passed arguments of different types.. >> > >> > So,, this succeeds: >> > >> > include("FESetModule.jl") >> > using JFinEALE.FESetModule >> > ... >> > export count >> > .... >> > >> > include("FENodeSetModule.jl") >> > using JFinEALE.FENodeSetModule >> > ... >> > export count >> > >> > and this fails >> > >> > include("AcousticsAlgorithmModule.jl") >> > using JFinEALE.AcousticsAlgorithmModule >> > export AcousticsAlgorithm >> > export steadystate >> > >> > include("HeatDiffusionAlgorithmModule.jl") >> > using JFinEALE.HeatDiffusionAlgorithmModule >> > export HeatDiffusionAlgorithm >> > export steadystate >> > >> > I find this strange and inconsistent. Could someone please explain >> > whether this is something I should fix up at my end or that this is a >> > problem with the logic of the programming language.. >> > >> > Petr >> > >> > On Monday, January 12, 2015 at 11:24:07 PM UTC-8, Ivar Nesje wrote: >> >> >> >> New method definitions will replace the previous definition. >> >> >> >> If you put the function in a module and bring them into you scope with >> >> using/importall, you'll run into >> >> https://github.com/JuliaLang/julia/issues/4345, which can be >> considered >> >> either a bug or a missing feature. >> >>
