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. 
>
>

Reply via email to