[swift-evolution] [swift-evolution-announce] [Review] SE-0127: Cleaning up stdlib Pointer and Buffer Routines
Dave Abrahams
dabrahams at apple.com
Sat Jul 23 15:48:33 CDT 2016
on Fri Jul 22 2016, Charlie Monroe <charlie-AT-charliemonroe.net> wrote:
> Ok, I'll update the proposal to withdraw the change of inout for
> withUnsafePointer.
We could also add
withUnsafePointer(toCopyOf: x)
but that can also come later if we decide we need it.
> Under the discussion for the pull request, Bob mentioned possible
> removal of the multi-pointer variants
> (i.e. withUnsafe[Mutable]Pointers) - is this something that you'd
> agree on?
Absolutely.
> If so, I'd add this to the proposal since I agree that this is an API
> that is rarely used, can be used by nesting two
> withUnsafe[Mutable]Pointer calls and is limited to three pointers at
> max anyway. It almost feels like NSAssert1, NSAssert2, etc.
>
>> On Jul 23, 2016, at 3:35 AM, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
>>
>>
>> on Fri Jul 22 2016, Xiaodi Wu <xiaodi.wu-AT-gmail.com> wrote:
>>
>>> On Fri, Jul 22, 2016 at 6:49 PM, Dave Abrahams via swift-evolution <
>>> swift-evolution at swift.org> wrote:
>>>
>>>>
>>>> on Fri Jul 22 2016, Xiaodi Wu <swift-evolution at swift.org> wrote:
>>>>
>>>>> On Fri, Jul 22, 2016 at 5:06 PM, Dave Abrahams via swift-evolution <
>>>>> swift-evolution at swift.org> wrote:
>>>>>
>>>>>>
>>>>>> on Fri Jul 22 2016, Bob Wilson <swift-evolution at swift.org> wrote:
>>>>>>
>>>>>>> It is not so clear what to do about SR-1956. (Charlie and I had some
>>>>>>> comments on this in https://github.com/apple/swift-evolution/pull/437
>>>>>>> <https://github.com/apple/swift-evolution/pull/437>.) Jordan raised
>>>>>>> the objection that when using withUnsafePointer with a global, there
>>>>>>> is an expectation that you’ll get the same address every
>>>>>>> time. Removing inout would cause the argument to be passed by value
>>>>>>> and the address would refer to a copy. Dmitri agreed that this could
>>>>>>> be a problem. On the other hand, if you don’t care about the address,
>>>>>>> or if you’re not using a value type, it would indeed be convenient to
>>>>>>> have a version of withUnsafePointer that does not require an inout
>>>>>>> argument.
>>>>>>>
>>>>>>> Option 1: Keep inout (not addressing SR-1956). In this case, there’s
>>>>>>> no reason to have both withUnsafePointer and
>>>>>>> withUnsafeMutablePointer. If you want to call a function that expects
>>>>>>> an UnsafePointer, you can give it an UnsafeMutablePointer and there
>>>>>>> will be an implicit conversion to make it work. I discussed this with
>>>>>>> Apple’s stdlib team and they recommended that if we have only one
>>>>>>> function we use the shorter name “withUnsafePointer” and have it use
>>>>>>> an UnsafeMutablePointer.
>>>>>>
>>>>>> Very much in favor of Option 1.
>>>>>>
>>>>>
>>>>> Ditto, except that I think there is some value in keeping both (i.e.
>>>> doing
>>>>> nothing): allowing the user to document intent. It would be inconsistent
>>>>> and potentially confusing to call the function that returns an
>>>>> `UnsafeMutablePointer` `withUnsafePointer`.
>>>>
>>>> It doesn't return an `UnsafeMutablePointer`, it passes an
>>>> `UnsafeMutablePointer` to the body of the closure.
>>>>
>>>
>>> Brainfart. Yes, that's what I meant to write. Sorry.
>>>
>>>>> It's rarely used enough, and the shorter name needlessly raises the
>>>>> question of where I'm really "supposed to be" mutating the
>>>>> pointee.
>>>>
>>>> I don't understand; you only have the pointee inside the closure.
>>>> That's where you mutate it (obviously?)
>>>>
>>>
>>> If my closure does not mutate the pointee, `withUnsafePointer(_:)` allows
>>> me to document that. Everything *works* with
>>> `withUnsafeMutablePointer(_:)`, but I cannot read the code and understand
>>> that no mutation has happened within the body of the closure. [Am I wrong
>>> on this?]
>>
>> No, you're right.
>>
>>> For instance, I've been working with some of the Accelerate.framework
>>> functions and the arguments are often cryptic. Take this call:
>>>
>>> ```
>>> cblas_sgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, m, n, k, 1, matrix,
>>> m, b, k, 1, &c, m)
>>> ```
>>>
>>> There are times when I'd want to
>>> call `cblas_sgemm(_:_:_:_:_:_:_:_:_:_:_:_:_:_:)` inside an
>>> `withUnsafe[Mutable]Pointer(_:)` closure. Distinguishing
>>> `withUnsafePointer(_:)` and `withUnsafeMutablePointer(_:)` would allow a
>>> reader to know from the outset if `$0.pointee is mutated without having to
>>> know that the second-from-last argument is the one that stores the result
>>> (it is not consistently second-from-last; for vDSP_* functions, it's often
>>> the third-from-last argument, and for others it can be the first argument).
>>> Removing the current `withUnsafePointer(_:)` would decrease clarity for the
>>> reader here.
>>
>> Okay, fair enough.
>>
>>>> I've not had to use these functions much, but the distinction between
>>>>> `Array.withUnsafeBufferPointer(_:)` and
>>>>> `Array.withUnsafeMutableBufferPointer(_:)` has conditioned me to
>>>>> mutate the pointee using only "mutable" functions.
>>>>
>>>> Not sure if you're just drawing an analogy,
>>>
>>> I was trying to. I guess ineffectively.
>>>
>>>> but if not, those two
>>>> methods are not under discussion here. They are meaningfully different,
>>>> whereas the existing functions are not, and the one currently called
>>>> withUnsafePointer is always going to cause people to complain about
>>>> having to pass a mutable variable.
>>>>
>>>> As a fallback position, I would suggest we only provide the mutating
>>>> one, but with its existing name. But I still prefer the shorter name.
>>>>
>>>>>
>>>>>>>
>>>>>>> Option 2: Fix SR-1956 and have two functions, one with inout and the
>>>>>>> other not. This would address the inconvenience of not being able to
>>>>>>> use withUnsafePointer with immutable values, while still supporting
>>>>>>> the existing behavior. The question then would be what to call these
>>>>>>> two functions.
>>>>>>
>>>>>> We do not need to support new use-cases in this release, and this would
>>>>>> be unsatisfying because the “address of a global” property that Jordan
>>>>>> argued for would not hold for the immutable version.
>>>>>>
>>>>>>> - Option 2a. Combine the two existing functions as in Option 1 and use
>>>>>>> a new name for the non-inout version, e.g.,
>>>>>>> withUnsafePointer(toCopyOf:), so that it won’t be confused with the
>>>>>>> old function. (That particular name doesn’t work very well when
>>>>>>> dealing with references to objects, since the object itself would not
>>>>>>> be copied. I haven’t yet come up with a better name, though.) One
>>>>>>> advantage of this approach is that we would not need to rush the new
>>>>>>> function into Swift 3 since it would be an additive change.
>>>>>>
>>>>>> Not rushing that into Swift 3 is the same as Option 1.
>>>>>>
>>>>>>> - Option 2b. Switch to use withUnsafeMutablePointer for all the cases
>>>>>>> where you care about the getting the same address. Change
>>>>>>> withUnsafePointer to be the non-inout version. Charlie suggested that
>>>>>>> we could have the migrator convert all existing uses on
>>>>>>> withUnsafePointer in Swift 2 code to use withUnsafeMutablePointer in
>>>>>>> Swift 3, but I’m not sure how well that would work.
>>>>>>
>>>>>> That's exactly the same outcome, with respect to the language/library
>>>>>> surface, as Option 2 AFAICT. Can we simplify this list of options?
>>>>>>
>>>>>> --
>>>>>> Dave
>>>>>>
>>>>>> _______________________________________________
>>>>>> 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
>>>>>
>>>>
>>>> --
>>>> Dave
>>>>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>
>>
>> --
>> Dave
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
More information about the swift-evolution
mailing list