"Given a nonempty stream of [[Summable]] values, return the sum of the values. {Float+} values = ... ; Float total = sum(values); For the case of a possibly-empty stream, form a nonempty stream starting with the zero element (the [[additive identity|Summable]]). {Float*} values = ... ; Float total = sum { 0.0, *values }; For the case of a stream of `Integer`s, `Float`s, or `String`s, prefer [[Integer.sum]], [[Float.sum]], or [[String.sum]]." see (`function product`, `function Integer.sum`, `function Float.sum`, `function String.sum`) tagged("Streams", "Numbers") shared native Value sum<Value>({Value+} values) given Value satisfies Summable<Value>; shared native("js") Value sum<Value>({Value+} values) given Value satisfies Summable<Value> { value it = values.iterator(); assert (!is Finished first = it.next()); variable value sum = first; while (!is Finished val = it.next()) { sum += val; } return sum; } shared native("jvm") Value sum<Value>({Value+} values) given Value satisfies Summable<Value> { value it = values.iterator(); switch (first = it.next()) case (is Integer) { // unbox; don't infer type Value&Integer variable Integer sum = first; while (is Integer val = it.next()) { Integer unboxed = val; sum += unboxed; } assert (is Value result = sum); return result; } case (is Float) { // unbox; don't infer type Value&Float variable Float sum = first; while (is Float val = it.next()) { Float unboxed = val; sum += unboxed; } assert (is Value result = sum); return result; } case (is String) { value sum = StringBuilder(); sum.append(first); while (is String val = it.next()) { sum.append(val); } assert (is Value result = sum.string); return result; } case (is Finished) { assert (false); } else { variable value sum = first; while (!is Finished val = it.next()) { sum += val; } return sum; } }