I'll admit, I didn't entirely follow what you're trying to do, but based on
what I was able to see, is there any reason why my last suggestion wouldn't
work? I'll copy it here:
function mycode{T}(x...;t::T=x)
for j=1:length(x)
println(typeof(x[j])<:T[j])
end
end
By making t take the value of x, you are allowing t to have the same "type"
as x - namely, a tuple containing the input arguments. Then, by having
t::T, it makes T hold their types. And because it's a keyword argument, it
can be placed after x..., and doesn't need to be input at all, because it's
defaulted to x. It certainly satisfies the requirements you put forward in
your original question.
On Monday, 5 October 2015 18:30:48 UTC+10, [email protected] wrote:
>
> Hi Glen,
>
> Perhaps in my previous email when I wrote:
>
> f(1, 2, 3) rather than f((1, 2 , 3))
>
> I should have written something like f(1, 2.3, 5 + 3.im, 3 + 1im,
> Nullable{Float64}(5.)) to make it explicit that I would like to parametrise
> different types. I think David Gold's suggestion is the closest to what I
> want but doesn't quite solve the problem. If I wanted to lift a set of
> Julia's functionality to new types having an arbitrary set of input types,
> I could:
>
> 1. Spend alot of time writing code to parse different subsets of modules.
> This would take an immense amount of work and the libraries would
> inevitably change.
> 2. If we could model a variadic template function having the semantics as
> I specified previously:
>
> function {T...}my_fun(x...)
> for i in 1:length(x)
> println(typeof(x[i]) <: T[i])
> end
> end
>
> The above function for simplicity. Here T... are the types of x... and
> they could be all different or the same
>
> We could lift functionality of all the relevant function in one go with a
> sketch implementation like:
>
> # Import the functions ...
> import Base: get, +, -, /, *, ^, ...
>
> # Function symbols to be lifted
> funs = [:+, :-, ...]
>
> # Generic get function
> # Assume appropriate get functions are written for each type
> function get{T}(x::T)
> x
> end
>
> # My new type is T1{T}()
>
> S = Union{Symbol, Expr}
>
> # My lifter function
> function lift(fun_name::S, new_type::S)
> quote
> function $fun_name{T...}(x...)
> y = Array(Any, length(x))
> for i in 1:length(x)
> y[i] = get(i)
> end
> ret = $fun_name(y...)
> U = typeof(ret)
> return $new_type{U}(ret)
> end
> end
> end
>
> # Then lift the functions
> for i in funs
> eval(lift(i, :T1))
> end
>
> Could then do T1(3.4) + 9 and so on for all the functions regardless of
> number of arguments return type etc
>
> DP
>
>
>
>
>
> On Monday, October 5, 2015 at 7:20:55 AM UTC+1, Glen O wrote:
>>
>> Just to be clear, are you looking for something that will parameterise
>> across a variety of types, or are you wanting to restrict to a single type?
>>
>> If the latter, it can be easily done with
>>
>> function mycode{T}(x::T...)
>> <code here>
>> end
>>
>> which will make all values in the varargs list the same. To restrict to a
>> specific subset, there's also
>>
>> function mycode(x::Union(Int,Array)...)
>> <code here>
>> end
>>
>> which will require that the arguments in x be either Ints or Arrays (and
>> can have both).
>>
>> If you're actually after the former, is there a reason why you can't just
>> ask for typeof(x[i]), directly? Alternatively, would this work?
>>
>> function mycode{T}(x...;t::T=x)
>> for j=1:length(x)
>> println(typeof(x[j])<:T[j])
>> end
>> end
>>
>