This seems to be an unnecessarily obfuscated implementation of typeof.
Julia already knows how to deal with `typeof(x[j])` very efficiently, while
it doesn't understand any of `typeof(x).parameters[j]`, or
`T.parameters[j]`, or `t::T=x` particularly well.


On Mon, Oct 5, 2015 at 7:17 AM <[email protected]> wrote:

> Thanks Thomas so we can modify Glen's code as:
>
> function mycode3{T}(x...;t::T=x)
>     for j=1:length(x)
>       println(typeof(x[j])<:T.parameters[j])
>     end
> end
>
> and mycode3(2, 4., 4 + 5im, 4. + 2im) will print:
>
> true
> true
> true
>
>
> On Monday, October 5, 2015 at 11:56:54 AM UTC+1, Tomas Lycken wrote:
>>
>> In this case, typeof(x[j]) is probably preferable, but if you have
>> access only to the type and not the values, you can also use
>> T.parameters[j] to the same end.
>>
>> // T
>>
>> On Monday, October 5, 2015 at 12:53:36 PM UTC+2, data.pu…@gmail.com
>> wrote:
>>
>> I see we can do typeof(x[j])
>>>
>>> On Monday, October 5, 2015 at 11:51:20 AM UTC+1, [email protected]
>>> wrote:
>>>>
>>>> Sorry, I ran your code and got an error so assumed it wouldn't work,
>>>> but I think I see your point. If we modify it a bit:
>>>>
>>>> function mycode2{T}(x...;t::T=x)
>>>>     for j=1:length(x)
>>>>       println(x[j])
>>>>     end
>>>>     println(T)
>>>>   return(T)
>>>> end
>>>>
>>>> This: mycode2(2, 4., 4 + 5im, 4. + 2im) returns:
>>>>
>>>> Tuple{Int64,Float64,Complex{Int64},Complex{Float64}}
>>>>
>>>> and prints the correct values. So how do I access the types in Tuple{}
>>>> since T[i] will give errors?
>>>>
>>>> On Monday, October 5, 2015 at 11:31:06 AM UTC+1, Glen O wrote:
>>>>>
>>>>> 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
>>>>>>>
>>>>>> ​
>>
>

Reply via email to