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:
 [1] top-level scope at REPL[42]: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:
 [1] top-level scope at REPL[43]: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