# Parametric function return type

**URL:** <https://discourse.julialang.org/t/parametric-function-return-type/103460>\
**Category:** New to Julia\
**Tags:** type, suggestions, parametric-types, function\
**Created:** [September 2, 2023, 2:15am UTC](https://discourse.julialang.org/t/parametric-function-return-type/103460 "2023-09-02T02:15:13Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![raythurnevoid](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raythurnevoid/32/52651_2.png) [@raythurnevoid](https://discourse.julialang.org/u/raythurnevoid)\
**Post date:** [September 2, 2023, 2:15am UTC](https://discourse.julialang.org/t/parametric-function-return-type/103460/1 "2023-09-02T02:15:13Z")

</div>

I wanted to create a function that takes in input a callback and can return its result while being able to tell Julia what’s going to be the return type (since the Function type is not parametric).

This is the skeleton at the moment:

```julia
function call_cb_if_needed(::Type{T}, cb::Function)::T where {T<:Any}
    # if some_condition
    # return some_value
    # else
    return cb()
end

call_cb_if_needed(Int, () -> 3)
# 3

```

This is a paradigm I’m taking with me from JS, I don’t know whether there’s a better way to achieve the same in Julia, but the fact that you can define a parametric Type as an argument of the function looks like it is not documented anywhere, thus I wanted to share it here for anyone that may find this useful.

Suggestions are welcome!

---

<div class="post-metadata">

**Author:** ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)\
**Post date:** [September 2, 2023, 5:06am UTC](https://discourse.julialang.org/t/parametric-function-return-type/103460/2 "2023-09-02T05:06:13Z")

</div>

I think this is covered by the manual:  
[https://docs.julialang.org/en/v1/manual/types/#man-typet-type](https://docs.julialang.org/en/v1/manual/types/#man-typet-type)  
Quote:  
“For each type `T` , `Type{T}` is an abstract parametric type whose only instance is the object `T` . Until we discuss [Parametric Methods](https://docs.julialang.org/en/v1/manual/methods/#Parametric-Methods) and [conversions](https://docs.julialang.org/en/v1/manual/conversion-and-promotion/#conversion-and-promotion), it is difficult to explain the utility of this construct, but in short, it allows one to specialize function behavior on specific types as _values_ .”

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [September 2, 2023, 8:23am UTC](https://discourse.julialang.org/t/parametric-function-return-type/103460/3 "2023-09-02T08:23:19Z")

</div>

This is quite confused as a post, TBH. IMO you shouldn’t mention caching in this post (you can edit the post to remove all references to caching/memoization) to prevent confusing people, but you could make a dedicated post to ask about that.

Regarding the function return type annotation, I’d suggest not to use it, instead just use type assertions in the function body (like `some_expression::T`, where `some_expression` is some expression and `T` is some type), if necessary at all. The problem with putting a return type on a function is that, unintuitively, it doesn’t just do a type assertion, rather it also does a `convert` if I remember correctly. Usually it doesn’t matter, but the feature seems like something that should be avoided out of principle.

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [September 2, 2023, 10:46am UTC](https://discourse.julialang.org/t/parametric-function-return-type/103460/4 "2023-09-02T10:46:17Z")

</div>

### caching

I’m not sure I fully understand your goal, but perhaps Memoize.jl is worth taking a look at:  
[https://github.com/JuliaCollections/Memoize.jl/](https://github.com/JuliaCollections/Memoize.jl/)

### type as argument

> the fact that you can define a parametric Type as an argument of the function looks like it is not documented anywhere, thus I wanted to share it here for anyone that may find this useful.

The concepts behind it are documented as greatpet mentions above, and it’s a pretty common pattern you’ll come across in a lot of Julia code, including base Julia itself. But thank you for taking the time to make a post about it, there’s always people new to the language, some of whom might learn about this pattern from this.

---

<div class="post-metadata">

**Author:** ![raythurnevoid](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raythurnevoid/32/52651_2.png) [@raythurnevoid](https://discourse.julialang.org/u/raythurnevoid)\
**Post date:** [September 2, 2023, 3:39pm UTC](https://discourse.julialang.org/t/parametric-function-return-type/103460/5 "2023-09-02T15:39:28Z")

</div>

I didn’t get the some\_expression thing, may you provide an example?

---

<div class="post-metadata">

**Author:** ![raythurnevoid](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raythurnevoid/32/52651_2.png) [@raythurnevoid](https://discourse.julialang.org/u/raythurnevoid)\
**Post date:** [September 2, 2023, 3:40pm UTC](https://discourse.julialang.org/t/parametric-function-return-type/103460/6 "2023-09-02T15:40:44Z")

</div>

I’ve seen it, but it didn’t look like what I wanted, I’m using the Serialization module to save the output of a long external process in a file, this function checks if the file exists and deserialize it instead of calling the CB (that just calls the external process)

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [September 2, 2023, 4:33pm UTC](https://discourse.julialang.org/t/parametric-function-return-type/103460/7 "2023-09-02T16:33:24Z")

</div>

Instead of, for example:

```julia
return_int_0(f)::Int = f()

```

… one could instead write (for type assertion):

```julia
return_int_1(f) = f()::Int

```

… or, something like (for conversion, also see `convert`):

```julia
return_int_2(f) = Int(f())

```

Note that `return_int_1` doesn’t do any conversion of the return value, so it will error if `f()` doesn’t return an `Int` value, even if the value is convertible to `Int`.

It may make sense to do both conversion and a type assertion in some cases, because conversion doesn’t imply an assertion (this is being reconsidered for v2).

---

<div class="post-metadata">

**Author:** ![raythurnevoid](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raythurnevoid/32/52651_2.png) [@raythurnevoid](https://discourse.julialang.org/u/raythurnevoid)\
**Post date:** [September 2, 2023, 7:36pm UTC](https://discourse.julialang.org/t/parametric-function-return-type/103460/8 "2023-09-02T19:36:57Z")

</div>

I see! Interesting. Yeah I feel a little bit annoyed by not being able to explicitly define the return type while avoiding the conversion, I have to manually write it in the function’s docs.

---

<div class="post-metadata">

**Author:** ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)\
**Post date:** [September 2, 2023, 9:34pm UTC](https://discourse.julialang.org/t/parametric-function-return-type/103460/9 "2023-09-02T21:34:16Z")

</div>

> [@nsajko](#):
>
> The problem with putting a return type on a function is that, unintuitively, it doesn’t just do a type assertion, rather it also does a `convert` if I remember correctly.

If the function is type-stable and will always return the same type anyway, the `convert` call will be optimized away. Also, if the expected return type is a user-defined struct type, and you know that there’s no conversion method that can turn other types into this user-defined type, then you don’t need to worry about `convert`. In such cases, there is no harm in annotating the return type, and it can help document the code.
