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 < > [email protected]> wrote: > >> >> on Fri Jul 22 2016, Xiaodi Wu <[email protected]> wrote: >> >> > On Fri, Jul 22, 2016 at 5:06 PM, Dave Abrahams via swift-evolution < >> > [email protected]> wrote: >> > >> >> >> >> on Fri Jul 22 2016, Bob Wilson <[email protected]> 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 >> >> [email protected] >> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> >> >> > _______________________________________________ >> > swift-evolution mailing list >> > [email protected] >> > https://lists.swift.org/mailman/listinfo/swift-evolution >> > >> >> -- >> Dave >> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] >> https://lists.swift.org/mailman/listinfo/swift-evolution >> -- Dave _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
