[julia-users] Re: Function in module templated on types defined later

2016-06-20 Thread Fengyang Wang
This can't work because it would not, for instance, make sense to use 
module `M` independently. You could use the parent module from `M`, but as 
it stands that won't work either because loading the parent module will try 
to use `f` from `M`. What are you trying to do?

On Monday, June 20, 2016 at 8:06:11 AM UTC-4, ami...@gmail.com wrote:
>
> Hi,
>
> module M
> function f{T1}(x::T1) return x.a end
> function f{T2}(x::T2) return x.b + 1 end
> export f
> end
>
> using M
> type T1 a::Float64 end
> type T2 b::Float64 end
> t1 = T1(1.0)
> t2 = T2(2.0)
> println(f(t1))
> println(f(t2))
>
> This code doesn't work, how can I force the function templated for T1 to 
> be used when calling f(t1)?
> Many thanks,
>


[julia-users] Re: Function in module templated on types defined later

2016-06-20 Thread amiksvi
Thanks to both of you for the replies.

Module M contains a lot of functions for the simulation of dynamical 
models. Outside M, users are required to define some specific types to be 
consistent with another historical project. The definition of these types 
should be kept as simple as possible, this may look a bit odd, but forcing 
the user to define a type T1 <: AT1 is already too much, which is why 
Mauro's suggestion is not an option for me (but thanks anyway for the 
proposal!).

And the tricky thing is that T1 and T2 can't be initialized before the 
module, so I can't do:

type T1 a::Float64 end
type T2 b::Float64 end

module M
import Main.T1, Main.T2
function f(x::T1) return x.a end
function f(x::T2) return x.b + 1 end
export f
end

using M
t1 = T1(1.0)
t2 = T2(2.0)
println(f(t1))
println(f(t2))

which works. If there is no solution similar to the first code I proposed, 
I think I'll simply use two different names such as f1(x::T1) and f2(x::T2) 
in M. But new suggestions are still highly appreciated :)

Many thanks.



Re: [julia-users] Re: Function in module templated on types defined later

2016-06-20 Thread Mauro
In that case, you need traits.  In fact the motivating example I gave in
my JuliaCon talk on this subject last year matches yours almost exactly:
https://youtu.be/j9w8oHfG1Ic

Anyway, probably you want to hand-code the Holy-traits.  The example I
give in my talk modified to fit your example:

module M
   export f, Trait1, Trait2
   type Trait1 end
   type Trait2 end
   # this function does the grouping:
   function traitfn end

   # now define function f which should dispatch on those traits:
   f(x) = _f(x, traitfn(x)) # wrapper
   _f(x, ::Type{Trait1}) = x.a   # logic for Trait1
   _f(x, ::Type{Trait2}) = x.b+1   # logic for Trait2
end
using M

type T1 a::Float64 end
type T2 b::Float64 end

# now manually add your types to Trait1 or Trait2
M.traitfn(::T1) = Trait1
M.traitfn(::T2) = Trait2

t1 = T1(1.0)
t2 = T2(2.0)
println(f(t1))
println(f(t2))

Note, that the packages I mention in my talk are currently not
maintained but should work for Julia 0.4.  But I may not have time to
udate them for 0.5.

On Mon, 2016-06-20 at 18:53, amik...@gmail.com wrote:
> Thanks to both of you for the replies.
>
> Module M contains a lot of functions for the simulation of dynamical models.
> Outside M, users are required to define some specific types to be consistent
> with another historical project. The definition of these types should be kept
> as simple as possible, this may look a bit odd, but forcing the user to define
> a type T1 <: AT1 is already too much, which is why Mauro's suggestion is not 
> an
> option for me (but thanks anyway for the proposal!).
>
> And the tricky thing is that T1 and T2 can't be initialized before the module,
> so I can't do:
>
> type T1 a::Float64 end
> type T2 b::Float64 end
>
> module M
> import Main.T1, Main.T2
> function f(x::T1) return x.a end
> function f(x::T2) return x.b + 1 end
> export f
> end
>
> using M
> t1 = T1(1.0)
> t2 = T2(2.0)
> println(f(t1))
> println(f(t2))
>
> which works. If there is no solution similar to the first code I proposed, I
> think I'll simply use two different names such as f1(x::T1) and f2(x::T2) in 
> M.
> But new suggestions are still highly appreciated :)
>
> Many thanks.