# Types and arguments

**URL:** <https://discourse.julialang.org/t/types-and-arguments/121612>\
**Category:** New to Julia\
**Tags:** type, argument\
**Created:** [October 22, 2024, 8:45pm UTC](https://discourse.julialang.org/t/types-and-arguments/121612 "2024-10-22T20:45:54Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![martin\_sanchez](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/martin_sanchez/32/207525_2.png) [@martin\_sanchez](https://discourse.julialang.org/u/martin_sanchez)\
**Post date:** [October 22, 2024, 8:45pm UTC](https://discourse.julialang.org/t/types-and-arguments/121612/1 "2024-10-22T20:45:54Z")

</div>

I have a doubt. Sorry if is very obvious. First: is the type specification used as a cast? For example, if f receives a real number as argument, is

```julia
a=2
f(a::Real) 

```

doing a type conversion? And a second doubt is: can’t I specify an argument as a subtype of others?

```julia
g(z<:Integer, x<:AbstractFloat)

```

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [October 22, 2024, 8:53pm UTC](https://discourse.julialang.org/t/types-and-arguments/121612/2 "2024-10-22T20:53:59Z")

</div>

> [@martin\_sanchez](#):
>
> doing a type conversion?

No. All objects in julia have a concrete type, there is no conversion happening.

> [@martin\_sanchez](#):
>
> can’t I specify an argument as a subtype of others?
> 
> ```julia
> g(z<:Integer, x<:AbstractFloat)
> 
> ```

If you don’t need the actual type of `z` in the function, this is just ` g(z::Integer, x::AbstractFloat)` . You can call this with any object whose type is a subtype of integer (like ` Int8` , for example) in the first argument, and any object whose type is a subtype of `AbstractFloat` (like `Float16`, for example) in the second argument.

If you need direct access to the type of an object, you can also use `g(z::I, x::F) where {I <: Integer, F <: AbstractFloat}`. This allows you to use `I` and `F` (the types of each argument) directly in the function.

---

<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:** [October 22, 2024, 9:38pm UTC](https://discourse.julialang.org/t/types-and-arguments/121612/3 "2024-10-22T21:38:11Z")

</div>

> [@Sukera](#):
>
> All objects in julia have a concrete type, there is no conversion happening.

tbf, type annotations do cause conversions in different contexts, and it takes some reading to grok what they do where. It might be understandably confusing that the annotations in the definition `function f(a::Real) ... end` and the call `f(a::Real)` don’t do the same things at all, and it’s worth making that distinction in method signatures for newcomers. The wording “cast” makes me think there might be an expectation borne from experience in another language, but I can’t recall a language that annotates arguments at call sites often.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [October 22, 2024, 10:41pm UTC](https://discourse.julialang.org/t/types-and-arguments/121612/4 "2024-10-22T22:41:22Z")

</div>

> [@Benny](#):
>
> The wording “cast” makes me think there might be an expectation borne from experience in another language, but I can’t recall a language that annotates arguments at call sites often.

If you define a function `double foo(double x)` in C or C++, and call it with an integer argument ala `foo(1)`, the language will automatically cast it to `double`.

Whereas if you define a method `foo(x::Float64) = ...` in Julia, it will _only_ accept `Float64` arguments, and trying to call `foo(1)` (or any other numeric type) will throw a `MethodError` (unless another `foo` method exists for that type).

Argument-type declarations in Julia are best thought of as “filters” — saying what arguments are allowed for that method — rather than as directions on how to compile the code. If you define `foo(x::Real) = ...`, then it will accept any subtype of `Real` as an argument (integers, floating-point, rationals, …), but the compiler will still generate specialized code for each concrete argument type that you call `foo` with.

See also [Argument-type declarations](https://docs.julialang.org/en/v1/manual/functions/#Argument-type-declarations) in the Julia manual.

---

<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:** [October 22, 2024, 10:59pm UTC](https://discourse.julialang.org/t/types-and-arguments/121612/5 "2024-10-22T22:59:40Z")

</div>

> [@stevengj](#):
>
> trying to call `foo(1)`

I read the post as the call being `foo(a::Real)`, which is a type assertion (not conversion) prior to the call, but I think I misread that now.

It’s also probably worth pointing out that concrete (instantiable) types in Julia do not subtype each other, so they only subtype (and supertype a few special) abstract types. Conversions with a target abstract type cannot result in an instance of an abstract type, but some concrete subtype `convert(Real, 1) == 1`.
