# Array basics

**URL:** https://discourse.julialang.org/t/array-basics/55919
**Category:** New to Julia
**Created:** [February 24, 2021, 8:33am UTC](https://discourse.julialang.org/t/array-basics/55919 "2021-02-24T08:33:20Z")
**Posts on this page:** 18
**Page:** 1

<div class="post-metadata">

### Author: ![AlexanderChen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexanderchen/32/22007_2.png) [@AlexanderChen](https://discourse.julialang.org/u/AlexanderChen)
#### Post date: [February 24, 2021, 8:33am UTC](https://discourse.julialang.org/t/array-basics/55919/1 "2021-02-24T08:33:21Z")

</div>

Hi,

In Haskell when you declare a function you are expected to say before hand what you expect as input and output for instance [Integers] → Integer. How does one do this is Julia. I am no Haskell expert by any strech but I really like the discipline. Partly because i miss that my code is starting to get sloppy.  
For instance:

`b` and `e` are inputs that look like this :source or :type. Its the annotation used by Metagraphs to denote different metadata parts of a node or vertix. Its is not a Symbol.

```julia
function get_metadata(g::AbstractMetaGraph, l::Array,b,e)
    meta_list = []
    for i in 1:nv(g)
        if isin(l,get_prop(g,i,b))
           push!(meta_list,get_prop(g,i,e))
        else
            nothing
        end
    end
    return meta_list
end

```

1. How can I check the type julia has given this? And how, in this particular case can I specify it?
2. The output is an array of elements that are infact always Integers. How do I specify that instead of getting `any`? Do I do that here or at the moment I add the metadata to a node?  
3)is there documentation or a book specific to julia, which shows the way how you structure this discipline inside of Julia?

```julia
julia> B
3-element Array{Any,1}:
  7
 20
 24

```

---

<div class="post-metadata">

### Author: ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)
#### Post date: [February 24, 2021, 8:41am UTC](https://discourse.julialang.org/t/array-basics/55919/2 "2021-02-24T08:41:26Z")

</div>

You are instantiating

```julia
meta_list = []

```

which will create an array of type `Any`:

```julia
julia> []
Any[]

```

If you know `meta_list` will only hold integers, you should instantiate accordingly:

```julia
meta_list = Int[]

```

---

<div class="post-metadata">

### Author: ![AlexanderChen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexanderchen/32/22007_2.png) [@AlexanderChen](https://discourse.julialang.org/u/AlexanderChen)
#### Post date: [February 24, 2021, 8:48am UTC](https://discourse.julialang.org/t/array-basics/55919/3 "2021-02-24T08:48:48Z")

</div>

thanks that is one problem down 🙂

---

<div class="post-metadata">

### Author: ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)
#### Post date: [February 24, 2021, 9:09am UTC](https://discourse.julialang.org/t/array-basics/55919/4 "2021-02-24T09:09:30Z")

</div>

> [@AlexanderChen](#):
>
> In Haskell when you declare a function you are expected to say before hand what you expect as input and output for instance [Integers] → Integer. How does one do this is Julia.

Here you go

```julia
function myfunc(a::Float64,b::Int64)::Float64
    return a + b
end

```

But it’s much more fun when you do not tell Julia what the types are. Then you can do wonderful things like this

```julia
julia> function myfunc2(a,b)
           return a * b
       end
myfunc2 (generic function with 1 method)

julia> myfunc2("hello ","world")
"hello world"

julia> myfunc2(3,5)
15

julia> myfunc2([4,5,6],3)
3-element Array{Int64,1}:
 12
 15
 18

julia> myfunc2([1 2 3;4 5 6;7 8 9],[11 12 13;14 15 16; 17 18 19])
3×3 Array{Int64,2}:
  90 96 102
 216 231 246
 342 366 390

```

---

<div class="post-metadata">

### Author: ![moeddel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/moeddel/32/18641_2.png) [@moeddel](https://discourse.julialang.org/u/moeddel)
#### Post date: [February 24, 2021, 9:31am UTC](https://discourse.julialang.org/t/array-basics/55919/5 "2021-02-24T09:31:57Z")

</div>

> [@StevenSiew](#):
>
> But it’s much more fun when you do not tell Julia what the types are. Then you can do wonderful things like this

Great example @StevenSiew.

In julia you do not need to annotate the output type as long as it can be inferred from the input types you are good, see this section on [type stability](https://docs.julialang.org/en/v1/manual/faq/#man-type-stability). This way you do not need to write the same method over and over again.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [February 24, 2021, 9:47am UTC](https://discourse.julialang.org/t/array-basics/55919/6 "2021-02-24T09:47:55Z")

</div>

I don’t think you should hardcode in the return type. It makes your code inflexible. Let Julia figure out the types, using, for example, an array comprehension:

```julia
meta_list = [get_prop(g, i, b) for i in 1:nv(g) if isin(l,get_prop(g,i,b))] 

```

Maybe try to figure out a way to avoid evaluating `get_prop` twice per iteration.

BTW, the `else nothing` clause has no effect whatsoever, and should be removed.

---

<div class="post-metadata">

### Author: ![AlexanderChen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexanderchen/32/22007_2.png) [@AlexanderChen](https://discourse.julialang.org/u/AlexanderChen)
#### Post date: [February 24, 2021, 10:51am UTC](https://discourse.julialang.org/t/array-basics/55919/7 "2021-02-24T10:51:03Z")

</div>

@StevenSiew

cool! but does speed not suffer due to none instantiation?

---

<div class="post-metadata">

### Author: ![AlexanderChen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexanderchen/32/22007_2.png) [@AlexanderChen](https://discourse.julialang.org/u/AlexanderChen)
#### Post date: [February 24, 2021, 10:54am UTC](https://discourse.julialang.org/t/array-basics/55919/8 "2021-02-24T10:54:19Z")

</div>

@DNF

> Maybe try to figure out a way to avoid evaluating get\_prop twice per iteration.

I get your point will look into it.

> BTW, the `else nothing` clause has no effect whatsoever, and should be removed.

no, I understand that it does not do anything but I prefer to make it explicit.

---

<div class="post-metadata">

### Author: ![moeddel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/moeddel/32/18641_2.png) [@moeddel](https://discourse.julialang.org/u/moeddel)
#### Post date: [February 24, 2021, 10:58am UTC](https://discourse.julialang.org/t/array-basics/55919/9 "2021-02-24T10:58:15Z")

</div>

> [@AlexanderChen](#):
>
> cool! but does speed not suffer due to none instantiation?

As long as your function is type stable, you have no reduction in speed.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [February 24, 2021, 11:10am UTC](https://discourse.julialang.org/t/array-basics/55919/10 "2021-02-24T11:10:16Z")

</div>

> [@AlexanderChen](#):
>
> thanks that is one problem down

It can be done more generically as well. If you know that `get_prop(g,i,b)` returns the same type of value for every `i`, (in your case always an `Int`), you could do:

```julia
meta_list = typeof(get_prop(g,1,e))[]

```

that way the `meta_list` will contain the elements of the same type returned by `get_prop` always, even if in some other case they turn out to be floats or something else.

```julia
julia> get(x,i) = x[i]
get (generic function with 1 method)

julia> function f(x)
         list = typeof(get(x,1))[]
         push!(list,get(x,1))
         list
       end
f (generic function with 1 method)

julia> f([1,1])
1-element Array{Int64,1}:
 1

julia> f([1.0,2.0])
1-element Array{Float64,1}:
 1.0

```

---

<div class="post-metadata">

### Author: ![AlexanderChen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexanderchen/32/22007_2.png) [@AlexanderChen](https://discourse.julialang.org/u/AlexanderChen)
#### Post date: [February 24, 2021, 11:33am UTC](https://discourse.julialang.org/t/array-basics/55919/11 "2021-02-24T11:33:07Z")

</div>

@lmiq

now thats a neat trick. will use! thanks 🙂

---

<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: [February 24, 2021, 11:48am UTC](https://discourse.julialang.org/t/array-basics/55919/12 "2021-02-24T11:48:25Z")

</div>

Julia doesn’t need argument/return type annotations for speed because the method isn’t the final product, per se. When a function is called, Julia finds the most suitable method for that call’s argument types (dispatch). Then, Julia compiles the method for that call’s argument types (specialization), if it hasn’t already. One method can (and often is) called for different argument types, so one method can have many specializations. If you really want to document that a particular set of argument types results in a particular return type, you can jot it down in a comment or docstring. Just use `@code_warntype` to make sure it really does.

Annotating the return type just adds a type conversion step, maybe. If you already wrote your method to return that type given the function call’s argument types, then that step is omitted by the compiler. It’s rarely used because as others have demonstrated, this really limits what the method can do. Instead, you might be able to reuse this code for [Floats] → Float, [Bunnies] → Bunny, etc.

---

<div class="post-metadata">

### Author: ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)
#### Post date: [February 24, 2021, 11:59am UTC](https://discourse.julialang.org/t/array-basics/55919/13 "2021-02-24T11:59:08Z")

</div>

You can also use [InitialValues.jl](https://github.com/JuliaFolds/InitialValues.jl) together with [BangBang.jl](https://github.com/JuliaFolds/BangBang.jl)

```julia
using InitialValues
using BangBang

g(x) = x*x

function f(x)
    res = InitialValue(push!!)
    for el in x
        res = push!!(res, g(el))
    end

    return res
end

```

with the following result

```julia
julia> x1 = [1, 2, 3]
3-element Vector{Int64}:
 1
 2
 3

julia> f(x1)
3-element Vector{Int64}:
 1
 4
 9

julia> x2 = ["a", "b", "c"]
3-element Vector{String}:
 "a"
 "b"
 "c"

julia> f(x2)
3-element Vector{String}:
 "aa"
 "bb"
 "cc"

```

Be warned though, that the usage of `push!!` adds small overhead which may be or may be not crucial for you.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [February 24, 2021, 12:26pm UTC](https://discourse.julialang.org/t/array-basics/55919/14 "2021-02-24T12:26:29Z")

</div>

> [@Skoffer](#):
>
> You can also use [InitialValues.jl](https://github.com/JuliaFolds/InitialValues.jl) together with [BangBang.jl](https://github.com/JuliaFolds/BangBang.jl)

What those package bring that `typeof()[]` and `push!` do not? For that simple case they just seem to be obscuring the code.

---

<div class="post-metadata">

### Author: ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)
#### Post date: [February 24, 2021, 12:41pm UTC](https://discourse.julialang.org/t/array-basics/55919/15 "2021-02-24T12:41:43Z")

</div>

Well, first of all it is another approach and it is good to know another approaches, isn’t it? Secondly, they are used in various packages like Transducers.jl and as a next step one can switch from loops to transducers and the problem of initial value will go away by itself, but it is still good to understand how it works under the hood.

And thirdly, `typeof` construction is making additional call, and depending on the nature of the problem it may be a bad thing.

Consider following example

```julia
function g(x) 
    sleep(5)
    x*x
end

function f1(x)
    res = InitialValue(push!!)
    for el in x
        if el == 2
            res = push!!(res, g(el))
        end
    end

    return res
end

function f2(x)
    list = typeof(g(x[1]))[]
    for el in x
        if el == 2
            push!(list, g(el))
        end
    end

    return list
end

julia> x1 = [1, 2, 3]
julia> @time f1(x1)
  5.015492 seconds (6.64 k allocations: 349.130 KiB, 0.21% compilation time)
julia> @time f2(x1)
 10.021660 seconds (6.21 k allocations: 325.627 KiB, 0.11% compilation time)

```

At fourth, `push!!` is making type expansion, so in the following example

```julia
function g(x)
    if x < 2
        return 1
    else
        return 2.5
    end
end

julia> f1(x1)
1-element Vector{Float64}:
 2.5

julia> f2(x1)
ERROR: InexactError: Int64(2.5)

```

`typeof` function errors out.

Fifth, beauty in the eye of the beholder, I do not find that `push!!` is obscuring 🙂

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [February 24, 2021, 12:56pm UTC](https://discourse.julialang.org/t/array-basics/55919/16 "2021-02-24T12:56:15Z")

</div>

> [@Skoffer](#):
>
> Well, first of all it is another approach and it is good to know another approaches, isn’t it?

Thanks! (I didn’t mean to complain at all, sorry if I gave that impression). I was really curious and by reading the the package page I could not find out what the package did that a straight approach does not.

Indeed, I thought that avoiding that initial call was one of the things, but that seemed at first glance not much to justify someone writing a package. The type expansion is something nice, indeed.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [February 24, 2021, 1:30pm UTC](https://discourse.julialang.org/t/array-basics/55919/17 "2021-02-24T13:30:51Z")

</div>

> [@AlexanderChen](#):
>
> no, I understand that it does not do anything but I prefer to make it explicit.

Well, that’s up to you, but to me it’s confusing that it’s there. It’s easy to start wondering what its purpose is, and whether there is some non-obvious effect. I’ve never seen something like that before.

---

<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: [February 24, 2021, 2:23pm UTC](https://discourse.julialang.org/t/array-basics/55919/18 "2021-02-24T14:23:19Z")

</div>

See also this post and the surrounding discussion: [Why specify argument types and return types - #6 by stevengj](https://discourse.julialang.org/t/why-specify-argument-types-and-return-types/55567/6)

I’ve also proposed an addition to the manual, since this kind of question comes up a lot: [add basic overview of when to use type declarations by stevengj · Pull Request #39812 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/39812)
