Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do the triple dots (...) in a julia array do? Why do they change the type signature?

Tags:

julia

Given the data types bellow, the following comprehension yields two Array{Any,1} of Players:

[[team.players for team in [big_team_1, big_team_2]]]

This next comprehension, however, yields the desired result of an Array{Player,1} of 12 elements:

[[team.players for team in [big_team_1, big_team_2]]...]

What exactly is the ... doing? Where is this documented?


Data:

type Player
  ranking::Int
end

type Team
  players::Array{Player}
end

team_1 = Team([Player(10_000), Player(11_000), Player(9_000), Player(8_500),
                   Player(20_000), Player(10_500)])

team_2 = Team([Player(i.ranking + 3000) for i in team_1.players])
like image 810
o_o_o-- Avatar asked Nov 20 '15 21:11

o_o_o--


People also ask

What does DOT do in Julia?

The dots allow Julia to recognize the "vectorized" nature of the operations at a syntactic level (before e.g. the type of x is known), and hence the loop fusion is a syntactic guarantee, not a compiler optimization that may or may not occur for carefully written code.

What does the splat operator do Julia?

The "splat" operator, ... , represents a sequence of arguments. ... can be used in function definitions, to indicate that the function accepts an arbitrary number of arguments. ... can also be used to apply a function to a sequence of arguments.

What is :: In Julia?

A return type can be specified in the function declaration using the :: operator. This converts the return value to the specified type. This function will always return an Int8 regardless of the types of x and y .

Are arrays mutable in Julia?

Arrays in Julia are mutable and hence it allows modification of its content. Elements in arrays can be removed or updated as per requirement.


1 Answers

args... and ; kwargs... is the splat operator, if you know Python, it's the same as *args and **kwargs:

You can find documentation here: What does the splat ... operator do?

When in method signature (collects arguments).

julia> function foo(pos_1, pos_2, opt_1 = :opt_1, args...;
                    opt_kw1 = :opt_kw1, opt_kw2 = :opt_kw2, kwargs...)
           [pos_1, pos_2, opt_1, args, opt_kw1, opt_kw2, (kwargs,);]
       end
foo (generic function with 2 methods)

This signature means:

  • pos_1 is the first required positional argument.
  • pos_2 is the second required positional argument.
  • opt_1 is an optional positional argument.
  • args... are all the following positional arguments, collected in a tuple.

Notice how semi colon ; separates positional arguments from keyword arguments (order is not important in key word arguments):

  • opt_kw1 is an optional keyword argument.
  • opt_kw2 is an optional keyword argument.
  • kwargs... are all the following keyword arguments collected in an array of tuple (key, value) pairs.

julia> methods(foo)
# 2 methods for generic function "foo":
foo(pos_1, pos_2) at none:3
foo(pos_1, pos_2, opt_1, args...) at none:3

foo can be called like this:

Required arguments:
julia> foo(:pos_1, :pos_2)
7-element Array{Any,1}:
 :pos_1      # provided value
 :pos_2      # provided value
 :opt_1      # default value
 ()          # empty tuple
 :opt_kw1    # default value
 :opt_kw2    # default value
 (Any[],)    # there are no kwargs
Optional positional and keyword arguments:
julia> foo(:pos_1, :pos_2, :OPT_1, :a, :b, :c,
           opt_kw2 = :OPT_KW2, kwarg1 = true, opt_kw1 = :OPT_KW1, kwarg2 = false)
7-element Array{Any,1}:
 :pos_1
 :pos_2
 :OPT_1
 (:a,:b,:c)
 :OPT_KW1
 :OPT_KW2
 (Any[(:kwarg1,true),(:kwarg2,false)],)

Notice how the order in key word arguments is not relevant, also the semicolon ; is not needed when calling the function.


When in function call (spreads arguments).

Using collections for the positional arguments and assosiative collections with symbol keys for the keyword arguments:

julia> x, y, z = 1, 2, 3;

julia> sum(x, y, z)
ERROR: MethodError: `sum` has no method matching sum(::Int64, ::Int64, ::Int64)
Closest candidates are:
  sum(::Union{Base.Func{1},Function}, ::AbstractArray{T,N}, ::Any)
  sum(::Union{Base.Func{1},DataType,Function}, ::Any)
  sum(::BitArray{N}, ::Any)
  ...

julia> sum
sum (generic function with 12 methods)

julia> Base.sum(args...) = sum(args)
sum (generic function with 13 methods)

julia> sum(x, y, z)
6

julia> foo(x, y, z) = sum(x, y, z)
foo (generic function with 1 method)

julia> foo(x, y, z)
6

julia> foo([x, y, z])
ERROR: MethodError: `foo` has no method matching foo(::Array{Int64,1})
Closest candidates are:
  foo(::Any, ::Any, ::Any)

julia> foo([x, y, z]...)
6

julia> foo(; x = 0, y = 0, z = 0) = sum(x, y, z)
foo (generic function with 2 methods)

julia> foo()
0

julia> foo(z = 3, x = 1, y = 2)
6

julia> foo(; Dict(:z => 3, :y => 2, :x => 1))
ERROR: TypeError: anonymous: in typeassert, expected Symbol, got Pair{Symbol,Int64}
 in anonymous at no file

julia> foo(; Dict(:z => 3, :y => 2, :x => 1)...)
6
like image 66
HarmonicaMuse Avatar answered Oct 22 '22 23:10

HarmonicaMuse