# Is there a reason \*\*\*not\*\*\* to explicitly define return types?

**URL:** <https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [November 1, 2024, 3:51pm UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142 "2024-11-01T15:51:40Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [November 1, 2024, 3:51pm UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/1 "2024-11-01T15:51:40Z")

</div>

Allow me to summarize the findings of my research so far:

- Julia is able to automatically infer the return type
- from: [Do you put return type in function definitions?](https://discourse.julialang.org/t/do-you-put-return-type-in-function-definitions/32120)

This is true, however I do not see that this is a reason to prefer not to explicitly define the return type for a function.

- Specifying the return type can result in a performance penalty
- from: [A function return type of `::AbstractArray{AbstractString}` causes a performance penalty?](https://discourse.julialang.org/t/a-function-return-type-of-abstractarray-abstractstring-causes-a-performance-penalty/122003)

Actually, this is not quite correct. The above linked post specifies the type of the return value _incorrectly_, and it is this _incorrectly specified return type which results in a type conversion taking place resulting in a performance penalty_. If the return type is specified incorrectly, we should not be surprised if runtime performance degrades. From this, I concluded that this is not a reason to not specify the return type.

- Julia does not dispatch on the return type
- from: [Multiple-dispatch depending on output type? - #3 by xiaodai](https://discourse.julialang.org/t/multiple-dispatch-depending-on-output-type/7639/3)

This is true, however I don’t _think_ that implies that the return type should not be specified. It is just a statement that Julia doesn’t dispatch on return types in the same way that it does dispatch on argument types.

# Possible advantages of including the return type information:

- Specifying the return type is a good way to provide documentation to users of your API (aka functions)

While it is possible to _write_ the type of the return value in a docstring, this does not have the same effect of using the type system to specify it, which is harder to ignore.

# A discussion about specifying the types of arguments to functions:

In contrast to the above, I do not think that the types of arguments to functions should be explicitly specified, because this _limits_ the scope of application for your algorithm (aka function). (But this could be behavior you want - see below.)

There are two exceptions to the above, as far as I can see:

## 1

- Multiple dispatch. If a function implementation should have different logic _depending_ on the type of the argument(s), then the types need to be specified.
- This is nothing new or special. It is simply a statement as to what _methods_ are in Julia. It’s just the multiple dispatch system.

## 2

- To restrict the range of types which can be used when calling a function
- To provide documentation to the user of your API

It seems kind of obvious that a generic algorithm (function implementation) will not work for all types.

For example, some function which performs math operations (like taking the `sin` of something, or something involving multiplications) is unlikely to be valid when a `DateTime` type is passed in.

You might argue in order to increase robustness and make it easier for clients to understand how to use your API, the type should be documented. Just as before, it would be better to document this information in the type system rather than a documentation comment, because it is harder to ignore.

This argument is very similar to the argument for specifying the return type.

Do consider there may be less obvious cases. For example, almost anything can be represented using a `String` type. You can serialize most things, and create most things by parsing a `String`. Things involving dates and durations can also be a bit tricky. What units of time should the duration be? Is it seconds? Something like `CompoundPeriod` or `Period`? If this code is close to some code which reads/writes to file, should the string representation of a duration be used?

* * *

Does anyone disagree with anything I have written here. I would be quite happy to be proven wrong if my reasoning is not sound…

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [November 1, 2024, 5:00pm UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/2 "2024-11-01T17:00:11Z")

</div>

It is strange that you propose to not specify input types and at the same time specify the output type.

How would you even define output type without knowing the inputs?

Or, do you propose to specify loose type boundaries? Like

```julia
square(A::AbstractMatrix)::AbstractMatrix = A * A
square(x::Number)::Number = x * x

```

In that case, I’m not sure if it’s useful in function header. In docstring? Yes. In doctest? Absolutely. Those are meant for humans. The header is for the compiler, and compiler does not need that information.

Another reason to not specify return types is “opaque types”. Basically, you specify properties which the return type would satisfy, not the type itself. Like, do you need to know exactly what `eachsplit` returns?

---

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [November 1, 2024, 5:07pm UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/3 "2024-11-01T17:07:24Z")

</div>

> [@Vasily\_Pisarev](#):
>
> It is strange that you propose to not specify input types and at the same time specify the output type.

~~You raise a good point. I should have been more explicit - let me edit my post because otherwise I agree it makes no sense.~~

I spoke too soon. I have two further points to make.

The point you raise I think is quite useful. I think this gives a concrete answer to the question.

- If you specify the types of (all) the input arguments then you should specify the return value, because it can be only one thing, so you might as well document it for your users
- ~~If you specify the return value you must specify the return type~~

The second bullet is not quite right. By specifying the return type what you are doing is adding a constraint which says

_whatever the input types are for this function, they must produce the type specified by the annotated return type after the operations specified by the logic of the function are completed_

Consider a simple example.

```julia
function convertToString(x)::String
    return String(x)
end

```

It is a trivial example, but what it says is `x` _can be anything, but after the logic contained inside_ `convertToString` _is applied to_ `x` _the return type must be a_ `String`.

So: you could pass any types to `convertToString`, and the specification of the return type will produce an error at runtime if the function doesn’t produce the correct type. This could be a useful error catching behavior just as limiting the possible function input types can be.

Feel free to tell me I am talking total nonsense if I am.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [November 1, 2024, 5:28pm UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/4 "2024-11-01T17:28:24Z")

</div>

The return type syntax is a feature with a very specific behavior. It adds a convert and an assert to all returns from the method body. You can use it if it’s that’s helpful for your methods! You can even choose to demand that folks use it in _your_ codebases to maintain a consistent style. But you can also decide it’s not universally helpful, and just use it in some places. For some methods it might only serve as line noise that just gets in the way of the important things you want to pay attention to.

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [November 1, 2024, 5:30pm UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/5 "2024-11-01T17:30:54Z")

</div>

It might be difficult to describe the return type as a function of the input types. Take the function,

```julia
f(x, y) = x * y

```

For numbers, the output will typically be a number, and for standard numbers it will have the type `promote_typeof(x,y)`, so it can be described in the header. But, then `f('a', 'b')` is a `String`, and so is `f("a", "b")`. How all this can be specified, I don’t see. Such things can happen whenever the method signature contains abstract types. You may not know how to write down the type of the output. So, perhaps if the signature only has concrete types it would be possible to write down the output type in a concise manner.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [November 1, 2024, 5:45pm UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/6 "2024-11-01T17:45:47Z")

</div>

> [@world-peace](#):
>
> explicitly define the return type for a function.

This is technically impossible. We can document that a function _should_ have a particular return type. We can annotate a method with a return type, but it only adds a `convert` and `typeassert` step, so if the type conversion fails, then we fail to return at all. We could annotate every method with the same return type, but nothing stops another method with a different or no annotation from being defined.

The reason return type annotations are used sparingly is because of how generic Julia is. All functions we can define are generic functions, it’s even printed that way. The most generic a return type annotation can get is to be a parameter that matches the annotated parameter of an argument, and that often isn’t flexible enough. More generic return types can instead be documented very loosely, with a description (“an iterable”) instead of a bona fide type.

A more useful case for designating a return type is for call signatures varying the callable, in other words various functions taking a particular set of concrete input types and returning the same concrete output type. There’s partial support for that in FunctionWrappers.jl, but there’s some rough edges there.

---

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [November 1, 2024, 5:57pm UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/7 "2024-11-01T17:57:37Z")

</div>

Great feedback - thanks!

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [November 1, 2024, 7:59pm UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/8 "2024-11-01T19:59:03Z")

</div>

I may have been too concise previously.

What I wanted to emphasize is, if you write a generic function, and often you do, you (aim to) write it in such a way that it’s compatible with some types you know of, and hopefully with some types other people designed you don’t know of, and with some types not even written yet. As such, you may not know in advance what the return type would be and how it is derived from the input types.

Even in a simple case `square(x) = x * x`  
You may think that

```julia
function square(x::T)::T where {T}
    return x * x
end

```

would be a correct definition, but let’s try

```julia
julia> using Unitful

julia> function square(x::T)::T where {T}
           return x * x
       end;

julia> square(1u"m")
ERROR: DimensionError: m and 1 m^2 are not dimensionally compatible. # Whoops!

```

So, basically, specifying return type only makes sense for methods with concrete input types. Once you go generic - there are simply too many edge cases.

---

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [November 1, 2024, 8:18pm UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/9 "2024-11-01T20:18:54Z")

</div>

I do agree with your points here. I also think it may be worth sharing a further thought I had which again compares two different contexts.

When you want to write some generic algorithm, you are often working with numerical types. Or at least, a group of closely related types which interop well together.

For example, integers and floating point numbers are “basically the same” if you are willing to accept a certain loss of precision in your calculations. I mean this in a _very loose sense_.

You may have algorithms which are generic across scalars, vectors, matrices, objects with even more abstract dimensions. All different types, but the algorithms are the same.

Contrast this to something which is much closer to what you might describe as _systems programming_. Here’s a random example, pulled from something I have been working on.

```julia
struct ConfigurationFile
    df::DataFrame
    date::Date
end

```

This type is not part of a collection of related types. It is a thing which exists entirely on its own.

It might have some functions to operate on the internal data. Possibly to serialize and deserialize, and such. In these cases the functions (“algorithms”) are (probably) not generalizable things. In some cases they _might_ be.

I thought it was probably worth raising the distinction between these two “domains” of programming.

Certainly it is the case that specializing many mathematical functions to `Float64` makes little sense.

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [November 1, 2024, 10:21pm UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/10 "2024-11-01T22:21:36Z")

</div>

> [@world-peace](#):
>
> incorrectly

U mena imprecisely?

---

<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:** [November 1, 2024, 10:41pm UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/11 "2024-11-01T22:41:08Z")

</div>

A related topic:

> [@On type annotations](https://discourse.julialang.org/t/on-type-annotations/116305):
>
> I wonder if there are any risks or issues with type annotations. In short, together with colleagues I am writing a coding standard. All Julia code at my company must be implemented following this standard. Some packages contain hundreds of structs. So it seems that annotating functions and variables is a good idea for readability and maintainability of code. The annotation guarantees that the variable will not change type as long as it lives. The type annotation of functions guarantees the retur…

> [@world-peace](#):
>
> Does anyone disagree with anything I have written here. I would be quite happy to be proven wrong if my reasoning is not sound…

Don’t want to be harsh, but it’s difficult to even extract meaning from your post. Too difficult to invest my time into it. It’s a bit like _stream of consciousness_ literature; it seems like several (too many) statements and questions are hiding there, but I don’t think any of them are clearly and completely stated. If I were you I’d open a new topic, with a simpler OP, with just one or two clearly stated questions, then open more threads later as necessary.

The core of the issue here was already addressed by Benny, I think, the false premise of the idea of “explicitly define the return type of a function”. It’s just not possible to do this currently in Julia. (Although it might be kinda possible in the near future, I think, if method sealing/freezing gets public. It’d allow one to prevent more methods being added to a function. A PR: [Allow freezing of `Core.MethodTables` by fatteneder · Pull Request #56143 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/56143))

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [November 1, 2024, 10:46pm UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/12 "2024-11-01T22:46:04Z")

</div>

Sure, in the domains where you work with “white-box” objects, specifying the return type adds some safety against unintentionally returning a wrong object. But maybe just a run of a static analysis tool like JET.jl before commit would suffice.

Judging by your other posts and reasoning, you come from Python background? The OO paradigm there is more suitable for what you propose in this thread, as you can basically annotate not the concrete type but the supertype interface of which you care about. In Julia, interfaces are not tied to types and even to type hierarchy. An example is Tables.jl interface. Because of that, you cannot express satisfying that interface in the type domain (not that everyone is happy about it, you may find here many topics requesting formal interfaces).

---

<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:** [November 1, 2024, 10:48pm UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/13 "2024-11-01T22:48:12Z")

</div>

> [@Vasily\_Pisarev](#):
>
> The OO paradigm there is more suitable for what you propose in this thread, as you can basically annotate not the concrete type but the supertype interface of which you care about. In Julia, interfaces are not tied to types and even to type hierarchy.

To be fair, “prefer composition over inheritance” is quite influential as a guideline in the “object-oriented” world.

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [November 1, 2024, 10:59pm UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/14 "2024-11-01T22:59:51Z")

</div>

> [@nsajko](#):
>
> To be fair, “prefer composition over inheritance” is quite influential as a guideline in the “object-oriented” world.

I meant that Python type hint might specify ABC, not the concrete object type, and a class may inherit from multiple ABCs (probably? not 100% sure).

---

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [November 2, 2024, 9:27am UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/15 "2024-11-02T09:27:47Z")

</div>

> [@xiaodai](#):
>
> > [@world-peace](#):
> >
> > incorrectly
> 
> U mena imprecisely?

No, it’s not correct, because the vector does not contain `AbstractString`. It contains `String`.

I am making this statement from the point of view of considering what is written to the computer memory. You can’t write an abstract type to memory.

This is why I say it is _incorrect_. The function returns a `Vector` containing _only_ `String`s. It doesn’t return a `Vector` containing multiple types, the union of which is represented by `AbstractString`.

(Don’t worry too much about English semantics here.)

* * *

We could consider a simpler example.

```julia
v::Vector{Union{Int64, Float32}} = []
push!(v, 1)
push!(v, Float32(1.1))

```

What does the compiler does when it writes this data to memory? It must do two things:

- Decide on a static size for `Union{Int64,Float32}` so that it can do indexing in O(1) time. (`memory_index = sizeof_element * element_index`)
- Write some additional information (as part of each element of the vector) to track what the type of each element in each index of the vector is at runtime.

If you know a bit of OOP, most OOP languages do something similar where they write some information (usually a pointer address) which references a vtable. The vtable exists to figure out how to handle function calls on the object.

I don’t think Julia uses vtables, because it does multiple dispatch, not single dispatch.

* * *

All of this is to say that if I only write elements of the type `Float32` to `v`, then it is a mistake of the programmer to specify the type of `v` as `Union{Int64, Float32}}`.

I know that was a bit of a tangent, but I think it’s useful to consider something about the structure of what the compiler actually writes into memory.

---

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [November 2, 2024, 9:34am UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/16 "2024-11-02T09:34:54Z")

</div>

> [@Vasily\_Pisarev](#):
>
> Judging by your other posts and reasoning, you come from Python background?

I was a C++ developer for a long time, then worked with Rust for a bit before gradually moving over to Python. I know a bit about the internals of CPython, but I would not say I am an expert by any means. I know more about Rust and C++.

I guess you are thinking something along the lines of using `typeguard` in Python to achieve a similar thing?

> [@Vasily\_Pisarev](#):
>
> as you can basically annotate not the concrete type but the supertype interface of which you care about

This is a good point. Perhaps annotating `::String` as a return type makes little sense if you have an interface for it. `::AbstractString`.

> [@nsajko](#):
>
> The core of the issue here was already addressed by Benny, I think, the false premise of the idea of “explicitly define the return type of a function”. It’s just not possible to do this currently in Julia.

To clarify one thing - the intention was not to use annotated return types to get different dispatch, but to enforce some kind of correctness while getting documentation for free. Not sure if you interpreted my post as the former rather than the latter?

---

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [November 2, 2024, 10:02am UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/17 "2024-11-02T10:02:44Z")

</div>

> [@world-peace](#):
>
> > [@Vasily\_Pisarev](#):
> >
> > as you can basically annotate not the concrete type but the supertype interface of which you care about
> 
> This is a good point. Perhaps annotating `::String` as a return type makes little sense if you have an interface for it. `::AbstractString`.

Ah. I’ve realized there’s a problem with what I have suggested here.

It’s the same example as before.

~~If you annotate with an abstract type, because you want to return an _interface_, then you degrade performance.~~

```julia
function myFunction()::AbstractString
    s::String = "hello world"
    return s
end

# my_s is an AbstractString, not a String, so performance
# will degrade
my_s = myFunction()

julia> typeof(my_s)
String

```

… what, _ **what?!** _

```julia
function myFunction2()::Vector{AbstractString}
    v::Vector{String} = ["hello", "world"]
    return v
end

my_v = myFunction2()

julia> typeof(my_v)
Vector{AbstractString}

```

What is going on here? In the first example, it seems like the compiler is smart enough to figure out that it should compile `myFunction()` for a return type of `String`, which is a subtype of the “interface type” `AbstractString`.

In the second example, it isn’t smart enough to figure out that it should compile `myFunction2` for a return type of `Vector{String}`, instead it returns `Vector{AbstractString}` along with all the performance penalties of this.

- Why does this happen?
- Is it because `Vector` is mutable, whereas `String` is not?

I guess the compiler cannot guarantee that after returning `Vector{String}` there is not going to be a line of code like

```julia
# MyStringType<:AbstractString
my_string::MyStringType = MyStringType("weird encoding")
push!(v, my_string)

```

which follows afterwards.

---

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [November 2, 2024, 10:09am UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/18 "2024-11-02T10:09:25Z")

</div>

I’m fairly confident this is related

```julia
julia> String<:AbstractString
true

julia> Vector{String}<:Vector{AbstractString}
false

```

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [November 2, 2024, 10:11am UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/19 "2024-11-02T10:11:01Z")

</div>

> [@world-peace](#):
>
> In the second example, it isn’t smart enough to figure out that it should compile `myFunction2` for a return type of `Vector{String}`, instead it returns `Vector{AbstractString}` along with all the performance penalties of this.
> 
> - Why does this happen?

Simple because you said so, i.e., the signature required it to return `Vector{AbstractString}`. The compiler will not try to narrow the type based on anything that could have happened afterwards.

If you instead define `myFunction2()::Vector{<:AbstractString}` the return type will simply be `Vector{String}` as this is the concrete type matching the annotation. Again, the compiler does not care what you do to the value afterwards, e.g, `push(my_v, @view "Ha"[1:1])`.

---

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [November 2, 2024, 10:14am UTC](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142/20 "2024-11-02T10:14:36Z")

</div>

Ah yes, that’s making sense.

I tried this too, but for some reason this doesn’t compile?

```julia
function myFunction3()::Vector{T} where T<:AbstractString
    v::Vector{String}=["hi","there"]
    return v
end

julia> v3 = myFunction3()
ERROR: UndefVarError: `T` not defined in static parameter matching
Suggestion: run Test.detect_unbound_args to detect method arguments that do not fully constrain a type parameter.

```

* * *

Also, as you pointed out:

```julia
julia> Vector{String}<:Vector{<:AbstractString}
true

```

[Next page](https://discourse.julialang.org/t/is-there-a-reason-not-to-explicitly-define-return-types/122142.md?page=2)
