# What does "k for k = 1:3" expands out to be?

I am confused here

``````julia> sum([1,2,3])
6

julia> sum([k for k = 1:3])
6

julia> sum(k for k = 1:3)
6
``````

But when I expand out “k for k = 1:3” manually it does not work

``````julia> sum(1,2,3)
ERROR: MethodError: no method matching sum(::Int64, ::Int64, ::Int64)
Closest candidates are:
sum(::Any, ::Any) at reduce.jl:486
sum(::Any) at reduce.jl:503
sum(::Any, ::AbstractArray; dims) at reducedim.jl:653
Stacktrace:
 top-level scope at REPL:1

julia> sum(1.0,2.0,3.0)
ERROR: MethodError: no method matching sum(::Float64, ::Float64, ::Float64)
Closest candidates are:
sum(::Any, ::Any) at reduce.jl:486
sum(::Any) at reduce.jl:503
sum(::Any, ::AbstractArray; dims) at reducedim.jl:653
Stacktrace:
 top-level scope at REPL:1
``````

Why doesn’t sum(1,2,3) give me 6?

Are you trying to use a generator?

``````julia> (k for k = 1:3)
Base.Generator{UnitRange{Int64},typeof(identity)}(identity, 1:3)

julia> sum((k for k = 1:3))
6
``````
1 Like

To answer the question, `sum(1,2,3)` doesn’t work, because, as the error message tells you, there is no `sum` method which takes three arguments like that (or more for that matter). What you want is to sum a generator.

1 Like

To achieve this you need to define

``````sum(vals...) = sum(vals)
``````

You need something to “slurp” all the `vals` into one tuple/array.

2 Likes

Easier way to visualize this is that

`sum(x for x = 1:3)` is not equal to `sum(1, 2, 3)`. The former only has one argument (the generator) and the latter has 3 arguments for which sum is not defined.

2 Likes

Maybe I misunderstood the question: I think the more interesting question is why does `sum(k for k = 1:3)` work at all, given that `k for k = 1:3` on its own does not work. And that’s because (I assume) if a generator-looking thing is passed directly to a function, even without enclosing parens, it is still parsed as a generator. The method that gets called is therefore `sum(g::Generator)`, not `sum(1,2,3)`.

Interestingly, it also works when there are multiple function arguments:

``````julia> sum(abs, k for k = -1:3)
7
``````

You can see how this is parsed similarly with tuples (with and without parens):

``````julia> (1,2,3,(k for k = -1:3))
(1, 2, 3, Base.Generator{UnitRange{Int64},typeof(identity)}(identity, -1:3))

julia> (1,2,3,k for k = -1:3)
(1, 2, 3, Base.Generator{UnitRange{Int64},typeof(identity)}(identity, -1:3))
``````
1 Like