# Eltype and dimensions from function definition

**URL:** <https://discourse.julialang.org/t/eltype-and-dimensions-from-function-definition/78374>\
**Category:** General Usage\
**Created:** [March 24, 2022, 8:27am UTC](https://discourse.julialang.org/t/eltype-and-dimensions-from-function-definition/78374 "2022-03-24T08:27:01Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![andreasvarga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andreasvarga/32/11634_2.png) [@andreasvarga](https://discourse.julialang.org/u/andreasvarga)\
**Post date:** [March 24, 2022, 8:27am UTC](https://discourse.julialang.org/t/eltype-and-dimensions-from-function-definition/78374/1 "2022-03-24T08:27:01Z")

</div>

I would like to use a matrix function as basis for defining more complex structures. For this, I need to determine cheaply the `eltype` of the result and the dimensions. To be concrete, I have a matrix function defined as

```julia
julia> a(t) = [cos(t) sin(t); 1 -1]
a (generic function with 1 method)

```

and I would like to find out `eltype(a(t))` and `size(a(t))` without evaluating `a(t)` for a certain real value of` t`. Is this somehow possible?

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [March 24, 2022, 8:48am UTC](https://discourse.julialang.org/t/eltype-and-dimensions-from-function-definition/78374/2 "2022-03-24T08:48:58Z")

</div>

If `t` is a subtype of `Real` and `a(t)` evaluates a trigonometric function then the resulting matrix will have entries that are a subtype of `AbstractFloat`, and the specific `eltype(a(t))` ought to be the same as `typeof(float(t))`.  
When you are asking about size(a(t)), if you do not know about `a(t)` then you do not know about it.

---

<div class="post-metadata">

**Author:** ![andreasvarga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andreasvarga/32/11634_2.png) [@andreasvarga](https://discourse.julialang.org/u/andreasvarga)\
**Post date:** [March 24, 2022, 9:03am UTC](https://discourse.julialang.org/t/eltype-and-dimensions-from-function-definition/78374/3 "2022-03-24T09:03:28Z")

</div>

Thanks. I thought that since `a(t)` evaluates to a 2x2 matrix, this information is somehow coded in the definition of the function `a(t)`. So, my hope was to have a way to extract this information somehow.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [March 24, 2022, 9:14am UTC](https://discourse.julialang.org/t/eltype-and-dimensions-from-function-definition/78374/4 "2022-03-24T09:14:52Z")

</div>

Normal functions don’t have return types in Julia, the return type is just the type of whatever is returned.

Maybe there’s a package that makes something like this, you could even define it yourself:

```julia
struct TypedFunction{T} <: Function
    f
end

(f::TypedFunction)(args...) = f.f(args...)

return_type(::TypedFunction{T}) where {T} = T

f = TypedFunction{Float64}(sin)

```

But I’m not sure how much benefit there is to be extracted from doing this.

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [March 24, 2022, 9:39am UTC](https://discourse.julialang.org/t/eltype-and-dimensions-from-function-definition/78374/5 "2022-03-24T09:39:18Z")

</div>

> [@gustaphe](#):
>
> But I’m not sure how much benefit there is to be extracted from doing this.

I like that (although I’m not sure I’d use it). Examples (showing why there probably is no builtin solution to OP’s question and showing how `TypedFunction` could increase type stability

```julia
a(t) = t < 0 ? [1, 2] : [1 2]
@show a(-1), typeof(a(-1))
@show a(1), typeof(a(1))

struct TypedFunction{T} <: Function
    f
end

(f::TypedFunction{T})(args...) where T = convert(T, f.f(args...))

return_type(::TypedFunction{T}) where {T} = T

ta = TypedFunction{Vector{Float64}}(a)
@show ta(-1)
@show ta(1)

```

yielding

```julia
(a(-1), typeof(a(-1))) = ([1, 2], Vector{Int64})
(a(1), typeof(a(1))) = ([1 2], Matrix{Int64})
ta(-1) = [1.0, 2.0]
ERROR: MethodError: no method matching Vector{Float64}(::Matrix{Int64})

```

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [March 24, 2022, 9:44am UTC](https://discourse.julialang.org/t/eltype-and-dimensions-from-function-definition/78374/6 "2022-03-24T09:44:35Z")

</div>

```julia
julia> Base.return_types(a, (Float64,))
1-element Vector{Any}:
 Matrix{Float64} (alias for Array{Float64, 2})

```

Note that `Base.return_types` is an internal function so use at your own risk.

---

<div class="post-metadata">

**Author:** ![andreasvarga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andreasvarga/32/11634_2.png) [@andreasvarga](https://discourse.julialang.org/u/andreasvarga)\
**Post date:** [March 24, 2022, 9:52am UTC](https://discourse.julialang.org/t/eltype-and-dimensions-from-function-definition/78374/7 "2022-03-24T09:52:50Z")

</div>

Actually, I could reformulate my question to matrices which have constant dimensions. In my case, they are also periodic of a known period `T`, i.e.,  
`a(t) = a(t+T)` .
