Re: [swift-evolution] Pitch: Improved Swift pointers

2017-09-09 Thread Dave Abrahams via swift-evolution


on Wed Aug 09 2017, Xiaodi Wu 
 wrote: 

On Wed, Aug 9, 2017 at 8:22 PM, Brent Royal-Gordon via 
swift-evolution < 
swift-evolution@swift.org> wrote: 

On Jul 19, 2017, at 11:21 AM, Taylor Swift via swift-evolution 
< swift-evolution@swift.org> 
wrote: 

What about `value:`? 

`ptr.initialize(value: value)` `ptr.initialize(value: value, 
count: 13)` `ptr.initialize(as: UInt16.self, at: 0, value: 
value, count: 13)` 
 
Doesn't read as a sentence. Consider how "initialize to 3" 
sounds different from "initialize value 3". 

Personally, I'd go with: 

ptr.initialize(to: value) ptr.initialize(to: value, 
repeatCount: 3) 

(Or just `repeat`/`repeating` if you don't feel like you need 
the word "count" to disambiguate.) 



Per Swift API naming guidelines, initializers don't have to read 
as sentences IIRC, and I'd be inclined to grant a function named 
`initialize(_:)` the same courtesy. 


I know it's late to chime in here, but: that's not an initializer.

--
-Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-08-09 Thread Xiaodi Wu via swift-evolution
On Wed, Aug 9, 2017 at 8:22 PM, Brent Royal-Gordon via swift-evolution <
swift-evolution@swift.org> wrote:

> On Jul 19, 2017, at 11:21 AM, Taylor Swift via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> What about `value:`?
>
> `ptr.initialize(value: value)`
> `ptr.initialize(value: value, count: 13)`
> `ptr.initialize(as: UInt16.self, at: 0, value: value, count: 13)`
>
>
> Doesn't read as a sentence. Consider how "initialize to 3" sounds
> different from "initialize value 3".
>
> Personally, I'd go with:
>
> ptr.initialize(to: value)
> ptr.initialize(to: value, repeatCount: 3)
>
> (Or just `repeat`/`repeating` if you don't feel like you need the word
> "count" to disambiguate.)
>

Per Swift API naming guidelines, initializers don't have to read as
sentences IIRC, and I'd be inclined to grant a function named
`initialize(_:)` the same courtesy.

For arrays, `repeating:` labels the repeating value, not the number of
times it repeats, and the analogous labels here would indeed be
`ptr.initialize(repeating: value, count: 3)`. I agree with the observations
above that `repeating` looks weird if the default and most common use is 1,
though; `value` is fine, I guess--or the Swiftism `pointee`?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-08-09 Thread Brent Royal-Gordon via swift-evolution
> On Jul 19, 2017, at 11:21 AM, Taylor Swift via swift-evolution 
>  wrote:
> 
> What about `value:`?
> 
> `ptr.initialize(value: value)`
> `ptr.initialize(value: value, count: 13)`
> `ptr.initialize(as: UInt16.self, at: 0, value: value, count: 13)`

Doesn't read as a sentence. Consider how "initialize to 3" sounds different 
from "initialize value 3".

Personally, I'd go with:

ptr.initialize(to: value)
ptr.initialize(to: value, repeatCount: 3)

(Or just `repeat`/`repeating` if you don't feel like you need the word "count" 
to disambiguate.)

-- 
Brent Royal-Gordon
Architechies

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-20 Thread Taylor Swift via swift-evolution
Okay, I changed it to

Right now, UnsafeMutableBufferPointer is kind of a black box when it comes
to producing and modifying instances of it. To create, bind, allocate,
initialize, deinitialize, and deallocate them, you have to extract
baseAddresses and counts.


On Thu, Jul 20, 2017 at 1:30 PM, Michael Ilseman  wrote:

> Looks awesome!
>
> Super minor tweak:
>
> > Right now, UnsafeMutableBufferPointer is kind of a black box when it
> comes to producing and modifying instances of it. To do anything except
> read the elements it contains, you have to extract baseAddresses and count
> s
>
>
> You can still modify and reassign elements through the subscript,
> iterators, MutableRandomAccessSlice, etc. The point here is that creating
> and setting it up is a big pain compared to UnsafeMutablePointer. It’s a
> little more fair to say “UnsafeMutableBufferPointer is unwieldy for
> creation, binding, allocation, and element-wise initialization compared to
> UnsafeMutablePointer."
>
> On Jul 19, 2017, at 6:04 PM, Taylor Swift  wrote:
>
> Revised the document with these suggestions, notably I clarified some of
> the language about memory safety, and specified that mutable overloads will
> only be added to UnsafeMutableBufferPointer and
> UnsafeMutableRawBufferPointer, not their plain variants. It also picks `
> repeating:` as the argument label to replace `to:` in functions like `
> initialize(to:count:)`.
>
> 
>
> On Tue, Jul 18, 2017 at 4:41 PM, Michael Ilseman 
> wrote:
>
>>
>>
>> I agree with all of Andy’s points. I really like this and think it’s a
>> good time to start discussing its details and moving from a pitch to a
>> proposal. Thank you for writing it!
>>
>> Minor tweak: say “deprecate” instead of “remove” for APIs, which has a
>> better connotation with respect to source compatibility. While I want to
>> have the best APIs, it’s important to make migration smooth. For example,
>> see https://github.com/apple/swift-evolution/blob/master/proposals/
>> 0180-string-index-overhaul.md#source-compatibility
>> 
>>
>> The main thing that I think needs to be massaged before a formal proposal
>> is the introduction and motivation section. It contains hyperbole that is
>> distracting and misleading. Some examples:
>>
>> > Introduction
>> > …
>> > but the current API design is not very safe, consistent, or convenient.
>>
>>
>> This proposal does not address “safe” or unsafety. I think the proposal
>> is very good and important for addressing consistency and convenience,
>> which help encourage programmers to use APIs correctly, but “not very safe”
>> is orthogonal to the proposal.
>>
>> > In some places, this design turns UnsafePointers into
>> outright DangerousPointers, leading users to believe that they have
>> allocated or freed memory when in fact, they have not.
>>
>>
>> I see nothing in this proposal that identifies, nor address
>> UnsafePointers as being “DangerousPointers”. This proposal seeks to change
>> idiomatic use to be more consistent and convenient, which is very
>> important, but does not change what “Unsafe” means in Swift. Near as I can
>> tell, the semantics and “dangerousness" of Unsafe*Pointers are unchanged by
>> this proposal.
>>
>> > The current API suffers from inconsistent naming, poor usage of default
>> argument values, missing methods, and excessive verbosity, and encourages
>> excessively unsafe programming practices.
>>
>>
>> I agree with everything up until “excessively unsafe programming
>> practices”. What do you mean by “unsafe”? What practice is that? It seems
>> like you might have a very different definition of Unsafe than Swift does.
>> If so, then this will be a very different sort of proposal and you should
>> identify what you mean by “unsafe”.
>>
>> > This proposal seeks to iron out these inconsistencies, and offer a more
>> convenient, more sensible, and less bug-prone API for Swift pointers.
>>
>>
>> 100% agree and I’m super enthusiastic for this proposal for this reason!
>> My main feedback is to align the motivation and pitch with the message,
>> unless you really do have a different definition of “unsafe” that you’re
>> wanting to pitch.
>>
>> > This results in an equally elegant API with about one-third less
>> surface area.
>>
>>
>> 🎉
>>
>> > Motivation:
>> > Right now, UnsafeMutableBufferPointer is kind of a black box. To do
>> anything with the memory block it represents, you have to extract
>> baseAddresses and counts. This is unfortunate because
>> UnsafeMutableBufferPointer provides a handy container for tracking the size
>> of a memory buffer, but to actually make use of this information, the
>> buffer pointer must be disassembled.
>>
>>
>> Note that Unsafe*BufferPointer conforms to RandomAccessCollection and
>> thus gets all the same conveniences of anything else that is Array-like.
>> This means that after it has been properly alloc

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-20 Thread Michael Ilseman via swift-evolution
Looks awesome!

Super minor tweak:

> > Right now, UnsafeMutableBufferPointer is kind of a black box when it comes 
> > to producing and modifying instances of it. To do anything except read the 
> > elements it contains, you have to extract baseAddresses and counts


You can still modify and reassign elements through the subscript, iterators, 
MutableRandomAccessSlice, etc. The point here is that creating and setting it 
up is a big pain compared to UnsafeMutablePointer. It’s a little more fair to 
say “UnsafeMutableBufferPointer is unwieldy for creation, binding, allocation, 
and element-wise initialization compared to UnsafeMutablePointer."

> On Jul 19, 2017, at 6:04 PM, Taylor Swift  wrote:
> 
> Revised the document with these suggestions, notably I clarified some of the 
> language about memory safety, and specified that mutable overloads will only 
> be added to UnsafeMutableBufferPointer and UnsafeMutableRawBufferPointer, not 
> their plain variants. It also picks `repeating:` as the argument label to 
> replace `to:` in functions like `initialize(to:count:)`.
> 
>  >
> 
> On Tue, Jul 18, 2017 at 4:41 PM, Michael Ilseman  > wrote:
> 
> 
> I agree with all of Andy’s points. I really like this and think it’s a good 
> time to start discussing its details and moving from a pitch to a proposal. 
> Thank you for writing it!
> 
> Minor tweak: say “deprecate” instead of “remove” for APIs, which has a better 
> connotation with respect to source compatibility. While I want to have the 
> best APIs, it’s important to make migration smooth. For example, see 
> https://github.com/apple/swift- 
> evolution/blob/master/proposals/0180-string-index-overhaul.md#source-compatibility
>  
> 
> The main thing that I think needs to be massaged before a formal proposal is 
> the introduction and motivation section. It contains hyperbole that is 
> distracting and misleading. Some examples:
> 
>> > Introduction
>> > …
>> > but the current API design is not very safe, consistent, or convenient.
> 
> This proposal does not address “safe” or unsafety. I think the proposal is 
> very good and important for addressing consistency and convenience, which 
> help encourage programmers to use APIs correctly, but “not very safe” is 
> orthogonal to the proposal.
> 
>> > In some places, this design turns UnsafePointers into outright 
>> > DangerousPointers, leading users to believe that they have allocated or 
>> > freed memory when in fact, they have not.
> 
> I see nothing in this proposal that identifies, nor address UnsafePointers as 
> being “DangerousPointers”. This proposal seeks to change idiomatic use to be 
> more consistent and convenient, which is very important, but does not change 
> what “Unsafe” means in Swift. Near as I can tell, the semantics and 
> “dangerousness" of Unsafe*Pointers are unchanged by this proposal.
> 
>> > The current API suffers from inconsistent naming, poor usage of default 
>> > argument values, missing methods, and excessive verbosity, and encourages 
>> > excessively unsafe programming practices. 
> 
> I agree with everything up until “excessively unsafe programming practices”. 
> What do you mean by “unsafe”? What practice is that? It seems like you might 
> have a very different definition of Unsafe than Swift does. If so, then this 
> will be a very different sort of proposal and you should identify what you 
> mean by “unsafe”.
> 
>> > This proposal seeks to iron out these inconsistencies, and offer a more 
>> > convenient, more sensible, and less bug-prone API for Swift pointers.
> 
> 100% agree and I’m super enthusiastic for this proposal for this reason! My 
> main feedback is to align the motivation and pitch with the message, unless 
> you really do have a different definition of “unsafe” that you’re wanting to 
> pitch.
> 
>> > This results in an equally elegant API with about one-third less surface 
>> > area.
> 
> 🎉
> 
>> > Motivation:
>> > Right now, UnsafeMutableBufferPointer is kind of a black box. To do 
>> > anything with the memory block it represents, you have to extract 
>> > baseAddresses and counts. This is unfortunate because 
>> > UnsafeMutableBufferPointer provides a handy container for tracking the 
>> > size of a memory buffer, but to actually make use of this information, the 
>> > buffer pointer must be disassembled.
> 
> Note that Unsafe*BufferPointer conforms to RandomAccessCollection and thus 
> gets all the same conveniences of anything else that is Array-like. This 
> means that after it has been properly allocated, initialized, and 
> pointer-casted, it is very convenient for consumers of Unsafe*BufferPointers. 
> The main pain points, and this proposal is excellent at addressing, are on 
> the producers o

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-19 Thread Taylor Swift via swift-evolution
Revised the document with these suggestions, notably I clarified some of
the language about memory safety, and specified that mutable overloads will
only be added to UnsafeMutableBufferPointer and
UnsafeMutableRawBufferPointer, not their plain variants. It also picks `
repeating:` as the argument label to replace `to:` in functions like `
initialize(to:count:)`.



On Tue, Jul 18, 2017 at 4:41 PM, Michael Ilseman  wrote:

>
>
> I agree with all of Andy’s points. I really like this and think it’s a
> good time to start discussing its details and moving from a pitch to a
> proposal. Thank you for writing it!
>
> Minor tweak: say “deprecate” instead of “remove” for APIs, which has a
> better connotation with respect to source compatibility. While I want to
> have the best APIs, it’s important to make migration smooth. For example,
> see https://github.com/apple/swift-evolution/blob/master/proposals/
> 0180-string-index-overhaul.md#source-compatibility
>
> The main thing that I think needs to be massaged before a formal proposal
> is the introduction and motivation section. It contains hyperbole that is
> distracting and misleading. Some examples:
>
> > Introduction
> > …
> > but the current API design is not very safe, consistent, or convenient.
>
>
> This proposal does not address “safe” or unsafety. I think the proposal is
> very good and important for addressing consistency and convenience, which
> help encourage programmers to use APIs correctly, but “not very safe” is
> orthogonal to the proposal.
>
> > In some places, this design turns UnsafePointers into
> outright DangerousPointers, leading users to believe that they have
> allocated or freed memory when in fact, they have not.
>
>
> I see nothing in this proposal that identifies, nor address UnsafePointers
> as being “DangerousPointers”. This proposal seeks to change idiomatic use
> to be more consistent and convenient, which is very important, but does not
> change what “Unsafe” means in Swift. Near as I can tell, the semantics and
> “dangerousness" of Unsafe*Pointers are unchanged by this proposal.
>
> > The current API suffers from inconsistent naming, poor usage of default
> argument values, missing methods, and excessive verbosity, and encourages
> excessively unsafe programming practices.
>
>
> I agree with everything up until “excessively unsafe programming
> practices”. What do you mean by “unsafe”? What practice is that? It seems
> like you might have a very different definition of Unsafe than Swift does.
> If so, then this will be a very different sort of proposal and you should
> identify what you mean by “unsafe”.
>
> > This proposal seeks to iron out these inconsistencies, and offer a more
> convenient, more sensible, and less bug-prone API for Swift pointers.
>
>
> 100% agree and I’m super enthusiastic for this proposal for this reason!
> My main feedback is to align the motivation and pitch with the message,
> unless you really do have a different definition of “unsafe” that you’re
> wanting to pitch.
>
> > This results in an equally elegant API with about one-third less surface
> area.
>
>
> 🎉
>
> > Motivation:
> > Right now, UnsafeMutableBufferPointer is kind of a black box. To do
> anything with the memory block it represents, you have to extract
> baseAddresses and counts. This is unfortunate because
> UnsafeMutableBufferPointer provides a handy container for tracking the size
> of a memory buffer, but to actually make use of this information, the
> buffer pointer must be disassembled.
>
>
> Note that Unsafe*BufferPointer conforms to RandomAccessCollection and thus
> gets all the same conveniences of anything else that is Array-like. This
> means that after it has been properly allocated, initialized, and
> pointer-casted, it is very convenient for *consumers* of 
> Unsafe*BufferPointers.
> The main pain points, and this proposal is excellent at addressing, are on
> the *producers* of Unsafe*BufferPointers. For producers, there are a lot
> of rules and hoops to jump through and the APIs are not conveniently
> aligned with them. I do think you’ve done a great job of correctly
> identifying the pain points for people who need to produce
> Unsafe*BufferPointers.
>
> The rest of the motivation section is excellent! I have done every single
> “idiom” you highlight and hated having to do it.
>
>
> On Jul 18, 2017, at 11:19 AM, Andrew Trick via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> On Jul 17, 2017, at 10:06 PM, Taylor Swift via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> I’ve drafted a new version of the unsafe pointer proposal based on
> feedback I’ve gotten from this thread. You can read it here
> .
>
> ~~~
>
> Swift’s pointer types are an important interface for low-level memory
> manipulation, but the current API design is not very safe, consistent, or
> convenient. M

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-19 Thread Taylor Swift via swift-evolution
I don’t really have a strong preference between either `repeating:` or `
value:`, this all kind of seems like bikeshedding to me tbh. If I had to
pick one, I’d pick `repeating:` though because that’s what `
Array.init(repeating:count:)` uses, even if it makes a lot of calls sound a
little weird. `ptr.initialize(repeating: value)` isn’t wrong
, it just happens
to be repeated once.

More important I think is the immutable buffer pointer overloads for `
initialize(from:)` and `assign(from:)`. Currently the compiler doesn’t
recognize `UnsafeBufferPointer` as a subtype of `UnsafeMutableBufferPointer`.
Idk if it’s worth waiting for this to get added to the compiler, or just
cover it in the standard library.

On Wed, Jul 19, 2017 at 2:47 PM, Andrew Trick  wrote:

>
> On Jul 19, 2017, at 11:13 AM, Taylor Swift  wrote:
>
> What about `value:`?
>
> `ptr.initialize(value: value)`
> `ptr.initialize(value: value, count: 13)`
> `ptr.initialize(as: UInt16.self, at: 0, value: value, count: 13)`
>
>
> Works for me if it’s reasonably consistent with the rest of the stdlib. I
> don’t know why `value` was avoided in the first place.
> -Andy
>
> On Wed, Jul 19, 2017 at 12:01 PM, Andrew Trick  wrote:
>
>>
>> On Jul 18, 2017, at 9:42 PM, Taylor Swift  wrote:
>>
>> How do we feel about changing the label to `repeated:`, even in cases
>> where `count:` is 1?
>>
>> This would mean that calls would read like this: `ptr.initialize(repeated:
>> value)`
>>
>>
>> Right. Given the default `count` of 1, it’s probably best to stick with
>> `to: value`.
>> -Andy
>>
>>
>> A grep through the stdlib shows that this is by far the most common use
>> case:
>>
>> swift-source/swift$ grep initialize\(to: . -r
>> ./stdlib/private/SwiftPrivatePthreadExtras/SwiftPrivatePthreadExtras.swift:
>> result.initialize(to: block(arg))
>> ./stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.swift:
>> ptr.initialize(to: x)
>> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
>> anyPointer.initialize(to: any)
>> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
>> fn.initialize(to: ThickFunction0(function: function))
>> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
>> fn.initialize(to: ThickFunction1(function: function))
>> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
>> fn.initialize(to: ThickFunction2(function: function))
>> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
>> fn.initialize(to: ThickFunction3(function: function))
>> ./stdlib/private/SwiftPrivate/ShardedAtomicCounter.swift:  (shards +
>> i).initialize(to: 0)
>> ./stdlib/public/SDK/Foundation/NSError.swift:out.initialize(to:
>> bridged)
>> ./stdlib/public/core/UnsafeRawPointer.swift.gyb://
>> (self.assumingMemoryBound(to: T.self) + i).initialize(to: source[i])
>> ./stdlib/public/core/UnsafeRawPointer.swift.gyb:  //
>> .initialize(to: (source + i).move())
>> ./stdlib/public/core/UnsafeRawPointer.swift.gyb:  //
>> (--dst).initialize(to: (--src).move())
>> ./stdlib/public/core/Arrays.swift.gyb:  p.initialize(to:
>> repeatedValue)
>> ./stdlib/public/core/Arrays.swift.gyb:(_buffer.firstElementAddress +
>> oldCount).initialize(to: newElement)
>> ./stdlib/public/core/Arrays.swift.gyb:p.initialize(to: x)
>> ./stdlib/public/core/Arrays.swift.gyb:  p.initialize(to:
>> newValues[q])
>> ./stdlib/public/core/Arrays.swift.gyb:(base +
>> newCount).initialize(to: next)
>> ./stdlib/public/core/AnyHashable.swift:result.initialize(to: value)
>> ./stdlib/public/core/AnyHashable.swift:result.initialize(to:
>> value)
>> ./stdlib/public/core/AnyHashable.swift:  target.initialize(to:
>> AnyHashable(value))
>> ./stdlib/public/core/ArrayCast.swift:  target.initialize(to:
>> _arrayForceCast(source.pointee))
>> ./stdlib/public/core/ArrayCast.swift:target.initialize(to: result)
>> ./stdlib/public/core/ContiguousArrayBuffer.swift:  (resultPtr +
>> i).initialize(to: _bridgeAnythingToObjectiveC(p[i]))
>> ./stdlib/public/core/ContiguousArrayBuffer.swift:p.initialize(to:
>> source[i])
>> ./stdlib/public/core/ContiguousArrayBuffer.swift:p.initialize(to:
>> element)
>> ./stdlib/public/core/ArrayBuffer.swift:  result.initialize(to:
>> result.pointee)
>> ./stdlib/public/core/HashedCollections.swift.gyb:  target.initialize(to:
>> _setDownCast(source.pointee))
>> ./stdlib/public/core/HashedCollections.swift.gyb:
>> target.initialize(to: result)
>> ./stdlib/public/core/HashedCollections.swift.gyb:  target.initialize(to:
>> _dictionaryDownCast(source.pointee))
>> ./stdlib/public/core/HashedCollections.swift.gyb:
>> target.initialize(to: result)
>> ./stdlib/public/core/HashedCollections.swift.gyb:(keys +
>> i).initialize(to: k)
>> ./stdlib/public/core/HashedCollections.swift.gyb:(keys +
>> toEntryAt).initialize(to: (from.keys + at).move())
>> ./stdlib/public/core/HashedCollections.swift.gyb:(keys +
>> i).initiali

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-19 Thread Andrew Trick via swift-evolution

> On Jul 19, 2017, at 12:11 PM, Taylor Swift  wrote:
> 
> More important I think is the immutable buffer pointer overloads for 
> `initialize(from:)` and `assign(from:)`. Currently the compiler doesn’t 
> recognize `UnsafeBufferPointer` as a subtype of `UnsafeMutableBufferPointer`. 
> Idk if it’s worth waiting for this to get added to the compiler, or just 
> cover it in the standard library.

There are no plans to add this support to the compiler. For now, the the 
necessary overloads should be added to the standard library.

Sorry if I caused confusion over the implicit casting support. That’s really 
meant to handle `inout` references to variables but happens to work for 
UnsafeMutablePointer->UnsafePointer.

-Andy___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-19 Thread Andrew Trick via swift-evolution

> On Jul 19, 2017, at 11:13 AM, Taylor Swift  wrote:
> 
> What about `value:`?
> 
> `ptr.initialize(value: value)`
> `ptr.initialize(value: value, count: 13)`
> `ptr.initialize(as: UInt16.self, at: 0, value: value, count: 13)`

Works for me if it’s reasonably consistent with the rest of the stdlib. I don’t 
know why `value` was avoided in the first place.
-Andy

> On Wed, Jul 19, 2017 at 12:01 PM, Andrew Trick  > wrote:
> 
>> On Jul 18, 2017, at 9:42 PM, Taylor Swift > > wrote:
>> 
>> How do we feel about changing the label to `repeated:`, even in cases where 
>> `count:` is 1?
>> 
>> This would mean that calls would read like this: `ptr.initialize(repeated: 
>> value)`
> 
> Right. Given the default `count` of 1, it’s probably best to stick with `to: 
> value`.
> -Andy
> 
>> 
>> A grep through the stdlib shows that this is by far the most common use case:
>> 
>> swift-source/swift$ grep initialize\(to: . -r
>> ./stdlib/private/SwiftPrivatePthreadExtras/SwiftPrivatePthreadExtras.swift:  
>>   result.initialize(to: block(arg))
>> ./stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.swift:  
>> ptr.initialize(to: x)
>> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:  
>> anyPointer.initialize(to: any)
>> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:  
>> fn.initialize(to: ThickFunction0(function: function))
>> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:  
>> fn.initialize(to: ThickFunction1(function: function))
>> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:  
>> fn.initialize(to: ThickFunction2(function: function))
>> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:  
>> fn.initialize(to: ThickFunction3(function: function))
>> ./stdlib/private/SwiftPrivate/ShardedAtomicCounter.swift:  (shards + 
>> i).initialize(to: 0)
>> ./stdlib/public/SDK/Foundation/NSError.swift:out.initialize(to: bridged)
>> ./stdlib/public/core/UnsafeRawPointer.swift.gyb://   
>> (self.assumingMemoryBound(to: T.self) + i).initialize(to: source[i])
>> ./stdlib/public/core/UnsafeRawPointer.swift.gyb:  //   .initialize(to: 
>> (source + i).move())
>> ./stdlib/public/core/UnsafeRawPointer.swift.gyb:  //   
>> (--dst).initialize(to: (--src).move())
>> ./stdlib/public/core/Arrays.swift.gyb:  p.initialize(to: repeatedValue)
>> ./stdlib/public/core/Arrays.swift.gyb:(_buffer.firstElementAddress + 
>> oldCount).initialize(to: newElement)
>> ./stdlib/public/core/Arrays.swift.gyb:p.initialize(to: x)
>> ./stdlib/public/core/Arrays.swift.gyb:  p.initialize(to: newValues[q])
>> ./stdlib/public/core/Arrays.swift.gyb:(base + 
>> newCount).initialize(to: next)
>> ./stdlib/public/core/AnyHashable.swift:result.initialize(to: value)
>> ./stdlib/public/core/AnyHashable.swift:result.initialize(to: value)
>> ./stdlib/public/core/AnyHashable.swift:  target.initialize(to: 
>> AnyHashable(value))
>> ./stdlib/public/core/ArrayCast.swift:  target.initialize(to: 
>> _arrayForceCast(source.pointee))
>> ./stdlib/public/core/ArrayCast.swift:target.initialize(to: result)
>> ./stdlib/public/core/ContiguousArrayBuffer.swift:  (resultPtr + 
>> i).initialize(to: _bridgeAnythingToObjectiveC(p[i]))
>> ./stdlib/public/core/ContiguousArrayBuffer.swift:p.initialize(to: 
>> source[i])
>> ./stdlib/public/core/ContiguousArrayBuffer.swift:p.initialize(to: 
>> element)
>> ./stdlib/public/core/ArrayBuffer.swift:  result.initialize(to: 
>> result.pointee)
>> ./stdlib/public/core/HashedCollections.swift.gyb:  target.initialize(to: 
>> _setDownCast(source.pointee))
>> ./stdlib/public/core/HashedCollections.swift.gyb:target.initialize(to: 
>> result)
>> ./stdlib/public/core/HashedCollections.swift.gyb:  target.initialize(to: 
>> _dictionaryDownCast(source.pointee))
>> ./stdlib/public/core/HashedCollections.swift.gyb:target.initialize(to: 
>> result)
>> ./stdlib/public/core/HashedCollections.swift.gyb:(keys + 
>> i).initialize(to: k)
>> ./stdlib/public/core/HashedCollections.swift.gyb:(keys + 
>> toEntryAt).initialize(to: (from.keys + at).move())
>> ./stdlib/public/core/HashedCollections.swift.gyb:(keys + 
>> i).initialize(to: k)
>> ./stdlib/public/core/HashedCollections.swift.gyb:(values + 
>> i).initialize(to: v)
>> ./stdlib/public/core/HashedCollections.swift.gyb:(keys + 
>> toEntryAt).initialize(to: (from.keys + at).move())
>> ./stdlib/public/core/HashedCollections.swift.gyb:(values + 
>> toEntryAt).initialize(to: (from.values + at).move())
>> ./stdlib/public/core/ReflectionLegacy.swift:  out.initialize(to: 
>> String(reflecting: x))
>> 
>> ./stdlib/public/core/ManagedBuffer.swift:p.headerAddress.initialize(to: 
>> initHeaderVal)
>> ./stdlib/public/core/ManagedBuffer.swift:  $0.initialize(to: 
>> ./stdlib/public/core/ArrayBufferProtocol.swift:(elements + 
>> j).initialize(to: newValues[i])
>> ./stdlib/public/core/Se

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-19 Thread Taylor Swift via swift-evolution
What about `value:`?

`ptr.initialize(value: value)`
`ptr.initialize(value: value, count: 13)`
`ptr.initialize(as: UInt16.self, at: 0, value: value, count: 13)`

On Wed, Jul 19, 2017 at 12:01 PM, Andrew Trick  wrote:

>
> On Jul 18, 2017, at 9:42 PM, Taylor Swift  wrote:
>
> How do we feel about changing the label to `repeated:`, even in cases
> where `count:` is 1?
>
> This would mean that calls would read like this: `ptr.initialize(repeated:
> value)`
>
>
> Right. Given the default `count` of 1, it’s probably best to stick with
> `to: value`.
> -Andy
>
>
> A grep through the stdlib shows that this is by far the most common use
> case:
>
> swift-source/swift$ grep initialize\(to: . -r
> ./stdlib/private/SwiftPrivatePthreadExtras/SwiftPrivatePthreadExtras.swift:
> result.initialize(to: block(arg))
> ./stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.swift:
> ptr.initialize(to: x)
> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
> anyPointer.initialize(to: any)
> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
> fn.initialize(to: ThickFunction0(function: function))
> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
> fn.initialize(to: ThickFunction1(function: function))
> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
> fn.initialize(to: ThickFunction2(function: function))
> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
> fn.initialize(to: ThickFunction3(function: function))
> ./stdlib/private/SwiftPrivate/ShardedAtomicCounter.swift:  (shards +
> i).initialize(to: 0)
> ./stdlib/public/SDK/Foundation/NSError.swift:out.initialize(to:
> bridged)
> ./stdlib/public/core/UnsafeRawPointer.swift.gyb://
> (self.assumingMemoryBound(to: T.self) + i).initialize(to: source[i])
> ./stdlib/public/core/UnsafeRawPointer.swift.gyb:  //
> .initialize(to: (source + i).move())
> ./stdlib/public/core/UnsafeRawPointer.swift.gyb:  //
> (--dst).initialize(to: (--src).move())
> ./stdlib/public/core/Arrays.swift.gyb:  p.initialize(to:
> repeatedValue)
> ./stdlib/public/core/Arrays.swift.gyb:(_buffer.firstElementAddress +
> oldCount).initialize(to: newElement)
> ./stdlib/public/core/Arrays.swift.gyb:p.initialize(to: x)
> ./stdlib/public/core/Arrays.swift.gyb:  p.initialize(to: newValues[q])
> ./stdlib/public/core/Arrays.swift.gyb:(base +
> newCount).initialize(to: next)
> ./stdlib/public/core/AnyHashable.swift:result.initialize(to: value)
> ./stdlib/public/core/AnyHashable.swift:result.initialize(to:
> value)
> ./stdlib/public/core/AnyHashable.swift:  target.initialize(to:
> AnyHashable(value))
> ./stdlib/public/core/ArrayCast.swift:  target.initialize(to:
> _arrayForceCast(source.pointee))
> ./stdlib/public/core/ArrayCast.swift:target.initialize(to: result)
> ./stdlib/public/core/ContiguousArrayBuffer.swift:  (resultPtr +
> i).initialize(to: _bridgeAnythingToObjectiveC(p[i]))
> ./stdlib/public/core/ContiguousArrayBuffer.swift:p.initialize(to:
> source[i])
> ./stdlib/public/core/ContiguousArrayBuffer.swift:p.initialize(to:
> element)
> ./stdlib/public/core/ArrayBuffer.swift:  result.initialize(to:
> result.pointee)
> ./stdlib/public/core/HashedCollections.swift.gyb:  target.initialize(to:
> _setDownCast(source.pointee))
> ./stdlib/public/core/HashedCollections.swift.gyb:
> target.initialize(to: result)
> ./stdlib/public/core/HashedCollections.swift.gyb:  target.initialize(to:
> _dictionaryDownCast(source.pointee))
> ./stdlib/public/core/HashedCollections.swift.gyb:
> target.initialize(to: result)
> ./stdlib/public/core/HashedCollections.swift.gyb:(keys +
> i).initialize(to: k)
> ./stdlib/public/core/HashedCollections.swift.gyb:(keys +
> toEntryAt).initialize(to: (from.keys + at).move())
> ./stdlib/public/core/HashedCollections.swift.gyb:(keys +
> i).initialize(to: k)
> ./stdlib/public/core/HashedCollections.swift.gyb:(values +
> i).initialize(to: v)
> ./stdlib/public/core/HashedCollections.swift.gyb:(keys +
> toEntryAt).initialize(to: (from.keys + at).move())
> ./stdlib/public/core/HashedCollections.swift.gyb:(values +
> toEntryAt).initialize(to: (from.values + at).move())
> ./stdlib/public/core/ReflectionLegacy.swift:  out.initialize(to:
> String(reflecting: x))
>
> ./stdlib/public/core/ManagedBuffer.swift:
> p.headerAddress.initialize(to: initHeaderVal)
> ./stdlib/public/core/ManagedBuffer.swift:  $0.initialize(to:
> ./stdlib/public/core/ArrayBufferProtocol.swift:(elements +
> j).initialize(to: newValues[i])
> ./stdlib/public/core/Sequence.swift:ptr.initialize(to: x)
> ./stdlib/public/core/HeapBuffer.swift:  $0.initialize(to:
> Header(initializer))
> ./stdlib/public/core/UnsafeBitMap.swift:values.initialize(to: 0,
> count: numberOfWords)
> ./stdlib/public/core/String.swift:resultStorage.initialize(to:
> ./test/api-digester/stdlib-stable.json:  "printedName":
> "initialize(to:count:)",
> ./test/Generics/sl

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-19 Thread Andrew Trick via swift-evolution

> On Jul 18, 2017, at 9:42 PM, Taylor Swift  wrote:
> 
> How do we feel about changing the label to `repeated:`, even in cases where 
> `count:` is 1?
> 
> This would mean that calls would read like this: `ptr.initialize(repeated: 
> value)`

Right. Given the default `count` of 1, it’s probably best to stick with `to: 
value`.
-Andy
> 
> A grep through the stdlib shows that this is by far the most common use case:
> 
> swift-source/swift$ grep initialize\(to: . -r
> ./stdlib/private/SwiftPrivatePthreadExtras/SwiftPrivatePthreadExtras.swift:   
>  result.initialize(to: block(arg))
> ./stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.swift:  
> ptr.initialize(to: x)
> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:  
> anyPointer.initialize(to: any)
> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:  
> fn.initialize(to: ThickFunction0(function: function))
> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:  
> fn.initialize(to: ThickFunction1(function: function))
> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:  
> fn.initialize(to: ThickFunction2(function: function))
> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:  
> fn.initialize(to: ThickFunction3(function: function))
> ./stdlib/private/SwiftPrivate/ShardedAtomicCounter.swift:  (shards + 
> i).initialize(to: 0)
> ./stdlib/public/SDK/Foundation/NSError.swift:out.initialize(to: bridged)
> ./stdlib/public/core/UnsafeRawPointer.swift.gyb://   
> (self.assumingMemoryBound(to: T.self) + i).initialize(to: source[i])
> ./stdlib/public/core/UnsafeRawPointer.swift.gyb:  //   .initialize(to: 
> (source + i).move())
> ./stdlib/public/core/UnsafeRawPointer.swift.gyb:  //   
> (--dst).initialize(to: (--src).move())
> ./stdlib/public/core/Arrays.swift.gyb:  p.initialize(to: repeatedValue)
> ./stdlib/public/core/Arrays.swift.gyb:(_buffer.firstElementAddress + 
> oldCount).initialize(to: newElement)
> ./stdlib/public/core/Arrays.swift.gyb:p.initialize(to: x)
> ./stdlib/public/core/Arrays.swift.gyb:  p.initialize(to: newValues[q])
> ./stdlib/public/core/Arrays.swift.gyb:(base + 
> newCount).initialize(to: next)
> ./stdlib/public/core/AnyHashable.swift:result.initialize(to: value)
> ./stdlib/public/core/AnyHashable.swift:result.initialize(to: value)
> ./stdlib/public/core/AnyHashable.swift:  target.initialize(to: 
> AnyHashable(value))
> ./stdlib/public/core/ArrayCast.swift:  target.initialize(to: 
> _arrayForceCast(source.pointee))
> ./stdlib/public/core/ArrayCast.swift:target.initialize(to: result)
> ./stdlib/public/core/ContiguousArrayBuffer.swift:  (resultPtr + 
> i).initialize(to: _bridgeAnythingToObjectiveC(p[i]))
> ./stdlib/public/core/ContiguousArrayBuffer.swift:p.initialize(to: 
> source[i])
> ./stdlib/public/core/ContiguousArrayBuffer.swift:p.initialize(to: element)
> ./stdlib/public/core/ArrayBuffer.swift:  result.initialize(to: 
> result.pointee)
> ./stdlib/public/core/HashedCollections.swift.gyb:  target.initialize(to: 
> _setDownCast(source.pointee))
> ./stdlib/public/core/HashedCollections.swift.gyb:target.initialize(to: 
> result)
> ./stdlib/public/core/HashedCollections.swift.gyb:  target.initialize(to: 
> _dictionaryDownCast(source.pointee))
> ./stdlib/public/core/HashedCollections.swift.gyb:target.initialize(to: 
> result)
> ./stdlib/public/core/HashedCollections.swift.gyb:(keys + 
> i).initialize(to: k)
> ./stdlib/public/core/HashedCollections.swift.gyb:(keys + 
> toEntryAt).initialize(to: (from.keys + at).move())
> ./stdlib/public/core/HashedCollections.swift.gyb:(keys + 
> i).initialize(to: k)
> ./stdlib/public/core/HashedCollections.swift.gyb:(values + 
> i).initialize(to: v)
> ./stdlib/public/core/HashedCollections.swift.gyb:(keys + 
> toEntryAt).initialize(to: (from.keys + at).move())
> ./stdlib/public/core/HashedCollections.swift.gyb:(values + 
> toEntryAt).initialize(to: (from.values + at).move())
> ./stdlib/public/core/ReflectionLegacy.swift:  out.initialize(to: 
> String(reflecting: x))
> 
> ./stdlib/public/core/ManagedBuffer.swift:p.headerAddress.initialize(to: 
> initHeaderVal)
> ./stdlib/public/core/ManagedBuffer.swift:  $0.initialize(to: 
> ./stdlib/public/core/ArrayBufferProtocol.swift:(elements + 
> j).initialize(to: newValues[i])
> ./stdlib/public/core/Sequence.swift:ptr.initialize(to: x)
> ./stdlib/public/core/HeapBuffer.swift:  $0.initialize(to: 
> Header(initializer))
> ./stdlib/public/core/UnsafeBitMap.swift:values.initialize(to: 0, count: 
> numberOfWords)
> ./stdlib/public/core/String.swift:resultStorage.initialize(to: 
> ./test/api-digester/stdlib-stable.json:  "printedName": 
> "initialize(to:count:)",
> ./test/Generics/slice_test.swift:(newbase + i).initialize(to: 
> (base+i).move())
> ./test/Generics/slice_test.swift:(base+length).initialize(to: elem)
> ./test/Parse/pointer_con

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-18 Thread Xiaodi Wu via swift-evolution
FWIW, the label should be "repeating".

On Tue, Jul 18, 2017 at 11:42 PM, Taylor Swift via swift-evolution <
swift-evolution@swift.org> wrote:

> How do we feel about changing the label to `repeated:`, even in cases
> where `count:` is 1?
>
> This would mean that calls would read like this: `ptr.initialize(repeated:
> value)`
>
> A grep through the stdlib shows that this is by far the most common use
> case:
>
> swift-source/swift$ grep initialize\(to: . -r
> ./stdlib/private/SwiftPrivatePthreadExtras/SwiftPrivatePthreadExtras.swift:
> result.initialize(to: block(arg))
> ./stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.swift:
> ptr.initialize(to: x)
> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
> anyPointer.initialize(to: any)
> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
> fn.initialize(to: ThickFunction0(function: function))
> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
> fn.initialize(to: ThickFunction1(function: function))
> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
> fn.initialize(to: ThickFunction2(function: function))
> ./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
> fn.initialize(to: ThickFunction3(function: function))
> ./stdlib/private/SwiftPrivate/ShardedAtomicCounter.swift:  (shards +
> i).initialize(to: 0)
> ./stdlib/public/SDK/Foundation/NSError.swift:out.initialize(to:
> bridged)
> ./stdlib/public/core/UnsafeRawPointer.swift.gyb://
> (self.assumingMemoryBound(to: T.self) + i).initialize(to: source[i])
> ./stdlib/public/core/UnsafeRawPointer.swift.gyb:  //
> .initialize(to: (source + i).move())
> ./stdlib/public/core/UnsafeRawPointer.swift.gyb:  //
> (--dst).initialize(to: (--src).move())
> ./stdlib/public/core/Arrays.swift.gyb:  p.initialize(to:
> repeatedValue)
> ./stdlib/public/core/Arrays.swift.gyb:(_buffer.firstElementAddress +
> oldCount).initialize(to: newElement)
> ./stdlib/public/core/Arrays.swift.gyb:p.initialize(to: x)
> ./stdlib/public/core/Arrays.swift.gyb:  p.initialize(to: newValues[q])
> ./stdlib/public/core/Arrays.swift.gyb:(base +
> newCount).initialize(to: next)
> ./stdlib/public/core/AnyHashable.swift:result.initialize(to: value)
> ./stdlib/public/core/AnyHashable.swift:result.initialize(to:
> value)
> ./stdlib/public/core/AnyHashable.swift:  target.initialize(to:
> AnyHashable(value))
> ./stdlib/public/core/ArrayCast.swift:  target.initialize(to:
> _arrayForceCast(source.pointee))
> ./stdlib/public/core/ArrayCast.swift:target.initialize(to: result)
> ./stdlib/public/core/ContiguousArrayBuffer.swift:  (resultPtr +
> i).initialize(to: _bridgeAnythingToObjectiveC(p[i]))
> ./stdlib/public/core/ContiguousArrayBuffer.swift:p.initialize(to:
> source[i])
> ./stdlib/public/core/ContiguousArrayBuffer.swift:p.initialize(to:
> element)
> ./stdlib/public/core/ArrayBuffer.swift:  result.initialize(to:
> result.pointee)
> ./stdlib/public/core/HashedCollections.swift.gyb:  target.initialize(to:
> _setDownCast(source.pointee))
> ./stdlib/public/core/HashedCollections.swift.gyb:
> target.initialize(to: result)
> ./stdlib/public/core/HashedCollections.swift.gyb:  target.initialize(to:
> _dictionaryDownCast(source.pointee))
> ./stdlib/public/core/HashedCollections.swift.gyb:
> target.initialize(to: result)
> ./stdlib/public/core/HashedCollections.swift.gyb:(keys +
> i).initialize(to: k)
> ./stdlib/public/core/HashedCollections.swift.gyb:(keys +
> toEntryAt).initialize(to: (from.keys + at).move())
> ./stdlib/public/core/HashedCollections.swift.gyb:(keys +
> i).initialize(to: k)
> ./stdlib/public/core/HashedCollections.swift.gyb:(values +
> i).initialize(to: v)
> ./stdlib/public/core/HashedCollections.swift.gyb:(keys +
> toEntryAt).initialize(to: (from.keys + at).move())
> ./stdlib/public/core/HashedCollections.swift.gyb:(values +
> toEntryAt).initialize(to: (from.values + at).move())
> ./stdlib/public/core/ReflectionLegacy.swift:  out.initialize(to:
> String(reflecting: x))
>
> ./stdlib/public/core/ManagedBuffer.swift:
> p.headerAddress.initialize(to: initHeaderVal)
> ./stdlib/public/core/ManagedBuffer.swift:  $0.initialize(to:
> ./stdlib/public/core/ArrayBufferProtocol.swift:(elements +
> j).initialize(to: newValues[i])
> ./stdlib/public/core/Sequence.swift:ptr.initialize(to: x)
> ./stdlib/public/core/HeapBuffer.swift:  $0.initialize(to:
> Header(initializer))
> ./stdlib/public/core/UnsafeBitMap.swift:values.initialize(to: 0,
> count: numberOfWords)
> ./stdlib/public/core/String.swift:resultStorage.initialize(to:
> ./test/api-digester/stdlib-stable.json:  "printedName":
> "initialize(to:count:)",
> ./test/Generics/slice_test.swift:(newbase + i).initialize(to:
> (base+i).move())
> ./test/Generics/slice_test.swift:(base+length).initialize(to: elem)
> ./test/Parse/pointer_conversion.swift.gyb:  p.initialize(to: t)
>
> ./test/stdlib/Refl

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-18 Thread Taylor Swift via swift-evolution
How do we feel about changing the label to `repeated:`, even in cases where
`count:` is 1?

This would mean that calls would read like this: `ptr.initialize(repeated:
value)`

A grep through the stdlib shows that this is by far the most common use
case:

swift-source/swift$ grep initialize\(to: . -r
./stdlib/private/SwiftPrivatePthreadExtras/SwiftPrivatePthreadExtras.swift:
result.initialize(to: block(arg))
./stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.swift:
ptr.initialize(to: x)
./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
anyPointer.initialize(to: any)
./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
fn.initialize(to: ThickFunction0(function: function))
./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
fn.initialize(to: ThickFunction1(function: function))
./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
fn.initialize(to: ThickFunction2(function: function))
./stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:
fn.initialize(to: ThickFunction3(function: function))
./stdlib/private/SwiftPrivate/ShardedAtomicCounter.swift:  (shards +
i).initialize(to: 0)
./stdlib/public/SDK/Foundation/NSError.swift:out.initialize(to: bridged)
./stdlib/public/core/UnsafeRawPointer.swift.gyb://
(self.assumingMemoryBound(to: T.self) + i).initialize(to: source[i])
./stdlib/public/core/UnsafeRawPointer.swift.gyb:  //   .initialize(to:
(source + i).move())
./stdlib/public/core/UnsafeRawPointer.swift.gyb:  //
(--dst).initialize(to: (--src).move())
./stdlib/public/core/Arrays.swift.gyb:  p.initialize(to: repeatedValue)
./stdlib/public/core/Arrays.swift.gyb:(_buffer.firstElementAddress +
oldCount).initialize(to: newElement)
./stdlib/public/core/Arrays.swift.gyb:p.initialize(to: x)
./stdlib/public/core/Arrays.swift.gyb:  p.initialize(to: newValues[q])
./stdlib/public/core/Arrays.swift.gyb:(base +
newCount).initialize(to: next)
./stdlib/public/core/AnyHashable.swift:result.initialize(to: value)
./stdlib/public/core/AnyHashable.swift:result.initialize(to: value)
./stdlib/public/core/AnyHashable.swift:  target.initialize(to:
AnyHashable(value))
./stdlib/public/core/ArrayCast.swift:  target.initialize(to:
_arrayForceCast(source.pointee))
./stdlib/public/core/ArrayCast.swift:target.initialize(to: result)
./stdlib/public/core/ContiguousArrayBuffer.swift:  (resultPtr +
i).initialize(to: _bridgeAnythingToObjectiveC(p[i]))
./stdlib/public/core/ContiguousArrayBuffer.swift:p.initialize(to:
source[i])
./stdlib/public/core/ContiguousArrayBuffer.swift:p.initialize(to:
element)
./stdlib/public/core/ArrayBuffer.swift:  result.initialize(to:
result.pointee)
./stdlib/public/core/HashedCollections.swift.gyb:  target.initialize(to:
_setDownCast(source.pointee))
./stdlib/public/core/HashedCollections.swift.gyb:target.initialize(to:
result)
./stdlib/public/core/HashedCollections.swift.gyb:  target.initialize(to:
_dictionaryDownCast(source.pointee))
./stdlib/public/core/HashedCollections.swift.gyb:target.initialize(to:
result)
./stdlib/public/core/HashedCollections.swift.gyb:(keys +
i).initialize(to: k)
./stdlib/public/core/HashedCollections.swift.gyb:(keys +
toEntryAt).initialize(to: (from.keys + at).move())
./stdlib/public/core/HashedCollections.swift.gyb:(keys +
i).initialize(to: k)
./stdlib/public/core/HashedCollections.swift.gyb:(values +
i).initialize(to: v)
./stdlib/public/core/HashedCollections.swift.gyb:(keys +
toEntryAt).initialize(to: (from.keys + at).move())
./stdlib/public/core/HashedCollections.swift.gyb:(values +
toEntryAt).initialize(to: (from.values + at).move())
./stdlib/public/core/ReflectionLegacy.swift:  out.initialize(to:
String(reflecting: x))

./stdlib/public/core/ManagedBuffer.swift:p.headerAddress.initialize(to:
initHeaderVal)
./stdlib/public/core/ManagedBuffer.swift:  $0.initialize(to:
./stdlib/public/core/ArrayBufferProtocol.swift:(elements +
j).initialize(to: newValues[i])
./stdlib/public/core/Sequence.swift:ptr.initialize(to: x)
./stdlib/public/core/HeapBuffer.swift:  $0.initialize(to:
Header(initializer))
./stdlib/public/core/UnsafeBitMap.swift:values.initialize(to: 0, count:
numberOfWords)
./stdlib/public/core/String.swift:resultStorage.initialize(to:
./test/api-digester/stdlib-stable.json:  "printedName":
"initialize(to:count:)",
./test/Generics/slice_test.swift:(newbase + i).initialize(to:
(base+i).move())
./test/Generics/slice_test.swift:(base+length).initialize(to: elem)
./test/Parse/pointer_conversion.swift.gyb:  p.initialize(to: t)

./test/stdlib/Reflection.swift:sanePointerString.initialize(to: "Hello
panda")

./test/stdlib/Builtins.swift:  (buf + 0).initialize(to: value)
./test/stdlib/Builtins.swift:  (buf + 1).initialize(to: value)
./test/stdlib/Renames.swift:  x.initialize(e) // expected-error
{{'initialize' has been renamed to 'initialize(to:)'}} {{5-15=initialize}}
{

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-18 Thread Taylor Swift via swift-evolution
On Tue, Jul 18, 2017 at 4:41 PM, Michael Ilseman  wrote:

>
>
> I agree with all of Andy’s points. I really like this and think it’s a
> good time to start discussing its details and moving from a pitch to a
> proposal. Thank you for writing it!
>
> Minor tweak: say “deprecate” instead of “remove” for APIs, which has a
> better connotation with respect to source compatibility. While I want to
> have the best APIs, it’s important to make migration smooth. For example,
> see https://github.com/apple/swift-evolution/blob/master/proposals/
> 0180-string-index-overhaul.md#source-compatibility
>
> The main thing that I think needs to be massaged before a formal proposal
> is the introduction and motivation section. It contains hyperbole that is
> distracting and misleading. Some examples:
>
> > Introduction
> > …
> > but the current API design is not very safe, consistent, or convenient.
>
>
> This proposal does not address “safe” or unsafety. I think the proposal is
> very good and important for addressing consistency and convenience, which
> help encourage programmers to use APIs correctly, but “not very safe” is
> orthogonal to the proposal.
>
> > In some places, this design turns UnsafePointers into
> outright DangerousPointers, leading users to believe that they have
> allocated or freed memory when in fact, they have not.
>
>
> I see nothing in this proposal that identifies, nor address UnsafePointers
> as being “DangerousPointers”. This proposal seeks to change idiomatic use
> to be more consistent and convenient, which is very important, but does not
> change what “Unsafe” means in Swift. Near as I can tell, the semantics and
> “dangerousness" of Unsafe*Pointers are unchanged by this proposal.
>
> > The current API suffers from inconsistent naming, poor usage of default
> argument values, missing methods, and excessive verbosity, and encourages
> excessively unsafe programming practices.
>
>
> I agree with everything up until “excessively unsafe programming
> practices”. What do you mean by “unsafe”? What practice is that? It seems
> like you might have a very different definition of Unsafe than Swift does.
> If so, then this will be a very different sort of proposal and you should
> identify what you mean by “unsafe”.
>
>
The references to unsafety are about the signature of `deallocate(capacity:)`.
It’s unsafe because you can write perfectly legal Swift code that
*shouldn’t* segfault, but still can, for example

var ptr = UnsafeMutablePointer.allocate(capacity: 100)
ptr.initialize(to: 13, count: 100)
ptr.deallocate(capacity: 50) // deallocate the second half of the
memory block
ptr[0] // signal SIGSEGV: invalid address (fault address: 0x77e79010)

The first 50 addresses should still be valid if the documentation

is to be read literally.

As to the rest of your comments, I agree the language needs to be cleaned
up, right now the document is really more of a working draft to get my
points across until there’s more of less consensus around what should be in
it.

> > This proposal seeks to iron out these inconsistencies, and offer a more
> convenient, more sensible, and less bug-prone API for Swift pointers.
>
>
> 100% agree and I’m super enthusiastic for this proposal for this reason!
> My main feedback is to align the motivation and pitch with the message,
> unless you really do have a different definition of “unsafe” that you’re
> wanting to pitch.
>
> > This results in an equally elegant API with about one-third less surface
> area.
>
>
> 🎉
>
> > Motivation:
> > Right now, UnsafeMutableBufferPointer is kind of a black box. To do
> anything with the memory block it represents, you have to extract
> baseAddresses and counts. This is unfortunate because
> UnsafeMutableBufferPointer provides a handy container for tracking the size
> of a memory buffer, but to actually make use of this information, the
> buffer pointer must be disassembled.
>
>
> Note that Unsafe*BufferPointer conforms to RandomAccessCollection and thus
> gets all the same conveniences of anything else that is Array-like. This
> means that after it has been properly allocated, initialized, and
> pointer-casted, it is very convenient for *consumers* of 
> Unsafe*BufferPointers.
> The main pain points, and this proposal is excellent at addressing, are on
> the *producers* of Unsafe*BufferPointers. For producers, there are a lot
> of rules and hoops to jump through and the APIs are not conveniently
> aligned with them. I do think you’ve done a great job of correctly
> identifying the pain points for people who need to produce
> Unsafe*BufferPointers.
>
>
Good point


> The rest of the motivation section is excellent! I have done every single
> “idiom” you highlight and hated having to do it.
>
>
> On Jul 18, 2017, at 11:19 AM, Andrew Trick via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> On Jul 17, 2017, at 10:06 PM, Tay

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-18 Thread Taylor Swift via swift-evolution
On Tue, Jul 18, 2017 at 5:20 PM, Taylor Swift  wrote:

> No, I just forgot about the compiler subtyping relationship. Never mind
> that part then lol
>
> On Tue, Jul 18, 2017 at 4:40 PM, Andrew Trick  wrote:
>
>>
>> On Jul 18, 2017, at 11:36 AM, Taylor Swift  wrote:
>>
>> I'm not sure removing the need for implicit casts is a goal. I did
>>> that with the pointer `init` methods, but now I think that should be
>>> cleaned up to reduce API surface. I think smaller API surface wins in
>>> these cases. Is there a usability issue you're solving?
>>>
>>
>> Yes, I can imagine initializing a mutable pointer to some values, and
>> then wanting to use that pointer as a source to initialize more buffers.
>> Having to convert a mutable pointer to an immutable pointer is annoying
>> because a function that takes an immutable pointer obviously shouldn’t care
>> if the pointer could be mutated anyway. It’s like having to rebind a `var`
>> variable to a `let` constant before passing it as any non-inout argument
>> to a function, since function parameters are immutable. At any rate, this
>> only applies to two out of the seven memorystate operations, so comparably,
>> it’s not a big API expansion at all.
>>
>>
>> The conversion you’re talking about should be handled by the compiler.
>>
>> public func get(_ p: UnsafePointer) -> T {
>>   return p.pointee
>> }
>>
>> public func foo(p: UnsafeMutablePointer) {
>>   _ = get(p)
>> }
>>
>> Or are you thinking of a different use case?
>>
>> -Andy
>>
>
>
It doesn’t look like there’s an equivalent subtyping relationship between
UnsafeMutableBufferPointer and UnsafeBufferPointer like there is between
the plain pointers. I agree this should be solved in the compiler.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-18 Thread Taylor Swift via swift-evolution
No, I just forgot about the compiler subtyping relationship. Never mind
that part then lol

On Tue, Jul 18, 2017 at 4:40 PM, Andrew Trick  wrote:

>
> On Jul 18, 2017, at 11:36 AM, Taylor Swift  wrote:
>
> I'm not sure removing the need for implicit casts is a goal. I did
>> that with the pointer `init` methods, but now I think that should be
>> cleaned up to reduce API surface. I think smaller API surface wins in
>> these cases. Is there a usability issue you're solving?
>>
>
> Yes, I can imagine initializing a mutable pointer to some values, and then
> wanting to use that pointer as a source to initialize more buffers. Having
> to convert a mutable pointer to an immutable pointer is annoying because a
> function that takes an immutable pointer obviously shouldn’t care if the
> pointer could be mutated anyway. It’s like having to rebind a `var`
> variable to a `let` constant before passing it as any non-inout argument
> to a function, since function parameters are immutable. At any rate, this
> only applies to two out of the seven memorystate operations, so comparably,
> it’s not a big API expansion at all.
>
>
> The conversion you’re talking about should be handled by the compiler.
>
> public func get(_ p: UnsafePointer) -> T {
>   return p.pointee
> }
>
> public func foo(p: UnsafeMutablePointer) {
>   _ = get(p)
> }
>
> Or are you thinking of a different use case?
>
> -Andy
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-18 Thread Goffredo Marocchi via swift-evolution
Mmh, I think like the do while -> repeat while change it makes sense, but not 
enough to displace the obvious meaning of the original... but then again, I 
lost back then...

Sent from my iPhone

Begin forwarded message:

> From: Andrew Trick via swift-evolution 
> Date: 18 July 2017 at 21:33:31 BST
> To: Taylor Swift 
> Cc: swift-evolution 
> Subject: Re: [swift-evolution] Pitch: Improved Swift pointers
> Reply-To: Andrew Trick 
> 
> 
>>> On Jul 18, 2017, at 11:36 AM, Taylor Swift  wrote:
>>> 
>>> > fix the ordering of the arguments in 
>>> > initializeMemory(as:at:count:to:)
>>> 
>>> I think this ordering was an attempt to avoid confusion with binding
>>> memory where `to` refers to a type. However, it should be consistent
>>> with `UnsafePointer.initialize`, so we need to pick one of those to
>>> change.
>> 
>> This would be a non-issue had we just been consistent with the rest of the 
>> stdlib and named this argument `repeating:` instead of `to:`. But 
>> `ptr.initialize(repeating: 255, count: 100)` doesn’t read quite as naturally 
>> in English as `ptr.initialize(to: 255, count: 100)` which is why I left this 
>> idea out of the proposal. Now that you mention the problem with 
>> `initializeMemory(as:at:count:to:)`, it might be a good idea to add 
>> this rename back into it.
> 
> I think `repeating` is much more clear.
> 
> -Andy
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-18 Thread Michael Ilseman via swift-evolution


I agree with all of Andy’s points. I really like this and think it’s a good 
time to start discussing its details and moving from a pitch to a proposal. 
Thank you for writing it!

Minor tweak: say “deprecate” instead of “remove” for APIs, which has a better 
connotation with respect to source compatibility. While I want to have the best 
APIs, it’s important to make migration smooth. For example, see 
https://github.com/apple/swift-evolution/blob/master/proposals/0180-string-index-overhaul.md#source-compatibility

The main thing that I think needs to be massaged before a formal proposal is 
the introduction and motivation section. It contains hyperbole that is 
distracting and misleading. Some examples:

> > Introduction
> > …
> > but the current API design is not very safe, consistent, or convenient.

This proposal does not address “safe” or unsafety. I think the proposal is very 
good and important for addressing consistency and convenience, which help 
encourage programmers to use APIs correctly, but “not very safe” is orthogonal 
to the proposal.

> > In some places, this design turns UnsafePointers into outright 
> > DangerousPointers, leading users to believe that they have allocated or 
> > freed memory when in fact, they have not.

I see nothing in this proposal that identifies, nor address UnsafePointers as 
being “DangerousPointers”. This proposal seeks to change idiomatic use to be 
more consistent and convenient, which is very important, but does not change 
what “Unsafe” means in Swift. Near as I can tell, the semantics and 
“dangerousness" of Unsafe*Pointers are unchanged by this proposal.

> > The current API suffers from inconsistent naming, poor usage of default 
> > argument values, missing methods, and excessive verbosity, and encourages 
> > excessively unsafe programming practices. 

I agree with everything up until “excessively unsafe programming practices”. 
What do you mean by “unsafe”? What practice is that? It seems like you might 
have a very different definition of Unsafe than Swift does. If so, then this 
will be a very different sort of proposal and you should identify what you mean 
by “unsafe”.

> > This proposal seeks to iron out these inconsistencies, and offer a more 
> > convenient, more sensible, and less bug-prone API for Swift pointers.

100% agree and I’m super enthusiastic for this proposal for this reason! My 
main feedback is to align the motivation and pitch with the message, unless you 
really do have a different definition of “unsafe” that you’re wanting to pitch.

> > This results in an equally elegant API with about one-third less surface 
> > area.

🎉

> > Motivation:
> > Right now, UnsafeMutableBufferPointer is kind of a black box. To do 
> > anything with the memory block it represents, you have to extract 
> > baseAddresses and counts. This is unfortunate because 
> > UnsafeMutableBufferPointer provides a handy container for tracking the size 
> > of a memory buffer, but to actually make use of this information, the 
> > buffer pointer must be disassembled.

Note that Unsafe*BufferPointer conforms to RandomAccessCollection and thus gets 
all the same conveniences of anything else that is Array-like. This means that 
after it has been properly allocated, initialized, and pointer-casted, it is 
very convenient for consumers of Unsafe*BufferPointers. The main pain points, 
and this proposal is excellent at addressing, are on the producers of 
Unsafe*BufferPointers. For producers, there are a lot of rules and hoops to 
jump through and the APIs are not conveniently aligned with them. I do think 
you’ve done a great job of correctly identifying the pain points for people who 
need to produce Unsafe*BufferPointers.

The rest of the motivation section is excellent! I have done every single 
“idiom” you highlight and hated having to do it.


> On Jul 18, 2017, at 11:19 AM, Andrew Trick via swift-evolution 
>  wrote:
> 
>> 
>> On Jul 17, 2017, at 10:06 PM, Taylor Swift via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> I’ve drafted a new version of the unsafe pointer proposal based on feedback 
>> I’ve gotten from this thread. You can read it here 
>> .
>> 
>> ~~~
>> Swift’s pointer types are an important interface for low-level memory 
>> manipulation, but the current API design is not very safe, consistent, or 
>> convenient. Many memory methods demand a capacity: or count: argument, 
>> forcing the user to manually track the size of the memory block, even though 
>> most of the time this is either unnecessary, or redundant as buffer pointers 
>> track this information natively. In some places, this design turns 
>> UnsafePointers into outright DangerousPointers, leading users to believe 
>> that they have allocated or freed memory when in fact, they have not.
>> 
>> The current API suffers from inconsistent naming, poor usage of default 
>> argument values, missing metho

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-18 Thread Andrew Trick via swift-evolution

> On Jul 18, 2017, at 11:36 AM, Taylor Swift  wrote:
> 
> I'm not sure removing the need for implicit casts is a goal. I did
> that with the pointer `init` methods, but now I think that should be
> cleaned up to reduce API surface. I think smaller API surface wins in
> these cases. Is there a usability issue you're solving?
> 
> Yes, I can imagine initializing a mutable pointer to some values, and then 
> wanting to use that pointer as a source to initialize more buffers. Having to 
> convert a mutable pointer to an immutable pointer is annoying because a 
> function that takes an immutable pointer obviously shouldn’t care if the 
> pointer could be mutated anyway. It’s like having to rebind a `var` variable 
> to a `let` constant before passing it as any non-inout argument to a 
> function, since function parameters are immutable. At any rate, this only 
> applies to two out of the seven memorystate operations, so comparably, it’s 
> not a big API expansion at all.

The conversion you’re talking about should be handled by the compiler.

public func get(_ p: UnsafePointer) -> T {
  return p.pointee
}

public func foo(p: UnsafeMutablePointer) {
  _ = get(p)
}

Or are you thinking of a different use case?

-Andy___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-18 Thread Andrew Trick via swift-evolution

> On Jul 18, 2017, at 11:36 AM, Taylor Swift  wrote:
> 
> > fix the ordering of the arguments in 
> > initializeMemory(as:at:count:to:)
> 
> I think this ordering was an attempt to avoid confusion with binding
> memory where `to` refers to a type. However, it should be consistent
> with `UnsafePointer.initialize`, so we need to pick one of those to
> change.
> 
> This would be a non-issue had we just been consistent with the rest of the 
> stdlib and named this argument `repeating:` instead of `to:`. But 
> `ptr.initialize(repeating: 255, count: 100)` doesn’t read quite as naturally 
> in English as `ptr.initialize(to: 255, count: 100)` which is why I left this 
> idea out of the proposal. Now that you mention the problem with 
> `initializeMemory(as:at:count:to:)`, it might be a good idea to add 
> this rename back into it.

I think `repeating` is much more clear.

-Andy___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-18 Thread Taylor Swift via swift-evolution
On Tue, Jul 18, 2017 at 2:18 PM, Andrew Trick  wrote:

>
> > rename count in UnsafeMutableRawBufferPointer.allocate(count:) to bytes
> and add an
> > alignedTo parameter to make it UnsafeMutableRawBufferPointer.
> allocate(bytes:alignedTo:)
>
> Memory allocation is an issue unto itself. I generally prefer your
> proposed API. However...
>
> 1. Larger-than-pointer alignments aren't currently respected.
>
> 2. Users virtually never want to specify the alignment explicitly. They
>just want platform alignment. Unfortunately, there's no reasonable
>"maximal" alignment to use as a default. I think pointer-alignment
>is an excellent default guarantee.
>
> 3. The current allocation builtins seem to presume that
>allocation/deallocation can be made more efficient if the user code
>specifies alignment at deallocation. I don't think
>UnsafeRawBufferPointer should expose that to the user, so I agree
>with your proposal. In fact, I think aligned `free` should be
>handled within the Swift runtime.
>
> Resolving these issues requires changes to the Swift runtime API and
> implementation. This might be a good time to revisit that design, but
> it might slow down the rest of the proposal.
>
>
I don’t know much about the Swift runtime, but for now at least, it might
be a good idea to emit a runtime error if an alignment larger than a
pointer is specified, if only when built in debug mode.


> > fix the ordering of the arguments in initializeMemory(as:
> at:count:to:)
>
> I think this ordering was an attempt to avoid confusion with binding
> memory where `to` refers to a type. However, it should be consistent
> with `UnsafePointer.initialize`, so we need to pick one of those to
> change.
>

This would be a non-issue had we just been consistent with the rest of the
stdlib and named this argument `repeating:` instead of `to:`. But
`ptr.initialize(repeating:
255, count: 100)` doesn’t read quite as naturally in English as
`ptr.initialize(to:
255, count: 100)` which is why I left this idea out of the proposal. Now
that you mention the problem with `initializeMemory(as:
at:count:to:)`, it might be a good idea to add this rename back into it.


>
> > add the sized memorystate functions withMemoryRebound Result>(to:count:_:) to
> > UnsafeMutableBufferPointer, and initializeMemory(as:
> at:to:count:),
> > initializeMemory(as:from:count:) moveInitializeMemory(
> as:from:count:),
> > and bindMemory(to:count:) to UnsafeMutableRawBufferPointer
>
> Yay!
>
> > add mutable overloads to non-vacating memorystate method arguments
>
> I'm not sure removing the need for implicit casts is a goal. I did
> that with the pointer `init` methods, but now I think that should be
> cleaned up to reduce API surface. I think smaller API surface wins in
> these cases. Is there a usability issue you're solving?
>

Yes, I can imagine initializing a mutable pointer to some values, and then
wanting to use that pointer as a source to initialize more buffers. Having
to convert a mutable pointer to an immutable pointer is annoying because a
function that takes an immutable pointer obviously shouldn’t care if the
pointer could be mutated anyway. It’s like having to rebind a `var`
variable to a `let` constant before passing it as any non-inout argument to
a function, since function parameters are immutable. At any rate, this only
applies to two out of the seven memorystate operations, so comparably, it’s
not a big API expansion at all.


>
> > add a init(mutating:) initializer to UnsafeMutableBufferPointer
>
> Yes, finally.
>
> > remove initialize(from:) from UnsafeMutablePointer
>
> Yep.
>
> > adding an initializer UnsafeMutableBufferPointer<
> Element>.init(allocatingCount:) instead > of a type method to
> UnsafeMutableBufferPointer
>
> For the record, I strongly prefer a type method for allocation for the
> reason you mention, it has important side effects beyond simply
> initializingn the pointer.
>
>
> -Andy
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-18 Thread Andrew Trick via swift-evolution

> On Jul 17, 2017, at 10:06 PM, Taylor Swift via swift-evolution 
>  wrote:
> 
> I’ve drafted a new version of the unsafe pointer proposal based on feedback 
> I’ve gotten from this thread. You can read it here 
> .
> 
> ~~~
> Swift’s pointer types are an important interface for low-level memory 
> manipulation, but the current API design is not very safe, consistent, or 
> convenient. Many memory methods demand a capacity: or count: argument, 
> forcing the user to manually track the size of the memory block, even though 
> most of the time this is either unnecessary, or redundant as buffer pointers 
> track this information natively. In some places, this design turns 
> UnsafePointers into outright DangerousPointers, leading users to believe that 
> they have allocated or freed memory when in fact, they have not.
> 
> The current API suffers from inconsistent naming, poor usage of default 
> argument values, missing methods, and excessive verbosity, and encourages 
> excessively unsafe programming practices. This proposal seeks to iron out 
> these inconsistencies, and offer a more convenient, more sensible, and less 
> bug-prone API for Swift pointers.
> 
> The previous draft 
>  of this 
> proposal was relatively source-breaking, calling for a separation of 
> functionality between singular pointer types and vector (buffer) pointer 
> types. This proposal instead separates functionality between 
> internally-tracked length pointer types and externally-tracked length pointer 
> types. This results in an equally elegant API with about one-third less 
> surface area.
> 
>  >
> 
> ~~~
> 

> remove the capacity parameter from deallocate(capacity:) and 
> deallocate(bytes:alignedTo:)

That's probably for the best.

> add unsized memory methods to UnsafeMutableBufferPointer

Yay!

> add an assign(to:count:) method to UnsafeMutablePointer and an assign(to:) 
> method to UnsafeMutableBufferPointer

Sure.

> add a default value of 1 to all size parameters on UnsafeMutablePointer and 
> applicable
> size parameters on UnsafeMutableRawPointer

I'm not opposed to it.

> rename copyBytes(from:count:) to copy(from:bytes:)

LGTM in the interest of consistency. I should not have caved on this the first 
time around.

> bytes refers to, well, a byte quantity that is not assumed to be initialized.
> capacity refers to a strided quantity that is not assumed to be initialized.
> count refers to a strided quantity that is assumed to be initialized.

That's how I see it.

> rename count in UnsafeMutableRawBufferPointer.allocate(count:) to bytes and 
> add an
> alignedTo parameter to make it 
> UnsafeMutableRawBufferPointer.allocate(bytes:alignedTo:)

Memory allocation is an issue unto itself. I generally prefer your
proposed API. However...

1. Larger-than-pointer alignments aren't currently respected.

2. Users virtually never want to specify the alignment explicitly. They
   just want platform alignment. Unfortunately, there's no reasonable
   "maximal" alignment to use as a default. I think pointer-alignment
   is an excellent default guarantee.

3. The current allocation builtins seem to presume that
   allocation/deallocation can be made more efficient if the user code
   specifies alignment at deallocation. I don't think
   UnsafeRawBufferPointer should expose that to the user, so I agree
   with your proposal. In fact, I think aligned `free` should be
   handled within the Swift runtime.

Resolving these issues requires changes to the Swift runtime API and
implementation. This might be a good time to revisit that design, but
it might slow down the rest of the proposal.

> fix the ordering of the arguments in 
> initializeMemory(as:at:count:to:)

I think this ordering was an attempt to avoid confusion with binding
memory where `to` refers to a type. However, it should be consistent
with `UnsafePointer.initialize`, so we need to pick one of those to
change.

> add the sized memorystate functions withMemoryRebound Result>(to:count:_:) to
> UnsafeMutableBufferPointer, and initializeMemory(as:at:to:count:),
> initializeMemory(as:from:count:) 
> moveInitializeMemory(as:from:count:),
> and bindMemory(to:count:) to UnsafeMutableRawBufferPointer

Yay!

> add mutable overloads to non-vacating memorystate method arguments

I'm not sure removing the need for implicit casts is a goal. I did
that with the pointer `init` methods, but now I think that should be
cleaned up to reduce API surface. I think smaller API surface wins in
these cases. Is there a usability issue you're solving?

> add a init(mutating:) initializer to UnsafeMutableBufferPointer

Yes, finally.

> remove initialize(from:) from UnsafeMutablePointer

Yep.

> adding an initializer 
> UnsafeMutableBuf

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-17 Thread Taylor Swift via swift-evolution
I’ve drafted a new version of the unsafe pointer proposal based on feedback
I’ve gotten from this thread. You can read it here
.

~~~

Swift’s pointer types are an important interface for low-level memory
manipulation, but the current API design is not very safe, consistent, or
convenient. Many memory methods demand a capacity: or count: argument,
forcing the user to manually track the size of the memory block, even
though most of the time this is either unnecessary, or redundant as buffer
pointers track this information natively. In some places, this design turns
UnsafePointers into outright *Dangerous*Pointers, leading users to believe
that they have allocated or freed memory when in fact, they have not.

The current API suffers from inconsistent naming, poor usage of default
argument values, missing methods, and excessive verbosity, and encourages
excessively unsafe programming practices. This proposal seeks to iron out
these inconsistencies, and offer a more convenient, more sensible, and less
bug-prone API for Swift pointers.

The previous draft
 of this
proposal was relatively source-breaking, calling for a separation of
functionality between singular pointer types and vector (buffer) pointer
types. This proposal instead separates functionality between
internally-tracked length pointer types and externally-tracked length
pointer types. This results in an equally elegant API with about one-third
less surface area.



~~~

On Wed, Jul 12, 2017 at 3:16 PM, Taylor Swift  wrote:

> Hi all, I’ve written up a proposal to modify the unsafe pointer API for
> greater consistency, safety, and ease of use.
>
> ~~~
>
> Swift currently offers two sets of pointer types — singular pointers such
> as UnsafeMutablePointer, and vector (buffer) pointers such as
> UnsafeMutable*Buffer*Pointer. This implies a natural separation of tasks
> the two kinds of pointers are meant to do. For example, buffer pointers
> implement Collection conformance, while singular pointers do not.
>
> However, some aspects of the pointer design contradict these implied
> roles. It is possible to allocate an arbitrary number of instances from a
> type method on a singular pointer, but not from a buffer pointer. The
> result of such an operation returns a singular pointer, even though a
> buffer pointer would be more appropriate to capture the information about
> the *number* of instances allocated. It’s possible to subscript into a
> singular pointer, even though they are not real Collections. Some parts
> of the current design turn UnsafePointers into downright *Dangerous*Pointers,
> leading users to believe that they have allocated or freed memory when in
> fact, they have not.
>
> This proposal seeks to iron out these inconsistencies, and offer a more
> convenient, more sensible, and less bug-prone API for Swift pointers.
>
> 
>
> ~~~
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-17 Thread Andrew Trick via swift-evolution

> On Jul 14, 2017, at 7:24 PM, Taylor Swift  wrote:
> 
> For the sake of argument, I’m gonna claim that instead, 
> UnsafeMutableBufferPointer is the low level necessity, and 
> UnsafeMutablePointer is the low level convenience structure.
> 
> Suppose that every block of memory has a starting point, and a length. An 
> UnsafeBufferPointer represents that, since all an UnsafeBufferPointer is, is 
> a start address, and a length value, bundled together into one variable 
> instead of two. Then we can say that UnsafePointer is a special case of 
> UnsafeBufferPointer, where the length value is unknown.
> 
> Mind you I didn’t say that the length value equals 1. But it might as well 
> be. Because when the length is unknown, the only index where you can 
> reasonably expect there to be a valid value is index zero. You wouldn’t feel 
> confident trying to do something to the memory address 3 strides down from 
> the pointer. If you did feel confident doing that, well now you have a length 
> value. The length value is 4. Your regular Pointer is now a BufferPointer.
> 
> The only reason any of this matters, is because all of our memory and 
> memorystate -related functions take size arguments. You have to fill in the 
> size argument with something. That something is the buffer `count`. Even if 
> you don’t actually know the number for the `count`, you still have to supply 
> some value, in which case the “only” sensible choice is “1”. That’s why you 
> could argue that UnsafePointer is just a special case of a buffer pointer 
> where `count` is 1. The UnsafePointer API demands information that only 
> BufferPointers know. You could design an API where buffer pointers are the 
> only pointers that exist, and everything would still work fine. Just because 
> they have high-level capabilities doesn’t mean they can’t do everything plain 
> pointers can do just as efficiently. A plain pointer takes up one word of 
> storage, and you use another word of storage yourself to track the size. A 
> buffer pointer stores the two words next to each other. You could ignore the 
> size word and track the size yourself, taking up three words of storage, but 
> that would just be silly.
> 
> But wait! I don’t need to track the size, you say! The pointer just points to 
> one item! I just need the address word, not the size word! Well, yeah. That’s 
> why I proposed a sizeless singular pointer API, so you don’t have to go 
> around plugging “1”s everywhere and save yourself a word of storage. You can 
> argue that’s the actual high-level API, since it abstracts away the length 
> stuff. But if “1” isn’t your answer to the question “on how many instances 
> should this method operate on”, go back to paragraph 3 and convince yourself 
> that what you really have is an buffer pointer, not a plain pointer.
> 
> Now I thought of an exception to this, like when you’re assigning 8-bit RGBA 
> values to an image buffer and it might make sense to write something like 
> this in the current API:
> 
> let size:Int = height * width << 2
> let base = UnsafeMutablePointer.allocate(capacity: size) 
> defer 
> {
> base.deallocate(capacity: -314159) // anything goes
> }
> var pixel:UnsafeMutablePointer = base
> while pixel < base + size 
> {
> pixel.initialize(from: bg_color_rgba, count: 4)
> pixel += 4
> }
> 
> And it’s convenient to be able to initialize 4 instances at a time without 
> creating a 4-count buffer pointer. But this doesn’t really contradict my 
> point if you think carefully. The groups of 4 RGBA values are your atom here, 
> you’re not really working on 4 instances at a time with a stride 1 UInt8 big, 
> you’re working on 1 single instance at a time with a stride 4 UInt8s big. 
> Writing this is currently painful without the sized UnsafeMutablePointer API, 
> but I think this is a deficiency of the UnsafeMutableBufferPointer API and 
> that of its slice type, not a reason for keeping the sized 
> UnsafeMutablePointer API, which if you ask me is a hack to get around the 
> fact that we can’t use buffer pointer slices easily.
> 
> Anyway, I mention all of this only because everyone seems convinced that 
> UnsafePointer is supposed to be “edgier” than UnsafeBufferPointer. If you 
> have ideas to make this better, by all means share them

UnsafeBufferPointer was developed to add safety and convenience on top of 
UnsafePointer. That’s just a historical fact, not necessarily detracting from 
your argument.

The problem with your use case above is that UnsafePointer doesn’t get the 
debug-mode bounds checks.

There’s an argument to be made for keeping the UnsafePointer API complete (as a 
single point of truth for the memory model), and an argument to be made for 
removing it (it’s not the *right* API to use in nearly all cases). I would be 
fine with either approach and people can argue it out. At the moment I would 
lean toward not breaking source for something that isn’t a critical problem for 
the language.

That doesn

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-14 Thread Taylor Swift via swift-evolution
For the sake of argument, I’m gonna claim that instead,
UnsafeMutableBufferPointer is the low level necessity, and
UnsafeMutablePointer is the low level convenience structure.

Suppose that every block of memory has a starting point, and a length. An
UnsafeBufferPointer represents that, since all an UnsafeBufferPointer is,
is a start address, and a length value, bundled together into one variable
instead of two. Then we can say that UnsafePointer is a *special case* of
UnsafeBufferPointer, where the length value is *unknown*.

Mind you I didn’t say that the length value *equals* *1*. But it *might as
well* be. Because when the length is unknown,* the only index where you can
reasonably expect there to be a valid value is index zero*. You wouldn’t
feel confident trying to do something to the memory address 3 strides down
from the pointer. If you did feel confident doing that, well now you have a
length value. The length value is 4. Your regular Pointer is now a
BufferPointer.

The only reason any of this matters, is because all of our memory and
memorystate -related functions take size arguments. You have to fill in the
size argument with *something*. That *something* is the buffer `count`.
Even if you don’t actually know the number for the `count`, you still have
to supply some value, in which case the “only” sensible choice is “1”.
That’s why you could argue that UnsafePointer is just a special case of a
buffer pointer where `count` is 1. The UnsafePointer API demands
information that only BufferPointers know. You could design an API where
buffer pointers are the only pointers that exist, and everything would
still work fine. Just because they have high-level *capabilities* doesn’t
mean they can’t do everything plain pointers can do just as efficiently. A
plain pointer takes up one word of storage, and you use another word of
storage yourself to track the size. A buffer pointer stores the two words
next to each other. You could ignore the size word and track the size
yourself, taking up three words of storage, but that would just be silly.

*But wait! I don’t need to track the size*, you say! *The pointer just
points to one item! I just need the address word, not the size word!* Well,
*yeah*. That’s why I proposed a sizeless singular pointer API, so you don’t
have to go around plugging “1”s everywhere and save yourself a word of
storage. You can argue that’s the *actual* high-level API, since it
abstracts away the length stuff. But if “1” isn’t your answer to the
question “on how many instances should this method operate on”, go back to
paragraph 3 and convince yourself that what you really have is an buffer
pointer, not a plain pointer.

Now I thought of an exception to this, like when you’re assigning 8-bit
RGBA values to an image buffer and it might make sense to write something
like this in the current API:

let size:Int = height * width << 2
let base = UnsafeMutablePointer.allocate(capacity: size)
defer
{
base.deallocate(capacity: -314159) // anything goes
}
var pixel:UnsafeMutablePointer = base
while pixel < base + size
{
pixel.initialize(from: bg_color_rgba, count: 4)
pixel += 4
}

And it’s convenient to be able to initialize 4 instances at a time without
creating a 4-count buffer pointer. But this doesn’t really contradict my
point if you think carefully. The groups of 4 RGBA values are your atom
here, you’re not really working on 4 instances at a time with a stride 1
UInt8 big, you’re working on 1 single instance at a time with a stride 4
UInt8s big. Writing this is currently painful without the sized
UnsafeMutablePointer API, but I think this is a deficiency of the
UnsafeMutableBufferPointer API and that of its slice type, not a reason for
keeping the sized UnsafeMutablePointer API, which if you ask me is a hack
to get around the fact that we can’t use buffer pointer slices easily.

Anyway, I mention all of this only because everyone seems convinced that
UnsafePointer is supposed to be “edgier” than UnsafeBufferPointer. If you
have ideas to make this better, by all means share them


On Fri, Jul 14, 2017 at 2:27 PM, Michael Ilseman  wrote:

>
> On Jul 13, 2017, at 6:55 PM, Taylor Swift via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
>
> On Thu, Jul 13, 2017 at 6:56 PM, Andrew Trick  wrote:
>
>>
>> On Jul 12, 2017, at 12:16 PM, Taylor Swift via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> Hi all, I’ve written up a proposal to modify the unsafe pointer API for
>> greater consistency, safety, and ease of use.
>>
>> ~~~
>>
>> Swift currently offers two sets of pointer types — singular pointers such
>> as UnsafeMutablePointer, and vector (buffer) pointers such as
>> UnsafeMutable*Buffer*Pointer. This implies a natural separation of tasks
>> the two kinds of pointers are meant to do. For example, buffer pointers
>> implement Collection conformance, while singular pointers do not.
>>
>> However, some aspects of the pointer design contradict these implied
>> rol

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-14 Thread Andrew Trick via swift-evolution

> On Jul 14, 2017, at 11:27 AM, Michael Ilseman  wrote:
> 
>> I also have to say it’s not common to deallocate something in Swift that you 
>> didn’t previously allocate in Swift. 
>> 
> 
> I’m not sure it is even defined to use `deallocate` on memory that wasn’t 
> `allocated` in Swift. Andy, thoughts here? Perhaps more clarity in 
> deallocate’s documentation is needed?

If my memory is correct, Swift’s `deallocate` requires a pointer that was 
allocated via Swift’s `allocate`.

What’s missing from the docs I suppose is the fact that we now have a set of 
Swift allocate/deallocate entry points, which are of course compatible as long 
as the user keeps track of the capacity and alignment. IMO the buffer pointer 
API should alleviate that responsibility from the user.

-Andy___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-14 Thread Michael Ilseman via swift-evolution

> On Jul 13, 2017, at 6:55 PM, Taylor Swift via swift-evolution 
>  wrote:
> 
> 
> 
> On Thu, Jul 13, 2017 at 6:56 PM, Andrew Trick  > wrote:
> 
>> On Jul 12, 2017, at 12:16 PM, Taylor Swift via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Hi all, I’ve written up a proposal to modify the unsafe pointer API for 
>> greater consistency, safety, and ease of use.
>> 
>> ~~~
>> 
>> Swift currently offers two sets of pointer types — singular pointers such as 
>> UnsafeMutablePointer, and vector (buffer) pointers such as 
>> UnsafeMutableBufferPointer. This implies a natural separation of tasks the 
>> two kinds of pointers are meant to do. For example, buffer pointers 
>> implement Collection conformance, while singular pointers do not.
>> 
>> However, some aspects of the pointer design contradict these implied roles. 
>> It is possible to allocate an arbitrary number of instances from a type 
>> method on a singular pointer, but not from a buffer pointer. The result of 
>> such an operation returns a singular pointer, even though a buffer pointer 
>> would be more appropriate to capture the information about the number of 
>> instances allocated. It’s possible to subscript into a singular pointer, 
>> even though they are not real Collections. Some parts of the current design 
>> turn UnsafePointers into downright DangerousPointers, leading users to 
>> believe that they have allocated or freed memory when in fact, they have not.
>> 
>> This proposal seeks to iron out these inconsistencies, and offer a more 
>> convenient, more sensible, and less bug-prone API for Swift pointers.
>> 
>> > >
>> 
>> ~~~
>> 
> 
> Thanks for taking time to write this up.
> 
> General comments:
> 
> UnsafeBufferPointer is an API layer on top of UnsafePointer. The role
> of UnsafeBufferPointer is direct memory access sans lifetime
> management with Collection semantics. The role of UnsafePointer is
> primarily C interop. Those C APIs should be wrapped in Swift APIs that
> take UnsafeBufferPointer whenever the pointer represents a C array. I
> suppose making UnsafePointer less convenient would push developers
> toward UnsafeBufferPointer. I don't think that's worth outright
> breaking source, but gradual deprecation of convenience methods, like
> `susbscript` might be acceptable.
> 
> Gradual deprecation is exactly what I am proposing. As the document states 
> ,
>  the only methods which should be marked immediately as unavailable are the 
> `deallocate(capacity:)` methods, for safety and source compatibility reasons. 
> Removing `deallocate(capacity:)` now and forcing a loud compiler error 
> prevents catastrophic *silent* source breakage in the future, or worse, from 
> having to *support our own bug*.
>  
> 
> I have mixed feelings about stripping UnsafePointer of basic
> functionality. Besides breaking source, doing that would be
> inconsistent with its role as a lower API layer. The advantage would
> just be descreasing API surface area and forcing developers to use a
> higher-level API.
> 
> UnsafePointer is as much a high level API as UnsafeBufferPointer is. You 
> wouldn’t create a buffer pointer of length 1 just so you can “stick with the 
> high level API”. UnsafePointer and UnsafeBufferPointer are two tools that do 
> related but different things and they can exist at whatever abstract level 
> you need them at. After all, UnsafeBufferPointer is nothing but an 
> UnsafePointer? with a length value attached to it. If you’re allocating more 
> than one instance of memory, you almost certainly need to track the length of 
> the buffer anyway.
>  

I disagree. UnsafePointer can be viewed as the low level representation of 
Swift’s memory model. UnsafeBufferPointer is a convenient facility for 
programming at this level, as illustrated by e.g. RandomAccessCollection 
conformance. One could drop UnsafeBufferPointer from the standard library 
without compromising Swift’s core capabilities, it would just be a large 
convenience regression.

UnsafePointer is a low level necessity; UnsafeBufferPointer is a low level 
convenience.

> The additive changes you propose are fairly obvious. See [SR-3088]
> UnsafeMutableBufferPointer doesn't have an allocating init.
> 
> I haven't wanted to waste review cycles on small additive
> changes. It may make sense to batch them up into one coherent
> proposal. Here are a few more to consider.
> 
> - [SR-3929] UnsafeBufferPointer should have init from mutable
> - [SR-4340] UnsafeBufferPointer needs a withMemoryRebound method
> - [SR-3087] No way to arbitrarily initialise an Array's storage
> 
> The feature requests you mention are all very valuable, however with 
> Michael’s point about fixing the memorystate API’s, the size of this

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-14 Thread Andrew Trick via swift-evolution

> On Jul 14, 2017, at 9:33 AM, Taylor Swift  wrote:
> 
> How would you feel about:
> 
> struct UnsafeMutableRawBufferPointer
> {
> 
> --- static func allocate(count:Int) -> UnsafeMutableRawBufferPointer
> +++ static func allocate(bytes:Int, alignedTo:Int) -> 
> UnsafeMutableRawBufferPointer
> func deallocate()
> +++ func bindMemory(to:Element.Type, capacity:Int)
> +++ func copy(from:UnsafeRawBufferPointer, bytes:Int)
> +++ func initializeMemory(as:Element.Type, at:Int, to:Element, 
> count:Int)
> +++ func initializeMemory(as:Element.Type, 
> from:UnsafeBufferPointer, count:Int)
> +++ func moveInitializeMemory(as:Element.Type, 
> from:UnsafeMutableBufferPointer, count:Int
> }
> 
> “bytes”= 8 bit quantities (don’t @ me we’re assuming 8 bit bytes)
> “capacity” = strided quantities, not assumed to be initialized 
> “count”= strided quantities, assumed to be initialized
> 
> It’s also worth nothing that a lot of what the proposal tries to add to 
> UnsafeBufferPointer is already present in UnsafeMutableRawPointer like a 
> sizeless deallocate() and a sizeless copyBytes(from:).
> 
> Although I’m not sure what’s going on with the latter one 
> …lol
>  swiftdoc

Purely in terms of label names, what you have above is perfectly fine.

You’re going to have a problem adding the alignment constraint to buffer 
pointer, but that’s another topic.

-Andy

> On Fri, Jul 14, 2017 at 1:57 AM, Andrew Trick  > wrote:
> 
>> On Jul 13, 2017, at 10:30 PM, Taylor Swift > > wrote:
>> 
>> I’m confused I thought we were talking about the naming choices for the 
>> argument labels in those functions. I think defining and abiding by 
>> consistent meanings for `count`, `capacity`, and `bytes` is a good idea, and 
>> it’s part of what this proposal tries to accomplish. Right now half the time 
>> we use `count` to refer to “bytes” and half the time we use it to refer to 
>> “instances”. The same goes for the word “capacity”. This is all laid out in 
>> the document:
>> 
>> “““
>> Finally, the naming and design of some UnsafeMutableRawPointer members 
>> deserves to be looked at. The usage of capacity, bytes, and count as 
>> argument labels is wildly inconsistent and confusing. In 
>> copyBytes(from:count:), count refers to the number of bytes, while in 
>> initializeMemory(as:at:count:to:) and 
>> initializeMemory(as:from:count:), count refers to the number of strides. 
>> Meanwhile bindMemory(to:capacity:) uses capacity to refer to this 
>> quantity. The always-problematic deallocate(bytes:alignedTo) method and 
>> allocate(bytes:alignedTo:) type methods use bytes to refer to 
>> byte-quantities. Adding to the confusion, UnsafeMutableRawBufferPointer 
>> offers an allocate(count:) type method (the same signature method we’re 
>> trying to add to UnsafeMutableBufferPointer), except the count in this 
>> method refers to bytes. This kind of API naming begets stride bugs and makes 
>> Swift needlessly difficult to learn.
>> ”””
>> 
>> The only convenience methods this proposal is trying to add is the 
>> functionality on the buffer pointer types. There seems to be broad support 
>> for adding this functionality as no one has really opposed that part of the 
>> proposal yet. Any other new methods like `UnsafeMutablePointer.assign(to:)` 
>> are there for API consistency.
>> 
>> This proposal also calls for getting rid of one of those “redundant 
>> initializers” :)
> 
> Since we’re not bike-shedding the specifics yet, I’ll just give you some 
> background.
> 
> We would ultimately like APIs that allocate and initialize in one go. It’s 
> important that the current lower-level (dangerous) APIs make a clear 
> distinction between initialized and uninitialized memory to avoid confusing 
> them with future (safer) APIs. `capacity` always refers to memory that may be 
> uninitialized. I think that’s very clear and helpful.
> 
> In the context of pointers `count` should always be in strides. For raw 
> pointers, that happens to be the same as as `bytes`.
> 
> I initially proposed copy(bytes:from:), but someone thought that `bytes` in 
> this particular context did not properly convey the "count of bytes" as 
> opposed to the source of the bytes. You’re right, that’s inconsistent with 
> allocate/deallocate(bytes:), because allocateBytes(count:) would be silly. 
> Just be aware that the inconsistency is a result of over-thinking and 
> excessive bike shedding to the detriment of something that looks nice and is 
> easy to remember.
> 
> I should also point out that the inconsistencies in functionality across 
> pointer types, in terms of collection support and other convenience, is also 
> known but was deliberately stripped from proposals as “additive”.
> 
> -Andy
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.s

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-14 Thread Taylor Swift via swift-evolution
How would you feel about:

struct UnsafeMutableRawBufferPointer
{

--- static func allocate(count:Int) -> UnsafeMutableRawBufferPointer
+++ static func allocate(bytes:Int, alignedTo:Int) ->
UnsafeMutableRawBufferPointer
func deallocate()
+++ func bindMemory(to:Element.Type, capacity:Int)
+++ func copy(from:UnsafeRawBufferPointer, bytes:Int)
+++ func initializeMemory(as:Element.Type, at:Int, count:Int,
to:Element)
+++ func initializeMemory(as:Element.Type,
from:UnsafeBufferPointer, count:Int)
+++ func moveInitializeMemory(as:Element.Type,
from:UnsafeMutableBufferPointer, count:Int
}

“bytes”= 8 bit quantities (don’t @ me we’re assuming 8 bit bytes)
“capacity” = strided quantities, not assumed to be initialized
“count”= strided quantities, assumed to be initialized

It’s also worth nothing that a lot of what the proposal tries to add to
UnsafeBufferPointer is already present in UnsafeMutableRawPointer like a
sizeless deallocate() and a sizeless copyBytes(from:).

Although I’m not sure what’s going on with the latter one
…lol
swiftdoc


On Fri, Jul 14, 2017 at 1:57 AM, Andrew Trick  wrote:

>
> On Jul 13, 2017, at 10:30 PM, Taylor Swift  wrote:
>
> I’m confused I thought we were talking about the naming choices for the
> argument labels in those functions. I think defining and abiding by
> consistent meanings for `count`, `capacity`, and `bytes` is a good idea,
> and it’s part of what this proposal tries to accomplish. Right now half the
> time we use `count` to refer to “bytes” and half the time we use it to
> refer to “instances”. The same goes for the word “capacity”. This is all
> laid out in the document:
>
> “““
> *Finally, the naming and design of some UnsafeMutableRawPointer members
> deserves to be looked at. The usage of capacity, bytes, and count as
> argument labels is wildly inconsistent and confusing.
> In copyBytes(from:count:), count refers to the number of bytes, while
> in initializeMemory(as:at:count:to:) and 
> initializeMemory(as:from:count:), count refers
> to the number of strides.
> Meanwhile bindMemory(to:capacity:) uses capacity to refer to this
> quantity. The always-problematic deallocate(bytes:alignedTo) method
> and allocate(bytes:alignedTo:) type methods use bytes to refer to
> byte-quantities. Adding to the
> confusion, UnsafeMutableRawBufferPointer offers an allocate(count:) type
> method (the same signature method we’re trying to add
> to UnsafeMutableBufferPointer), except the count in this method refers to
> bytes. This kind of API naming begets stride bugs and makes Swift
> needlessly difficult to learn.*
> ”””
>
> The only convenience methods this proposal is trying to add is the
> functionality on the buffer pointer types. There seems to be broad support
> for adding this functionality as no one has really opposed that part of the
> proposal yet. Any other new methods like `UnsafeMutablePointer.assign(to:)`
> are there for API consistency.
>
> This proposal also calls for getting rid of one of those “redundant
> initializers” :)
>
>
> Since we’re not bike-shedding the specifics yet, I’ll just give you some
> background.
>
> We would ultimately like APIs that allocate and initialize in one go. It’s
> important that the current lower-level (dangerous) APIs make a clear
> distinction between initialized and uninitialized memory to avoid confusing
> them with future (safer) APIs. `capacity` always refers to memory that may
> be uninitialized. I think that’s very clear and helpful.
>
> In the context of pointers `count` should always be in strides. For raw
> pointers, that happens to be the same as as `bytes`.
>
> I initially proposed copy(bytes:from:), but someone thought that `bytes`
> in this particular context did not properly convey the "count of bytes" as
> opposed to the source of the bytes. You’re right, that’s inconsistent with
> allocate/deallocate(bytes:), because allocateBytes(count:) would be silly.
> Just be aware that the inconsistency is a result of over-thinking and
> excessive bike shedding to the detriment of something that looks nice and
> is easy to remember.
>
> I should also point out that the inconsistencies in functionality across
> pointer types, in terms of collection support and other convenience, is
> also known but was deliberately stripped from proposals as “additive”.
>
> -Andy
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-14 Thread Taylor Swift via swift-evolution
I’d also like to swap the ordering of `count:` and `to:` in `
UnsafeMutableRawPointer.initializeMemory(as:at:count:to:)` so it matches
up with the ordering in `UnsafeMutablePointer.initializeMemory(to:count:)
`.

On Fri, Jul 14, 2017 at 12:33 PM, Taylor Swift  wrote:

> How would you feel about:
>
> struct UnsafeMutableRawBufferPointer
> {
>
> --- static func allocate(count:Int) -> UnsafeMutableRawBufferPointer
> +++ static func allocate(bytes:Int, alignedTo:Int) ->
> UnsafeMutableRawBufferPointer
> func deallocate()
> +++ func bindMemory(to:Element.Type, capacity:Int)
> +++ func copy(from:UnsafeRawBufferPointer, bytes:Int)
> +++ func initializeMemory(as:Element.Type, at:Int, count:Int,
> to:Element)
> +++ func initializeMemory(as:Element.Type,
> from:UnsafeBufferPointer, count:Int)
> +++ func moveInitializeMemory(as:Element.Type, from:
> UnsafeMutableBufferPointer, count:Int
> }
>
> “bytes”= 8 bit quantities (don’t @ me we’re assuming 8 bit bytes)
> “capacity” = strided quantities, not assumed to be initialized
> “count”= strided quantities, assumed to be initialized
>
> It’s also worth nothing that a lot of what the proposal tries to add to
> UnsafeBufferPointer is already present in UnsafeMutableRawPointer like a
> sizeless deallocate() and a sizeless copyBytes(from:).
>
> Although I’m not sure what’s going on with the latter one
> …lol
> swiftdoc
>
>
> On Fri, Jul 14, 2017 at 1:57 AM, Andrew Trick  wrote:
>
>>
>> On Jul 13, 2017, at 10:30 PM, Taylor Swift  wrote:
>>
>> I’m confused I thought we were talking about the naming choices for the
>> argument labels in those functions. I think defining and abiding by
>> consistent meanings for `count`, `capacity`, and `bytes` is a good idea,
>> and it’s part of what this proposal tries to accomplish. Right now half the
>> time we use `count` to refer to “bytes” and half the time we use it to
>> refer to “instances”. The same goes for the word “capacity”. This is all
>> laid out in the document:
>>
>> “““
>> *Finally, the naming and design of some UnsafeMutableRawPointer members
>> deserves to be looked at. The usage of capacity, bytes, and count as
>> argument labels is wildly inconsistent and confusing.
>> In copyBytes(from:count:), count refers to the number of bytes, while
>> in initializeMemory(as:at:count:to:) and 
>> initializeMemory(as:from:count:), count refers
>> to the number of strides.
>> Meanwhile bindMemory(to:capacity:) uses capacity to refer to this
>> quantity. The always-problematic deallocate(bytes:alignedTo) method
>> and allocate(bytes:alignedTo:) type methods use bytes to refer to
>> byte-quantities. Adding to the
>> confusion, UnsafeMutableRawBufferPointer offers an allocate(count:) type
>> method (the same signature method we’re trying to add
>> to UnsafeMutableBufferPointer), except the count in this method refers to
>> bytes. This kind of API naming begets stride bugs and makes Swift
>> needlessly difficult to learn.*
>> ”””
>>
>> The only convenience methods this proposal is trying to add is the
>> functionality on the buffer pointer types. There seems to be broad support
>> for adding this functionality as no one has really opposed that part of the
>> proposal yet. Any other new methods like `UnsafeMutablePointer.assign(t
>> o:)` are there for API consistency.
>>
>> This proposal also calls for getting rid of one of those “redundant
>> initializers” :)
>>
>>
>> Since we’re not bike-shedding the specifics yet, I’ll just give you some
>> background.
>>
>> We would ultimately like APIs that allocate and initialize in one go.
>> It’s important that the current lower-level (dangerous) APIs make a clear
>> distinction between initialized and uninitialized memory to avoid confusing
>> them with future (safer) APIs. `capacity` always refers to memory that may
>> be uninitialized. I think that’s very clear and helpful.
>>
>> In the context of pointers `count` should always be in strides. For raw
>> pointers, that happens to be the same as as `bytes`.
>>
>> I initially proposed copy(bytes:from:), but someone thought that `bytes`
>> in this particular context did not properly convey the "count of bytes" as
>> opposed to the source of the bytes. You’re right, that’s inconsistent with
>> allocate/deallocate(bytes:), because allocateBytes(count:) would be silly.
>> Just be aware that the inconsistency is a result of over-thinking and
>> excessive bike shedding to the detriment of something that looks nice and
>> is easy to remember.
>>
>> I should also point out that the inconsistencies in functionality across
>> pointer types, in terms of collection support and other convenience, is
>> also known but was deliberately stripped from proposals as “additive”.
>>
>> -Andy
>>
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-13 Thread Andrew Trick via swift-evolution

> On Jul 13, 2017, at 10:30 PM, Taylor Swift  wrote:
> 
> I’m confused I thought we were talking about the naming choices for the 
> argument labels in those functions. I think defining and abiding by 
> consistent meanings for `count`, `capacity`, and `bytes` is a good idea, and 
> it’s part of what this proposal tries to accomplish. Right now half the time 
> we use `count` to refer to “bytes” and half the time we use it to refer to 
> “instances”. The same goes for the word “capacity”. This is all laid out in 
> the document:
> 
> “““
> Finally, the naming and design of some UnsafeMutableRawPointer members 
> deserves to be looked at. The usage of capacity, bytes, and count as argument 
> labels is wildly inconsistent and confusing. In copyBytes(from:count:), count 
> refers to the number of bytes, while in initializeMemory(as:at:count:to:) 
> and initializeMemory(as:from:count:), count refers to the number of 
> strides. Meanwhile bindMemory(to:capacity:) uses capacity to refer to this 
> quantity. The always-problematic deallocate(bytes:alignedTo) method and 
> allocate(bytes:alignedTo:) type methods use bytes to refer to 
> byte-quantities. Adding to the confusion, UnsafeMutableRawBufferPointer 
> offers an allocate(count:) type method (the same signature method we’re 
> trying to add to UnsafeMutableBufferPointer), except the count in this method 
> refers to bytes. This kind of API naming begets stride bugs and makes Swift 
> needlessly difficult to learn.
> ”””
> 
> The only convenience methods this proposal is trying to add is the 
> functionality on the buffer pointer types. There seems to be broad support 
> for adding this functionality as no one has really opposed that part of the 
> proposal yet. Any other new methods like `UnsafeMutablePointer.assign(to:)` 
> are there for API consistency.
> 
> This proposal also calls for getting rid of one of those “redundant 
> initializers” :)

Since we’re not bike-shedding the specifics yet, I’ll just give you some 
background.

We would ultimately like APIs that allocate and initialize in one go. It’s 
important that the current lower-level (dangerous) APIs make a clear 
distinction between initialized and uninitialized memory to avoid confusing 
them with future (safer) APIs. `capacity` always refers to memory that may be 
uninitialized. I think that’s very clear and helpful.

In the context of pointers `count` should always be in strides. For raw 
pointers, that happens to be the same as as `bytes`.

I initially proposed copy(bytes:from:), but someone thought that `bytes` in 
this particular context did not properly convey the "count of bytes" as opposed 
to the source of the bytes. You’re right, that’s inconsistent with 
allocate/deallocate(bytes:), because allocateBytes(count:) would be silly. Just 
be aware that the inconsistency is a result of over-thinking and excessive bike 
shedding to the detriment of something that looks nice and is easy to remember.

I should also point out that the inconsistencies in functionality across 
pointer types, in terms of collection support and other convenience, is also 
known but was deliberately stripped from proposals as “additive”.

-Andy___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-13 Thread Taylor Swift via swift-evolution
On Fri, Jul 14, 2017 at 12:29 AM, Andrew Trick  wrote:

>
> On Jul 13, 2017, at 6:16 PM, Taylor Swift via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> I am not very familiar with the inner workings of the standard library,
> however I maintain a few libraries which make extensive use of Swift
> pointers, such as https://github.com/kelvin13/maxpng which makes
> extensive use of Unsafe_Pointers. I also write a lot of code that
> interfaces with C APIs like Cairo and OpenGL. Most of the ideas in the
> original proposal came from me dealing with the current Swift pointer APIs
> in my own code. For example I find myself writing this bit of code
>
> let buffer = UnsafeMutableBufferPointer(start: 
> UnsafeMutablePointer.allocate(capacity: byteCount), count: 
> byteCount)defer
> {
> buffer.baseAddress?.deallocate(capacity: buffer.count)
> }
>
> far more than I would like to. While this proposal doesn’t solve every 
> problem with Swift pointers — for example, we need a UMBP initializer that 
> takes an immutable buffer pointer before we are really able to write a lot of 
> examples more concisely, it takes us a great deal closer to being able to 
> write things like
>
> UnsafeMutablePointer(mutating: 
> self.zero_line.baseAddress!).deallocate(capacity: self.zero_line.count)
>
> as
>
> UnsafeMutableBufferPointer(mutating: self.zero_line).deallocate()
>
>
> You should not need to do this at all. A pointer does not need to be
> mutable to deallocate the memory. That’s a bug in the UnsafePointer API.
>
> -Andy
>
>
I think this falls under “convenience methods that would be really nice to
have but should probably go in a separate proposal”.

>
> On Thu, Jul 13, 2017 at 2:47 PM, Dave Abrahams via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>>
>> on Wed Jul 12 2017, Taylor Swift  wrote:
>>
>> > Hi all, I’ve written up a proposal to modify the unsafe pointer API for
>> > greater consistency, safety, and ease of use.
>> >
>> > ~~~
>> >
>> > Swift currently offers two sets of pointer types — singular pointers
>> such
>> > as UnsafeMutablePointer, and vector (buffer) pointers such as
>> UnsafeMutable
>> > *Buffer*Pointer. This implies a natural separation of tasks the two
>> kinds
>> > of pointers are meant to do. For example, buffer pointers implement
>> > Collection conformance, while singular pointers do not.
>> >
>> > However, some aspects of the pointer design contradict these implied
>> roles.
>> > It is possible to allocate an arbitrary number of instances from a type
>> > method on a singular pointer, but not from a buffer pointer. The result
>> of
>> > such an operation returns a singular pointer, even though a buffer
>> pointer
>> > would be more appropriate to capture the information about the *number*
>> of
>> > instances allocated. It’s possible to subscript into a singular pointer,
>> > even though they are not real Collections. Some parts of the current
>> design
>> > turn UnsafePointers into downright *Dangerous*Pointers, leading users to
>> > believe that they have allocated or freed memory when in fact, they have
>> > not.
>> >
>> > This proposal seeks to iron out these inconsistencies, and offer a more
>> > convenient, more sensible, and less bug-prone API for Swift pointers.
>> >
>> > 
>>
>> I have no problem with this direction in principle; it sounds like a
>> good idea.  However, before affirming any particular design I would like
>> to see the results of any such proposal applied to a fairly large body
>> of code that uses Unsafe[XXX]Pointer today in diverse ways (such as the
>> Swift standard library itself), to demonstrate that it does in fact
>> improve the code in practice.
>>
>> Cheers,
>>
>> --
>> -Dave
>>
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-13 Thread Taylor Swift via swift-evolution
On Fri, Jul 14, 2017 at 12:22 AM, Andrew Trick  wrote:

>
> On Jul 13, 2017, at 6:55 PM, Taylor Swift  wrote:
>
>
>
> On Thu, Jul 13, 2017 at 6:56 PM, Andrew Trick  wrote:
>
>>
>> On Jul 12, 2017, at 12:16 PM, Taylor Swift via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> Hi all, I’ve written up a proposal to modify the unsafe pointer API for
>> greater consistency, safety, and ease of use.
>>
>> ~~~
>>
>> Swift currently offers two sets of pointer types — singular pointers such
>> as UnsafeMutablePointer, and vector (buffer) pointers such as
>> UnsafeMutable*Buffer*Pointer. This implies a natural separation of tasks
>> the two kinds of pointers are meant to do. For example, buffer pointers
>> implement Collection conformance, while singular pointers do not.
>>
>> However, some aspects of the pointer design contradict these implied
>> roles. It is possible to allocate an arbitrary number of instances from a
>> type method on a singular pointer, but not from a buffer pointer. The
>> result of such an operation returns a singular pointer, even though a
>> buffer pointer would be more appropriate to capture the information about
>> the *number* of instances allocated. It’s possible to subscript into a
>> singular pointer, even though they are not real Collections. Some parts
>> of the current design turn UnsafePointers into downright *Dangerous*Pointers,
>> leading users to believe that they have allocated or freed memory when in
>> fact, they have not.
>>
>> This proposal seeks to iron out these inconsistencies, and offer a more
>> convenient, more sensible, and less bug-prone API for Swift pointers.
>>
>> 
>>
>> ~~~
>>
>>
>> Thanks for taking time to write this up.
>>
>> General comments:
>>
>> UnsafeBufferPointer is an API layer on top of UnsafePointer. The role
>> of UnsafeBufferPointer is direct memory access sans lifetime
>> management with Collection semantics. The role of UnsafePointer is
>> primarily C interop. Those C APIs should be wrapped in Swift APIs that
>> take UnsafeBufferPointer whenever the pointer represents a C array. I
>> suppose making UnsafePointer less convenient would push developers
>> toward UnsafeBufferPointer. I don't think that's worth outright
>> breaking source, but gradual deprecation of convenience methods, like
>> `susbscript` might be acceptable.
>>
>
> Gradual deprecation is exactly what I am proposing. As the document states
> ,
> the only methods which should be marked immediately as unavailable are the `
> deallocate(capacity:)` methods, for safety and source compatibility
> reasons. Removing `deallocate(capacity:)` now and forcing a loud compiler
> error prevents catastrophic *silent* source breakage in the future, or
> worse, from having to *support our own bug*.
>
>>
>>
>> I have mixed feelings about stripping UnsafePointer of basic
>> functionality. Besides breaking source, doing that would be
>> inconsistent with its role as a lower API layer. The advantage would
>> just be descreasing API surface area and forcing developers to use a
>> higher-level API.
>>
>
> UnsafePointer is as much a high level API as UnsafeBufferPointer is.
>
>
> No it isn’t. We don’t have support for importing certain function
> signatures as taking UnsafeBufferPointer and UnsafePointer doesn't conform
> to Collection even though it nearly always represents an array.
>

C functions get imported as taking UnsafePointers because buffer pointers
in C are represented as pointer–length pairs. UnsafePointer can’t conform
to Collection because there’s no way to automatically associate that length
information with the pointer. So why do you think UnsafePointers should
support doing Collection-y things if a precondition for performing
collection-y operations is knowing the length? No sense exposing a `capacity`
argument if you don’t have a `count` to go in it. That’s why I don’t really
agree with viewing UnsafePointers as arrays, since trying to do random
access into something you don’t know the length of seems off to me.


>
> You wouldn’t create a buffer pointer of length 1 just so you can “stick
> with the high level API”. UnsafePointer and UnsafeBufferPointer are two
> tools that do related but different things and they can exist at whatever
> abstract level you need them at. After all, UnsafeBufferPointer is nothing
> but an UnsafePointer? with a length value attached to it. If you’re
> allocating more than one instance of memory, you almost certainly need to
> track the length of the buffer anyway.
>
>
> You could call this a proposal to "make unsafe pointer APIs easier to use
> safely". I just want to put an end to the fallacy that the buffer type is
> for multiple values and the plain old pointer represents single instances.
>

I mean, parts of the current API do heavily suggest that the plain pointer
is for single instances — t

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-13 Thread Andrew Trick via swift-evolution

> On Jul 13, 2017, at 6:16 PM, Taylor Swift via swift-evolution 
>  wrote:
> 
> I am not very familiar with the inner workings of the standard library, 
> however I maintain a few libraries which make extensive use of Swift 
> pointers, such as https://github.com/kelvin13/maxpng 
>  which makes extensive use of 
> Unsafe_Pointers. I also write a lot of code that interfaces with C APIs 
> like Cairo and OpenGL. Most of the ideas in the original proposal came from 
> me dealing with the current Swift pointer APIs in my own code. For example I 
> find myself writing this bit of code 
> 
> let buffer = UnsafeMutableBufferPointer(start: 
> UnsafeMutablePointer.allocate(capacity: byteCount), count: byteCount)
> defer
> {
> buffer.baseAddress?.deallocate(capacity: buffer.count)
> }
> 
> far more than I would like to. While this proposal doesn’t solve every 
> problem with Swift pointers — for example, we need a UMBP initializer that 
> takes an immutable buffer pointer before we are really able to write a lot of 
> examples more concisely, it takes us a great deal closer to being able to 
> write things like 
> 
> UnsafeMutablePointer(mutating: 
> self.zero_line.baseAddress!).deallocate(capacity: self.zero_line.count)
> 
> as 
> 
> UnsafeMutableBufferPointer(mutating: self.zero_line).deallocate()

You should not need to do this at all. A pointer does not need to be mutable to 
deallocate the memory. That’s a bug in the UnsafePointer API.

-Andy

> 
> On Thu, Jul 13, 2017 at 2:47 PM, Dave Abrahams via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> on Wed Jul 12 2017, Taylor Swift  > wrote:
> 
> > Hi all, I’ve written up a proposal to modify the unsafe pointer API for
> > greater consistency, safety, and ease of use.
> >
> > ~~~
> >
> > Swift currently offers two sets of pointer types — singular pointers such
> > as UnsafeMutablePointer, and vector (buffer) pointers such as UnsafeMutable
> > *Buffer*Pointer. This implies a natural separation of tasks the two kinds
> > of pointers are meant to do. For example, buffer pointers implement
> > Collection conformance, while singular pointers do not.
> >
> > However, some aspects of the pointer design contradict these implied roles.
> > It is possible to allocate an arbitrary number of instances from a type
> > method on a singular pointer, but not from a buffer pointer. The result of
> > such an operation returns a singular pointer, even though a buffer pointer
> > would be more appropriate to capture the information about the *number* of
> > instances allocated. It’s possible to subscript into a singular pointer,
> > even though they are not real Collections. Some parts of the current design
> > turn UnsafePointers into downright *Dangerous*Pointers, leading users to
> > believe that they have allocated or freed memory when in fact, they have
> > not.
> >
> > This proposal seeks to iron out these inconsistencies, and offer a more
> > convenient, more sensible, and less bug-prone API for Swift pointers.
> >
> >  > >
> 
> I have no problem with this direction in principle; it sounds like a
> good idea.  However, before affirming any particular design I would like
> to see the results of any such proposal applied to a fairly large body
> of code that uses Unsafe[XXX]Pointer today in diverse ways (such as the
> Swift standard library itself), to demonstrate that it does in fact
> improve the code in practice.
> 
> Cheers,
> 
> --
> -Dave
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-13 Thread Andrew Trick via swift-evolution

> On Jul 13, 2017, at 6:55 PM, Taylor Swift  wrote:
> 
> 
> 
> On Thu, Jul 13, 2017 at 6:56 PM, Andrew Trick  > wrote:
> 
>> On Jul 12, 2017, at 12:16 PM, Taylor Swift via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Hi all, I’ve written up a proposal to modify the unsafe pointer API for 
>> greater consistency, safety, and ease of use.
>> 
>> ~~~
>> 
>> Swift currently offers two sets of pointer types — singular pointers such as 
>> UnsafeMutablePointer, and vector (buffer) pointers such as 
>> UnsafeMutableBufferPointer. This implies a natural separation of tasks the 
>> two kinds of pointers are meant to do. For example, buffer pointers 
>> implement Collection conformance, while singular pointers do not.
>> 
>> However, some aspects of the pointer design contradict these implied roles. 
>> It is possible to allocate an arbitrary number of instances from a type 
>> method on a singular pointer, but not from a buffer pointer. The result of 
>> such an operation returns a singular pointer, even though a buffer pointer 
>> would be more appropriate to capture the information about the number of 
>> instances allocated. It’s possible to subscript into a singular pointer, 
>> even though they are not real Collections. Some parts of the current design 
>> turn UnsafePointers into downright DangerousPointers, leading users to 
>> believe that they have allocated or freed memory when in fact, they have not.
>> 
>> This proposal seeks to iron out these inconsistencies, and offer a more 
>> convenient, more sensible, and less bug-prone API for Swift pointers.
>> 
>> > >
>> 
>> ~~~
>> 
> 
> Thanks for taking time to write this up.
> 
> General comments:
> 
> UnsafeBufferPointer is an API layer on top of UnsafePointer. The role
> of UnsafeBufferPointer is direct memory access sans lifetime
> management with Collection semantics. The role of UnsafePointer is
> primarily C interop. Those C APIs should be wrapped in Swift APIs that
> take UnsafeBufferPointer whenever the pointer represents a C array. I
> suppose making UnsafePointer less convenient would push developers
> toward UnsafeBufferPointer. I don't think that's worth outright
> breaking source, but gradual deprecation of convenience methods, like
> `susbscript` might be acceptable.
> 
> Gradual deprecation is exactly what I am proposing. As the document states 
> ,
>  the only methods which should be marked immediately as unavailable are the 
> `deallocate(capacity:)` methods, for safety and source compatibility reasons. 
> Removing `deallocate(capacity:)` now and forcing a loud compiler error 
> prevents catastrophic *silent* source breakage in the future, or worse, from 
> having to *support our own bug*.
>  
> 
> I have mixed feelings about stripping UnsafePointer of basic
> functionality. Besides breaking source, doing that would be
> inconsistent with its role as a lower API layer. The advantage would
> just be descreasing API surface area and forcing developers to use a
> higher-level API.
> 
> UnsafePointer is as much a high level API as UnsafeBufferPointer is.

No it isn’t. We don’t have support for importing certain function signatures as 
taking UnsafeBufferPointer and UnsafePointer doesn't conform to Collection even 
though it nearly always represents an array.

> You wouldn’t create a buffer pointer of length 1 just so you can “stick with 
> the high level API”. UnsafePointer and UnsafeBufferPointer are two tools that 
> do related but different things and they can exist at whatever abstract level 
> you need them at. After all, UnsafeBufferPointer is nothing but an 
> UnsafePointer? with a length value attached to it. If you’re allocating more 
> than one instance of memory, you almost certainly need to track the length of 
> the buffer anyway.

You could call this a proposal to "make unsafe pointer APIs easier to use 
safely". I just want to put an end to the fallacy that the buffer type is for 
multiple values and the plain old pointer represents single instances.

> The additive changes you propose are fairly obvious. See [SR-3088]
> UnsafeMutableBufferPointer doesn't have an allocating init.
> 
> I haven't wanted to waste review cycles on small additive
> changes. It may make sense to batch them up into one coherent
> proposal. Here are a few more to consider.
> 
> - [SR-3929] UnsafeBufferPointer should have init from mutable
> - [SR-4340] UnsafeBufferPointer needs a withMemoryRebound method
> - [SR-3087] No way to arbitrarily initialise an Array's storage
> 
> The feature requests you mention are all very valuable, however with 
> Michael’s point about fixing the memorystate API’s, the size of this proposal 
> has already grown to encompass dozens of methods in five types. I 

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-13 Thread Taylor Swift via swift-evolution
On Thu, Jul 13, 2017 at 6:56 PM, Andrew Trick  wrote:

>
> On Jul 12, 2017, at 12:16 PM, Taylor Swift via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Hi all, I’ve written up a proposal to modify the unsafe pointer API for
> greater consistency, safety, and ease of use.
>
> ~~~
>
> Swift currently offers two sets of pointer types — singular pointers such
> as UnsafeMutablePointer, and vector (buffer) pointers such as
> UnsafeMutable*Buffer*Pointer. This implies a natural separation of tasks
> the two kinds of pointers are meant to do. For example, buffer pointers
> implement Collection conformance, while singular pointers do not.
>
> However, some aspects of the pointer design contradict these implied
> roles. It is possible to allocate an arbitrary number of instances from a
> type method on a singular pointer, but not from a buffer pointer. The
> result of such an operation returns a singular pointer, even though a
> buffer pointer would be more appropriate to capture the information about
> the *number* of instances allocated. It’s possible to subscript into a
> singular pointer, even though they are not real Collections. Some parts
> of the current design turn UnsafePointers into downright *Dangerous*Pointers,
> leading users to believe that they have allocated or freed memory when in
> fact, they have not.
>
> This proposal seeks to iron out these inconsistencies, and offer a more
> convenient, more sensible, and less bug-prone API for Swift pointers.
>
> 
>
> ~~~
>
>
> Thanks for taking time to write this up.
>
> General comments:
>
> UnsafeBufferPointer is an API layer on top of UnsafePointer. The role
> of UnsafeBufferPointer is direct memory access sans lifetime
> management with Collection semantics. The role of UnsafePointer is
> primarily C interop. Those C APIs should be wrapped in Swift APIs that
> take UnsafeBufferPointer whenever the pointer represents a C array. I
> suppose making UnsafePointer less convenient would push developers
> toward UnsafeBufferPointer. I don't think that's worth outright
> breaking source, but gradual deprecation of convenience methods, like
> `susbscript` might be acceptable.
>

Gradual deprecation is exactly what I am proposing. As the document states
,
the only methods which should be marked immediately as unavailable are the `
deallocate(capacity:)` methods, for safety and source compatibility
reasons. Removing `deallocate(capacity:)` now and forcing a loud compiler
error prevents catastrophic *silent* source breakage in the future, or
worse, from having to *support our own bug*.

>
>
> I have mixed feelings about stripping UnsafePointer of basic
> functionality. Besides breaking source, doing that would be
> inconsistent with its role as a lower API layer. The advantage would
> just be descreasing API surface area and forcing developers to use a
> higher-level API.
>

UnsafePointer is as much a high level API as UnsafeBufferPointer is. You
wouldn’t create a buffer pointer of length 1 just so you can “stick with
the high level API”. UnsafePointer and UnsafeBufferPointer are two tools
that do related but different things and they can exist at whatever
abstract level you need them at. After all, UnsafeBufferPointer is nothing
but an UnsafePointer? with a length value attached to it. If you’re
allocating more than one instance of memory, you almost certainly need to
track the length of the buffer anyway.


> The additive changes you propose are fairly obvious. See [SR-3088]
> UnsafeMutableBufferPointer doesn't have an allocating init.
>
> I haven't wanted to waste review cycles on small additive
> changes. It may make sense to batch them up into one coherent
> proposal. Here are a few more to consider.
>
> - [SR-3929] UnsafeBufferPointer should have init from mutable
> - [SR-4340] UnsafeBufferPointer needs a withMemoryRebound method
> - [SR-3087] No way to arbitrarily initialise an Array's storage
>

The feature requests you mention are all very valuable, however with
Michael’s point about fixing the memorystate API’s, the size of this
proposal has already grown to encompass dozens of methods in five types. I
think this says a lot about just how broken the current system is, but I
think it’s better to try to fix one class of problems at a time, and save
the less closely-related issues for separate proposals.


>
> Point by point:
>
> > drop the capacity parameter from UnsafeMutablePointer.allocate() and
> deallocate().
>
> I do not agree with removing the capacity parameter and adding a
> single-instance allocation API. UnsafePointer was not designed for
> single instances, it was primarily designed for C-style arrays. I
> don't see the value in providing a different unsafe API for single
> vs. multiple values.
>

Although it’s common to *receive* Unsafe__Pointers from C API’s, it’s rare
to *create* t

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-13 Thread Taylor Swift via swift-evolution
I am not very familiar with the inner workings of the standard library,
however I maintain a few libraries which make extensive use of Swift
pointers, such as https://github.com/kelvin13/maxpng which makes extensive
use of Unsafe_Pointers. I also write a lot of code that interfaces with
C APIs like Cairo and OpenGL. Most of the ideas in the original proposal
came from me dealing with the current Swift pointer APIs in my own code.
For example I find myself writing this bit of code

let buffer = UnsafeMutableBufferPointer(start:
UnsafeMutablePointer.allocate(capacity: byteCount), count:
byteCount)defer
{
buffer.baseAddress?.deallocate(capacity: buffer.count)
}

far more than I would like to. While this proposal doesn’t solve every
problem with Swift pointers — for example, we need a UMBP initializer
that takes an immutable buffer pointer before we are really able to
write a lot of examples more concisely, it takes us a great deal
closer to being able to write things like

UnsafeMutablePointer(mutating:
self.zero_line.baseAddress!).deallocate(capacity:
self.zero_line.count)

as

UnsafeMutableBufferPointer(mutating: self.zero_line).deallocate()


On Thu, Jul 13, 2017 at 2:47 PM, Dave Abrahams via swift-evolution <
swift-evolution@swift.org> wrote:

>
> on Wed Jul 12 2017, Taylor Swift  wrote:
>
> > Hi all, I’ve written up a proposal to modify the unsafe pointer API for
> > greater consistency, safety, and ease of use.
> >
> > ~~~
> >
> > Swift currently offers two sets of pointer types — singular pointers such
> > as UnsafeMutablePointer, and vector (buffer) pointers such as
> UnsafeMutable
> > *Buffer*Pointer. This implies a natural separation of tasks the two kinds
> > of pointers are meant to do. For example, buffer pointers implement
> > Collection conformance, while singular pointers do not.
> >
> > However, some aspects of the pointer design contradict these implied
> roles.
> > It is possible to allocate an arbitrary number of instances from a type
> > method on a singular pointer, but not from a buffer pointer. The result
> of
> > such an operation returns a singular pointer, even though a buffer
> pointer
> > would be more appropriate to capture the information about the *number*
> of
> > instances allocated. It’s possible to subscript into a singular pointer,
> > even though they are not real Collections. Some parts of the current
> design
> > turn UnsafePointers into downright *Dangerous*Pointers, leading users to
> > believe that they have allocated or freed memory when in fact, they have
> > not.
> >
> > This proposal seeks to iron out these inconsistencies, and offer a more
> > convenient, more sensible, and less bug-prone API for Swift pointers.
> >
> > 
>
> I have no problem with this direction in principle; it sounds like a
> good idea.  However, before affirming any particular design I would like
> to see the results of any such proposal applied to a fairly large body
> of code that uses Unsafe[XXX]Pointer today in diverse ways (such as the
> Swift standard library itself), to demonstrate that it does in fact
> improve the code in practice.
>
> Cheers,
>
> --
> -Dave
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-13 Thread Taylor Swift via swift-evolution
Hi all, i’ve put out a new revision of the proposal which addresses
Michael’s point about dealing with the memorystate APIs along with the
allocation and deallocation API. I didn’t really think about fixing the
memorystate functions originally, but on closer inspection, they are almost
as problematic as the memory allocation API and deserve a closer look.

Here’s a new version of the proposal with revisions



On Wed, Jul 12, 2017 at 6:46 PM, Taylor Swift via swift-evolution <
swift-evolution@swift.org> wrote:

> I originally thought that would be too many changes for one proposal but
> if y’all think it’s a good idea to deal with those functions too I’m happy
> to add it to the proposal!
>
> On Wed, Jul 12, 2017 at 5:07 PM, Michael Ilseman 
> wrote:
>
>> If you’re considering moving allocate/deallocate to Unsafe*BufferPointer,
>> then you probably also want to consider doing the same for initialize,
>> deinitialize, and various move functions as well.
>>
>> On Jul 12, 2017, at 12:16 PM, Taylor Swift via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> Hi all, I’ve written up a proposal to modify the unsafe pointer API for
>> greater consistency, safety, and ease of use.
>>
>> ~~~
>>
>> Swift currently offers two sets of pointer types — singular pointers such
>> as UnsafeMutablePointer, and vector (buffer) pointers such as
>> UnsafeMutable*Buffer*Pointer. This implies a natural separation of tasks
>> the two kinds of pointers are meant to do. For example, buffer pointers
>> implement Collection conformance, while singular pointers do not.
>>
>> However, some aspects of the pointer design contradict these implied
>> roles. It is possible to allocate an arbitrary number of instances from a
>> type method on a singular pointer, but not from a buffer pointer. The
>> result of such an operation returns a singular pointer, even though a
>> buffer pointer would be more appropriate to capture the information about
>> the *number* of instances allocated. It’s possible to subscript into a
>> singular pointer, even though they are not real Collections. Some parts
>> of the current design turn UnsafePointers into downright *Dangerous*Pointers,
>> leading users to believe that they have allocated or freed memory when in
>> fact, they have not.
>>
>> This proposal seeks to iron out these inconsistencies, and offer a more
>> convenient, more sensible, and less bug-prone API for Swift pointers.
>>
>> 
>>
>> ~~~
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-13 Thread Andrew Trick via swift-evolution

> On Jul 12, 2017, at 12:16 PM, Taylor Swift via swift-evolution 
>  wrote:
> 
> Hi all, I’ve written up a proposal to modify the unsafe pointer API for 
> greater consistency, safety, and ease of use.
> 
> ~~~
> 
> Swift currently offers two sets of pointer types — singular pointers such as 
> UnsafeMutablePointer, and vector (buffer) pointers such as 
> UnsafeMutableBufferPointer. This implies a natural separation of tasks the 
> two kinds of pointers are meant to do. For example, buffer pointers implement 
> Collection conformance, while singular pointers do not.
> 
> However, some aspects of the pointer design contradict these implied roles. 
> It is possible to allocate an arbitrary number of instances from a type 
> method on a singular pointer, but not from a buffer pointer. The result of 
> such an operation returns a singular pointer, even though a buffer pointer 
> would be more appropriate to capture the information about the number of 
> instances allocated. It’s possible to subscript into a singular pointer, even 
> though they are not real Collections. Some parts of the current design turn 
> UnsafePointers into downright DangerousPointers, leading users to believe 
> that they have allocated or freed memory when in fact, they have not.
> 
> This proposal seeks to iron out these inconsistencies, and offer a more 
> convenient, more sensible, and less bug-prone API for Swift pointers.
> 
>  >
> 
> ~~~
> 

Thanks for taking time to write this up.

General comments:

UnsafeBufferPointer is an API layer on top of UnsafePointer. The role
of UnsafeBufferPointer is direct memory access sans lifetime
management with Collection semantics. The role of UnsafePointer is
primarily C interop. Those C APIs should be wrapped in Swift APIs that
take UnsafeBufferPointer whenever the pointer represents a C array. I
suppose making UnsafePointer less convenient would push developers
toward UnsafeBufferPointer. I don't think that's worth outright
breaking source, but gradual deprecation of convenience methods, like
`susbscript` might be acceptable.

I have mixed feelings about stripping UnsafePointer of basic
functionality. Besides breaking source, doing that would be
inconsistent with its role as a lower API layer. The advantage would
just be descreasing API surface area and forcing developers to use a
higher-level API.

The additive changes you propose are fairly obvious. See [SR-3088]
UnsafeMutableBufferPointer doesn't have an allocating init.

I haven't wanted to waste review cycles on small additive
changes. It may make sense to batch them up into one coherent
proposal. Here are a few more to consider.

- [SR-3929] UnsafeBufferPointer should have init from mutable
- [SR-4340] UnsafeBufferPointer needs a withMemoryRebound method
- [SR-3087] No way to arbitrarily initialise an Array's storage

Point by point:

> drop the capacity parameter from UnsafeMutablePointer.allocate() and 
> deallocate().

I do not agree with removing the capacity parameter and adding a
single-instance allocation API. UnsafePointer was not designed for
single instances, it was primarily designed for C-style arrays. I
don't see the value in providing a different unsafe API for single
vs. multiple values.

I agree the primary allocation API should be
UnsafeMutableBufferPointer.allocate(capacity:). There is an argument
to be made for removing UnsafeMutablePointer.allocate(capacity:)
entirely. But, as Michael Ilseman pointed out, that would involve
reevaluating several other members of the UnsafePointer API. I think
it's reasonable for UnsafePointer to retain all its functionality as a
lower level API.

I don't understand what is misleading about
UnsafePointer.deallocate(capacity:). It *is* inconvenienent for the
user to keep track of memory capacity. Presumably that was done so
either the implementation can move away from malloc/free or some sort
of memory tracking can be implemented on the standard library
side. Obviously, UnsafeBufferPointer.deallocate() would be cleaner in
most cases.

> add an allocate(count:) type method to UnsafeMutableBufferPointer

`capacity` should be used for allocating uninitialized memory not
`count`. `count` should only refer to a number of initialized objects!

> add a deallocate() instance method to UnsafeMutableBufferPointer

Yes, of course! I added a mention of that in SR-3088.

> remove subscripts from UnsafePointer and UnsafeMutablePointer

It's often more clear to perform arithmetic on C array indices rather
than pointers. That said, I'm happy to push developers to use
UnsafeBufferPointer whenever that have a known capacity. To me, this
is a question of whether the benefit of making a dangerous thing less
convenient is worth breaking source compatibility.

-Andy

___
swift-evolution mailing list
swift-evolution@swift.org
http

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-13 Thread Dave Abrahams via swift-evolution

on Wed Jul 12 2017, Taylor Swift  wrote:

> Hi all, I’ve written up a proposal to modify the unsafe pointer API for
> greater consistency, safety, and ease of use.
>
> ~~~
>
> Swift currently offers two sets of pointer types — singular pointers such
> as UnsafeMutablePointer, and vector (buffer) pointers such as UnsafeMutable
> *Buffer*Pointer. This implies a natural separation of tasks the two kinds
> of pointers are meant to do. For example, buffer pointers implement
> Collection conformance, while singular pointers do not.
>
> However, some aspects of the pointer design contradict these implied roles.
> It is possible to allocate an arbitrary number of instances from a type
> method on a singular pointer, but not from a buffer pointer. The result of
> such an operation returns a singular pointer, even though a buffer pointer
> would be more appropriate to capture the information about the *number* of
> instances allocated. It’s possible to subscript into a singular pointer,
> even though they are not real Collections. Some parts of the current design
> turn UnsafePointers into downright *Dangerous*Pointers, leading users to
> believe that they have allocated or freed memory when in fact, they have
> not.
>
> This proposal seeks to iron out these inconsistencies, and offer a more
> convenient, more sensible, and less bug-prone API for Swift pointers.
>
> 

I have no problem with this direction in principle; it sounds like a
good idea.  However, before affirming any particular design I would like
to see the results of any such proposal applied to a fairly large body
of code that uses Unsafe[XXX]Pointer today in diverse ways (such as the
Swift standard library itself), to demonstrate that it does in fact
improve the code in practice.

Cheers,

-- 
-Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-12 Thread Taylor Swift via swift-evolution
I originally thought that would be too many changes for one proposal but if
y’all think it’s a good idea to deal with those functions too I’m happy to
add it to the proposal!

On Wed, Jul 12, 2017 at 5:07 PM, Michael Ilseman  wrote:

> If you’re considering moving allocate/deallocate to Unsafe*BufferPointer,
> then you probably also want to consider doing the same for initialize,
> deinitialize, and various move functions as well.
>
> On Jul 12, 2017, at 12:16 PM, Taylor Swift via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Hi all, I’ve written up a proposal to modify the unsafe pointer API for
> greater consistency, safety, and ease of use.
>
> ~~~
>
> Swift currently offers two sets of pointer types — singular pointers such
> as UnsafeMutablePointer, and vector (buffer) pointers such as
> UnsafeMutable*Buffer*Pointer. This implies a natural separation of tasks
> the two kinds of pointers are meant to do. For example, buffer pointers
> implement Collection conformance, while singular pointers do not.
>
> However, some aspects of the pointer design contradict these implied
> roles. It is possible to allocate an arbitrary number of instances from a
> type method on a singular pointer, but not from a buffer pointer. The
> result of such an operation returns a singular pointer, even though a
> buffer pointer would be more appropriate to capture the information about
> the *number* of instances allocated. It’s possible to subscript into a
> singular pointer, even though they are not real Collections. Some parts
> of the current design turn UnsafePointers into downright *Dangerous*Pointers,
> leading users to believe that they have allocated or freed memory when in
> fact, they have not.
>
> This proposal seeks to iron out these inconsistencies, and offer a more
> convenient, more sensible, and less bug-prone API for Swift pointers.
>
> 
>
> ~~~
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-12 Thread Taylor Swift via swift-evolution
i’m sorry this sounds like something different than what this proposal is
trying to achieve. Right now I’m just trying to smooth out the singular vs.
vector functionality of the existing Swift pointer types. Maybe your idea
would be better in a separate proposal?

On Wed, Jul 12, 2017 at 4:16 PM, Gor Gyolchanyan 
wrote:

> In my understanding, the address manipulation abstractions are as follows:
>
>- An *address* is an integer denoting an index into the current *address
>space* (which, in case of a user-space process, is a virtual address
>space, uniquely allocated by the operating system for that process). The 
> *minimal
>addressable unit* (also known as *byte*, which is not to be confused
>with an *octet*) of the address space is the number of contiguous *binary
>digits* (also known as *bits*) that are uniquely identified by a
>single address (in most modern architectures that number is *8*).
>- A *buffer* is a range of addresses, denoting a fragment of the
>address space, where the delimited contiguous sequence of addresses share
>common semantics.
>- A *pointer* is a buffer with some metadata. In statically typed
>languages the length of the buffer is a compile-time constant and metadata
>contains type information of the buffer’s contents.
>- An *array* is a buffer, representing a contiguous sequence of
>pointers.
>
>
> Notice, that in above terms the address space is essentially a buffer
> denoting all available addresses.
>
> In Swift, the aforementioned concepts correspond to the following types:
>
>- *address*: UnsafeRawPointer, UnsafeRawMutablePointer, OpaquePointer.
>- *buffer*: UnsafeRawBufferPointer, UnsafeMutableRawBufferPointer.
>- *pointer*: UnsafePointer, UnsafeMutablePointer,
>AutoreleasingUnsafeMutablePointer.
>- *array*: UnsafeBufferPointer, UnsafeMutableBufferPointer.
>
>
> If the unsafe tools of Swift would be redesigned, I’d suggest defining
> them in the following manner:
>
>- A comparable and hashable address that can be added an address
>offset, and subtracted another address to get an address offset. An address
>would also expose a mutable/immutable property that is the byte referred to
>by that address.
>- A buffer, that is a random access mutable/immutable collection of
>addresses, represented as a range.
>- A pointer, that is a generic type that is represented by an address
>and the inherent type information of its generic parameter. The pointer
>would only expose the address in the form of a buffer and would expose the
>referred object in the form of a mutable/immutable property of the
>respective type.
>- An array, that is a random access mutable/immutable collection of
>pointers, represented as a pointer coupled by a count.
>
>
> So, in the end, we’d have the following set of types: UnsafeAddress,
> UnsafeBuffer, UnsafePointer, UnsafeArray (as well as their mutable
> counter-parts).
> The OpaquePointer would then be a thin wrapper around UnsafeAddress and
> would probably better off renamed to CStructPointer, due to the fact that
> all non-C usages of this type should be replaced by usage of UnsafeAddress
> .
> And the AutoreleasingUnsafeMutablePointer would also be a thing wrapper
> around UnsafeAddress with a possible renaming to NSObjectPointer.
>
> On Jul 12, 2017, at 10:26 PM, Taylor Swift via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Hi all, I’ve written up a proposal to modify the unsafe pointer API for
> greater consistency, safety, and ease of use.
>
> ~~~
>
> Swift currently offers two sets of pointer types — singular pointers such
> as UnsafeMutablePointer, and vector (buffer) pointers such as
> UnsafeMutable*Buffer*Pointer. This implies a natural separation of tasks
> the two kinds of pointers are meant to do. For example, buffer pointers
> implement Collection conformance, while singular pointers do not.
>
> However, some aspects of the pointer design contradict these implied
> roles. It is possible to allocate an arbitrary number of instances from a
> type method on a singular pointer, but not from a buffer pointer. The
> result of such an operation returns a singular pointer, even though a
> buffer pointer would be more appropriate to capture the information about
> the *number* of instances allocated. It’s possible to subscript into a
> singular pointer, even though they are not real Collections. Some parts
> of the current design turn UnsafePointers into downright *Dangerous*Pointers,
> leading users to believe that they have allocated or freed memory when in
> fact, they have not.
>
> This proposal seeks to iron out these inconsistencies, and offer a more
> convenient, more sensible, and less bug-prone API for Swift pointers.
>
> 
>
> ~~~
> ___
> swift-evolution mailing list
> swift-evolution@swift.or

Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-12 Thread Michael Ilseman via swift-evolution
If you’re considering moving allocate/deallocate to Unsafe*BufferPointer, then 
you probably also want to consider doing the same for initialize, deinitialize, 
and various move functions as well.

> On Jul 12, 2017, at 12:16 PM, Taylor Swift via swift-evolution 
>  wrote:
> 
> Hi all, I’ve written up a proposal to modify the unsafe pointer API for 
> greater consistency, safety, and ease of use.
> 
> ~~~
> 
> Swift currently offers two sets of pointer types — singular pointers such as 
> UnsafeMutablePointer, and vector (buffer) pointers such as 
> UnsafeMutableBufferPointer. This implies a natural separation of tasks the 
> two kinds of pointers are meant to do. For example, buffer pointers implement 
> Collection conformance, while singular pointers do not.
> 
> However, some aspects of the pointer design contradict these implied roles. 
> It is possible to allocate an arbitrary number of instances from a type 
> method on a singular pointer, but not from a buffer pointer. The result of 
> such an operation returns a singular pointer, even though a buffer pointer 
> would be more appropriate to capture the information about the number of 
> instances allocated. It’s possible to subscript into a singular pointer, even 
> though they are not real Collections. Some parts of the current design turn 
> UnsafePointers into downright DangerousPointers, leading users to believe 
> that they have allocated or freed memory when in fact, they have not.
> 
> This proposal seeks to iron out these inconsistencies, and offer a more 
> convenient, more sensible, and less bug-prone API for Swift pointers.
> 
>  >
> 
> ~~~
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-12 Thread Gor Gyolchanyan via swift-evolution
In my understanding, the address manipulation abstractions are as follows:
An address is an integer denoting an index into the current address space 
(which, in case of a user-space process, is a virtual address space, uniquely 
allocated by the operating system for that process). The minimal addressable 
unit (also known as byte, which is not to be confused with an octet) of the 
address space is the number of contiguous binary digits (also known as bits) 
that are uniquely identified by a single address (in most modern architectures 
that number is 8).
A buffer is a range of addresses, denoting a fragment of the address space, 
where the delimited contiguous sequence of addresses share common semantics.
A pointer is a buffer with some metadata. In statically typed languages the 
length of the buffer is a compile-time constant and metadata contains type 
information of the buffer’s contents.
An array is a buffer, representing a contiguous sequence of pointers.

Notice, that in above terms the address space is essentially a buffer denoting 
all available addresses.

In Swift, the aforementioned concepts correspond to the following types:
address: UnsafeRawPointer, UnsafeRawMutablePointer, OpaquePointer.
buffer: UnsafeRawBufferPointer, UnsafeMutableRawBufferPointer.
pointer: UnsafePointer, UnsafeMutablePointer, AutoreleasingUnsafeMutablePointer.
array: UnsafeBufferPointer, UnsafeMutableBufferPointer.

If the unsafe tools of Swift would be redesigned, I’d suggest defining them in 
the following manner:
A comparable and hashable address that can be added an address offset, and 
subtracted another address to get an address offset. An address would also 
expose a mutable/immutable property that is the byte referred to by that 
address.
A buffer, that is a random access mutable/immutable collection of addresses, 
represented as a range.
A pointer, that is a generic type that is represented by an address and the 
inherent type information of its generic parameter. The pointer would only 
expose the address in the form of a buffer and would expose the referred object 
in the form of a mutable/immutable property of the respective type.
An array, that is a random access mutable/immutable collection of pointers, 
represented as a pointer coupled by a count.

So, in the end, we’d have the following set of types: UnsafeAddress, 
UnsafeBuffer, UnsafePointer, UnsafeArray (as well as their mutable 
counter-parts).
The OpaquePointer would then be a thin wrapper around UnsafeAddress and would 
probably better off renamed to CStructPointer, due to the fact that all non-C 
usages of this type should be replaced by usage of UnsafeAddress.
And the AutoreleasingUnsafeMutablePointer would also be a thing wrapper around 
UnsafeAddress with a possible renaming to NSObjectPointer.

> On Jul 12, 2017, at 10:26 PM, Taylor Swift via swift-evolution 
>  wrote:
> 
> Hi all, I’ve written up a proposal to modify the unsafe pointer API for 
> greater consistency, safety, and ease of use.
> 
> ~~~
> 
> Swift currently offers two sets of pointer types — singular pointers such as 
> UnsafeMutablePointer, and vector (buffer) pointers such as 
> UnsafeMutableBufferPointer. This implies a natural separation of tasks the 
> two kinds of pointers are meant to do. For example, buffer pointers implement 
> Collection conformance, while singular pointers do not.
> 
> However, some aspects of the pointer design contradict these implied roles. 
> It is possible to allocate an arbitrary number of instances from a type 
> method on a singular pointer, but not from a buffer pointer. The result of 
> such an operation returns a singular pointer, even though a buffer pointer 
> would be more appropriate to capture the information about the number of 
> instances allocated. It’s possible to subscript into a singular pointer, even 
> though they are not real Collections. Some parts of the current design turn 
> UnsafePointers into downright DangerousPointers, leading users to believe 
> that they have allocated or freed memory when in fact, they have not.
> 
> This proposal seeks to iron out these inconsistencies, and offer a more 
> convenient, more sensible, and less bug-prone API for Swift pointers.
> 
>  >
> 
> ~~~
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Improved Swift pointers

2017-07-12 Thread Harlan Haskins via swift-evolution
I agree with most of this proposal. Removing the subscript bugs me, but pointer 
arithmetic currently takes the stride of the type into account, so I don’t 
necessarily have a problem with that.

I would really appreciate Unsafe*BufferPointer.allocate(count:), and I 
definitely think the sized deallocators are actively dangerous unless the 
arguments are used. I fully support their removal.

> On Jul 12, 2017, at 12:16 PM, Taylor Swift via swift-evolution 
>  wrote:
> 
> Hi all, I’ve written up a proposal to modify the unsafe pointer API for 
> greater consistency, safety, and ease of use.
> 
> ~~~
> 
> Swift currently offers two sets of pointer types — singular pointers such as 
> UnsafeMutablePointer, and vector (buffer) pointers such as 
> UnsafeMutableBufferPointer. This implies a natural separation of tasks the 
> two kinds of pointers are meant to do. For example, buffer pointers implement 
> Collection conformance, while singular pointers do not.
> 
> However, some aspects of the pointer design contradict these implied roles. 
> It is possible to allocate an arbitrary number of instances from a type 
> method on a singular pointer, but not from a buffer pointer. The result of 
> such an operation returns a singular pointer, even though a buffer pointer 
> would be more appropriate to capture the information about the number of 
> instances allocated. It’s possible to subscript into a singular pointer, even 
> though they are not real Collections. Some parts of the current design turn 
> UnsafePointers into downright DangerousPointers, leading users to believe 
> that they have allocated or freed memory when in fact, they have not.
> 
> This proposal seeks to iron out these inconsistencies, and offer a more 
> convenient, more sensible, and less bug-prone API for Swift pointers.
> 
>  >
> 
> ~~~
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution