Stream: beginners

Topic: Iter.sum


view this post on Zulip Aurélien Geron (Jul 29 2026 at 06:42):

I'd like to run (1..=10).sum() but Iter.sum does not exist. I can work around this by writing (1..=10)->List.from_iter().sum() and this works fine, but it's a pity we have to materialize a List for this. So I wrote the following function:

sum = |iter| {
    var $s = 0
    for value in iter {
        $s = $s + value
    }
    $s
}

It works fine, I can now write (1..=10)->sum(). However, I'd like to add the type spec for this function, and I just can't. The inferred type is:

        a -> b
          where [
            a.iter : a -> Iter(item),
            b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
            b.plus : b, item -> b,
          ]

But when I try to use this type spec, I get an error. Here's a REPL session that shows the error:

» sum : a -> b where [
        a.iter : a -> Iter(item),
        b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
        b.plus : b, item -> b,
  ]
  sum = |iter| {
        var $s = 0
        for value in iter {
                $s = $s + value
        }
        $s
  }

assigned `sum`
»
» (1..=10)->sum()

┌───────────────────┐
│ POLYMORPHIC VALUE ├─ This top-level value still has an unresolved polymorphic type. ─────────────────────────────────────────────────────────────────────────┐
└┬──────────────────┘                                                                                                                                          │
 │                                                                                                                                                             │
 │  main = (1..=10)->sum()                                                                                                                                     │
 │  ‾‾‾‾                                                                                                                                                       │
 └────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── repl:14:1 ┘

    Its type is:
    b
      where [
        b.from_numeral : Numeral -> Try(b, [InvalidNumeral(Str)]),
        b.plus : b, Dec -> b,
      ]
    Add an annotation or use this value in a way that fixes its concrete type.


┌────────────────┐
│ MISSING METHOD ├─ This is trying to dispatch a method named from_numeral on an unresolved type variable, but unresolved type variables have no methods. ─────┐
└┬───────────────┘                                                                                                                                             │
 │                                                                                                                                                             │
 │  main = (1..=10)->sum()                                                                                                                                     │
 │                   ‾‾‾                                                                                                                                       │
 └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── repl:14:18 ┘

    Hint: You can replace this static dispatch call with an ordinary function call, or force the type variable to become more concrete—for example, by adding a
    type annotation that narrows its type to something that actually has methods.
»

Should I file a bug?

view this post on Zulip Anton (Jul 29 2026 at 12:35):

@Jared Ramirez

view this post on Zulip Richard Feldman (Jul 29 2026 at 13:11):

oh this is a bug, should be a quick fix

view this post on Zulip Richard Feldman (Jul 29 2026 at 13:12):

separately, Iter.sum seems reasonable to me :thumbs_up:

view this post on Zulip Austin Clements (Jul 29 2026 at 17:23):

I had a use case for Iter.sum too in roc-random. I wound up doing it manually with folding but considered going to List so I could use List.sum I figured it would allocate but I was wondering if that’s the kind of thing that would get optimized away, and if so how dependable is that optimization to happen, and lastly is there a way/plan to be able to inspect whether these kind of optimizations are happening? I’m sure it’s a beast of a compilation pipeline, was just curious. @Luke Boswell mentioned adding logging to the host allocator so I’ll try that with both versions of the roc function

view this post on Zulip Anton (Jul 29 2026 at 17:48):

@Luke Boswell mentioned adding logging to the host allocator so I’ll try that with both versions of the roc function

Yes that is a very convenient way to check. You can also look at the llvm IR, instructions from Claude:

Quickest way to inspect IR right now: in src/cli/builder.zig around line 617-631, change
  `.llvm_ir_filename = null,`
  to point at a path, e.g. .llvm_ir_filename = "/tmp/out.ll".ptr, (temporarily, for debugging) before the emit_options struct
  is passed to ZigLLVMTargetMachineEmitToFile at line 633. Rebuild with zig build roc and run your compile — you'll get a
  human-readable .ll file alongside the object output.

view this post on Zulip Richard Feldman (Jul 29 2026 at 19:30):

@Aurélien Geron this now works, and also Iter.sum is a builtin!

view this post on Zulip Austin Clements (Jul 29 2026 at 19:30):

Anton said:

@Luke Boswell mentioned adding logging to the host allocator so I’ll try that with both versions of the roc function

Yes that is a very convenient way to check. You can also look at the llvm IR, instructions from Claude:

Quickest way to inspect IR right now: in src/cli/builder.zig around line 617-631, change
  `.llvm_ir_filename = null,`
  to point at a path, e.g. .llvm_ir_filename = "/tmp/out.ll".ptr, (temporarily, for debugging) before the emit_options struct
  is passed to ZigLLVMTargetMachineEmitToFile at line 633. Rebuild with zig build roc and run your compile — you'll get a
  human-readable .ll file alongside the object output.

Nice thanks so much I’m gonna try both approaches


Last updated: Aug 12 2026 at 12:35 UTC