[swift-evolution] Reduce with inout

Xiaodi Wu xiaodi.wu at gmail.com
Tue Jan 24 21:24:30 CST 2017


Hmm, good point--none come to mind.


On Tue, Jan 24, 2017 at 14:03 Matthew Johnson <matthew at anandabits.com>
wrote:

On Jan 24, 2017, at 1:27 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:

Hmm, brainstorming here. Given the pervasive use of `with` to mean "this
isn't accessible otherwise but inside this closure it's $0", maybe
`reduce(with: 42) { $0 += 1 }` might give a useful hint?


Are there any current uses of `with` passed `inout`?

On Tue, Jan 24, 2017 at 13:19 Matthew Johnson <matthew at anandabits.com>
wrote:

On Jan 24, 2017, at 1:01 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:

Hmm, it reads well, but IMO it avoids being misleading only because it
doesn't mean anything. In what way are you reducing "into" the first
argument any more so than the classic reduce function?


It isn't perfect, but it’s better than the alternatives I’ve seen so far.

In the classic reduce function a new value is produced for each step of the
reduction.  In this variation, each step reduces “into” an accumulator that
is initialized with the seed value.  In that sense, you could say that you
reduce “into” the seed value.

Labeling the argument `into` is a little bit of a stretch but I think it's
far superior to `mutating` which is pretty misleading at the call site.  I
think it would be pretty hard to come up with something better, but let’s
keep the bikeshed going if anyone has additional ideas.


On Tue, Jan 24, 2017 at 12:44 Matthew Johnson via swift-evolution <
swift-evolution at swift.org> wrote:

On Jan 24, 2017, at 12:36 PM, Pyry Jahkola via swift-evolution <
swift-evolution at swift.org> wrote:


Freak Show wrote:

Am I the only one who finds this incredibly ugly and hard to read?

This is more or less solved by inject:into: idiom.  There is no reason for
inout for this particular problem.


Yeah, the original signature seems more useful. If you go all `inout` like
Gwendal suggested, you might as well just iterate over the sequence with
`for x in xs`, updating the state as you go.

But your comment brought another idea to mind: if `mutating:` is considered
a bad name for a non-`inout` argument, how about `*reduce(into:combine:)`*,
similar to what Karl suggested earlier in this thread?

I think it reads very well at the call site, does not suggest `inout`ness
of the argument too much (of course there's no `&` at the call site
either), and it's still easily found with auto-completion:

    let counts = words.reduce(into: [:]) {
      $0[$1] = ($0[$1] ?? 0) + 1
    }


+1.  This is concise and I think it captures the essence of what is
happening pretty well!

The third variation where the seed argument actually *is* `inout` might
also be interesting in some cases where you *already* have a `var` that you
want to accumulate into.  I believe I have done this in the past in my own
code but don’t have an example handy.


— Pyry
_______________________________________________
swift-evolution mailing list
swift-evolution at swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution at swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170125/8d8465f8/attachment.html>


More information about the swift-evolution mailing list