[swift-evolution] Draft: Add @noescape and rethrows to ManagedBuffer API

Janosch Hildebrand jnosh at jnosh.com
Sun Feb 7 08:53:19 CST 2016


+1

Is there a reason for not marking 'ManagedBuffer.create' and 'ManagedBufferPointer.init' as rethrows and taking throwing closures?
Now that we can have throwing initializers I don't really see a reason for not allowing throwing closures here...


> On 06 Feb 2016, at 21:03, Károly Lőrentey via swift-evolution <swift-evolution at swift.org> wrote:
> 
> I’d like to request feedback on the draft proposal below, about a (hopefully) trivial change to the standard library. 
> 
> I considered adding it to SE-0012 <https://github.com/apple/swift-evolution/blob/master/proposals/0012-add-noescape-to-public-library-api.md>, which is also about @noescape, but that proposal is about modifying C/Obj-C API, so it’s not a good fit <https://github.com/apple/swift-evolution/pull/122>.
> 
> Introduction
> 
> stdlib’s ManagedBuffer family of APIs has some public initializers and methods taking closures that are missing the @noescape attribute. The same family has a set of withUnsafeMutablePointer* functions that do not have a rethrows declaration, while all similar methods elsewhere in the standard library allow closures to throw.
> 
> I propose to add the missing @noescape attributes and rethrows.
> 
> Motivation
> 
> - ManagedBuffer seems designed for raw performance. Not having @noescape on the only API that allows access to the buffer’s contents defeats some compiler optimizations, such as omitting unneccessary retain/release calls. This can negate the performance advantage of ManagedBuffer over simpler solutions, like using an Array.
> - Accepting throwing closures makes these APIs more versatile, and also improves their consistency with other parts of stdlib.
> 
> Detailed Design
> 
> The following set of APIs would be affected by this proposal:
> 
> public class ManagedProtoBuffer<Value, Element> : NonObjectiveCBase {
>   public final func withUnsafeMutablePointerToValue<R>(body: (UnsafeMutablePointer<Value>) -> R) -> R
>   public final func withUnsafeMutablePointerToElements<R>(body: (UnsafeMutablePointer<Element>) -> R) -> R
>   public final func withUnsafeMutablePointers<R>(body: (_: UnsafeMutablePointer<Value>, _: UnsafeMutablePointer<Element>) -> R) -> R
> }
> 
> public class ManagedBuffer<Value, Element> : ManagedProtoBuffer<Value, Element> {
>   public final class func create(minimumCapacity: Int, initialValue: (ManagedProtoBuffer<Value,Element>) -> Value) -> ManagedBuffer<Value,Element> 
> }
> 
> public struct ManagedBufferPointer<Value, Element> : Equatable {
>   public init(bufferClass: AnyClass, minimumCapacity: Int, initialValue: (buffer: AnyObject, allocatedCount: (AnyObject) -> Int) -> Value)
>   public func withUnsafeMutablePointerToValue<R>(body: (UnsafeMutablePointer<Value>) -> R) -> R
>   public func withUnsafeMutablePointerToElements<R>(body: (UnsafeMutablePointer<Element>) -> R) -> R
>   public func withUnsafeMutablePointers<R>(body: (_: UnsafeMutablePointer<Value>, _: UnsafeMutablePointer<Element>) -> R) -> R
> }
> 
> Here is how they would look after the proposed changes:
> 
> public class ManagedProtoBuffer<Value, Element> : NonObjectiveCBase {
>   public final func withUnsafeMutablePointerToValue<R>(@noescape body: (UnsafeMutablePointer<Value>) throws -> R) rethrows -> R
>   public final func withUnsafeMutablePointerToElements<R>(@noescape body: (UnsafeMutablePointer<Element>) throws -> R) rethrows -> R
>   public final func withUnsafeMutablePointers<R>(@noescape body: (_: UnsafeMutablePointer<Value>, _: UnsafeMutablePointer<Element>) throws -> R) rethrows -> R
> 
> public class ManagedBuffer<Value, Element> : ManagedProtoBuffer<Value, Element> {
>   public final class func create(minimumCapacity: Int, @noescape initialValue: (ManagedProtoBuffer<Value,Element>) -> Value) -> ManagedBuffer<Value,Element> 
> }
> 
> public struct ManagedBufferPointer<Value, Element> : Equatable {
>   public init(bufferClass: AnyClass, minimumCapacity: Int, @noescape initialValue: (buffer: AnyObject, allocatedCount: (AnyObject) -> Int) -> Value)
>   public func withUnsafeMutablePointerToValue<R>(@noescape body: (UnsafeMutablePointer<Value>) throws -> R) rethrows -> R
>   public func withUnsafeMutablePointerToElements<R>(@noescape body: (UnsafeMutablePointer<Element>) throws -> R) rethrows -> R
>   public func withUnsafeMutablePointers<R>(@noescape body: (_: UnsafeMutablePointer<Value>,_: UnsafeMutablePointer<Element>) throws -> R) rethrows -> R
> }
> 
> A draft implementation is available at https://github.com/apple/swift/compare/master...lorentey:noescape <https://github.com/apple/swift/compare/master...lorentey:noescape>
> 
> Impact on Existing Code
> 
> Luckily, all modified API is either marked final, or defined in a struct, so I expect no existing code is going to break due to these changes.
> 
> -- 
> Károly
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

- Janosch

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160207/e4b82309/attachment-0001.html>


More information about the swift-evolution mailing list