[swift-evolution] Reduce with inout

Chris Eidhof chris at eidhof.nl
Tue Jan 17 13:52:32 CST 2017


Any arguments against adding it? Otherwise I'll draft up a short proposal
tomorrow.

On Tue, Jan 17, 2017 at 7:24 PM, Joe Groff via swift-evolution <
swift-evolution at swift.org> wrote:

>
> > On Jan 16, 2017, at 8:10 PM, Dave Abrahams via swift-evolution <
> swift-evolution at swift.org> wrote:
> >
> >
> > on Mon Jan 16 2017, Charles Srstka <cocoadev-AT-charlessoft.com> wrote:
> >
> >> On Jan 16, 2017, at 6:42 PM, Dave Abrahams via swift-evolution <
> swift-evolution at swift.org> wrote:
> >>>
> >>>
> >>> on Mon Jan 16 2017, Charles Srstka <swift-evolution at swift.org
> >>> <mailto:swift-evolution at swift.org>> wrote:
> >>>
> >>
> >>>>> On Jan 16, 2017, at 7:49 AM, Chris Eidhof via swift-evolution <
> swift-evolution at swift.org> wrote:
> >>>>>
> >>>>> Hi,
> >>>>>
> >>>>> How does everyone feel about adding a second version of `reduce` to
> >>>>
> >>>>> `Sequence`? Instead of a `combine` function that's of type `(A,
> >>>>> Element) -> A`, it would be `(inout A, Element) -> ()`. This way, we
> >>>>> can write nice functionals algorithms, but have the benefits of
> >>>>> inout (mutation within the function, and hopefully some copy
> >>>>> eliminations).
> >>>>>
> >>>>> IIRC, Loïc Lecrenier first asked this on Twitter. I've been using it
> >>>>> ever since, because it can really improve readability (the possible
> >>>>> performance gain is nice, too).
> >>>>>
> >>>>> Here's `reduce` with an `inout` parameter, including a sample:
> >>>>> https://gist.github.com/chriseidhof/fd3e9aa621569752d1b04230f92969d7
> >>>>>
> >>>>> --
> >>>>> Chris Eidhof
> >>>>
> >>>> I did this in my own private code a while ago. There is one drawback,
> which is that Swift’s type
> >>>> inference system isn’t quite up to handling it. For example, doing
> this results in an “ambiguous
> >>>> reference to member” warning:
> >>>>
> >>>> range.reduce([Int]()) { $0.append($1) }
> >>>
> >>> The diagnostic could be better, but the compiler shouldn't let you do
> >>> that, because it requires passing an unnamed temporary value ([Int]())
> >>> as inout.
> >>
> >> No it doesn’t. The signature of the method is:
> >>
> >> func reduce<A>(_ initial: A, combine: (inout A, Iterator.Element) ->
> ()) -> A
> >>
> >> The unnamed temporary value is “initial” here, which is not passed as
> inout; the inout parameter is
> >> the first argument to the “combine” closure. The value represented by
> the ‘initial’ parameter is
> >> passed to the closure, true, but only after being stored in a
> not-unnamed ‘var’ variable, as you can
> >> see from the source of the proposed method:
> >>
> >> func reduce<A>(_ initial: A, combine: (inout A, Iterator.Element) ->
> ()) -> A {
> >>    var result = initial
> >>    for element in self {
> >>        combine(&result, element)
> >>    }
> >>    return result
> >> }
> >>
> >> Therefore, I don’t understand this objection.
> >>
> >>>> One would think that the type of this closure should be clear:
> >>>>
> >>>> 1) The closure calls append(), a mutating function, so $0 must be
> inout.
> >>>>
> >>>> 2) The closure doesn’t return anything, which should rule out the
> >>>> default implementations of reduce,
> >>>
> >>> The closure *does* return something: (), the empty tuple
> >>
> >> But it’s not what it’s supposed to return. Sequence’s implementation
> >> of reduce, which the compiler thinks matches the above, is declared
> >> like this:
> >>
> >> public func reduce<Result>(_ initialResult: Result, _
> >> nextPartialResult: (Result, Self.Iterator.Element) throws -> Result)
> >> rethrows -> Result
> >>
> >> The closure is supposed to return Result, which in this case would be
> >> [Int]. It doesn’t, so I’m not sure why the compiler is thinking this
> >> is a match.
> >
> > Okay, sounds like I'm totally wrong! Has to happen at least once in a
> > lifetime, doesn't it? 😉
> >
> > So please file bug reports for these issues.
>
> This one should already be fixed in master. If it isn't, definitely file a
> new one!
>
> -Joe
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>



-- 
Chris Eidhof
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170117/a39f1e79/attachment.html>


More information about the swift-evolution mailing list