Re: [swift-evolution] Shouldn't ".withUnsafeBufferPointer" and ".withUnsafeMutableBufferPointer" be parts of protocols?

2017-01-28 Thread Brent Royal-Gordon via swift-evolution
> On Jan 28, 2017, at 11:48 AM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> The way to handle Deque is to add this requirement to Collection when
> we get the language features to express it:
> 
>  protocol Collection {
> 
>associatedtype Segments : Collection 
>where Segments.Element : Collection,
>  Segments.Element.Element == Element
> = EmptyCollection>
> 
>var segments: Segments? {get}
>...
>  }
> 
>  extension Collection 
>  where Segments == EmptyCollection> {
>var segments: Segments? { return nil }
>  }

Couldn't that be be expressed more accurately with `Never` if it were a 
subtype-of-all-types?

 protocol Collection {

   associatedtype Segments : Collection 
   where Segments.Element : Collection,
 Segments.Element.Element == Element
= Never

   var segments: Segments? {get}
   ...
 }

 extension Collection 
 where Segments == Never {
   var segments: Segments? { return nil }
 }

Or you could say that there is always at least *one* segment:

 protocol Collection {

   associatedtype Segments : Collection 
   where Segments.Element : Collection,
 Segments.Element.Element == Element
= CollectionOfOne

   var segments: Segments {get}
   ...
 }

 extension Collection 
 where Segments == CollectionOfOne {
   var segments: Segments { return CollectionOfOne(self) }
 }

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] A case for postponing ABI stability

2017-01-28 Thread Russ Bishop via swift-evolution

> On Jan 27, 2017, at 2:08 PM, Freak Show via swift-evolution 
>  wrote:
> 
> Maybe so - but IB M
> solved this very problem along with release to release binary compatibility 
> for C++ and a number of other languages twenty years ago with the System 
> Object Model (SOM).

Yeah and Microsoft’s COM is a reasonable approach (and Apple ships a version of 
it used for plugin loading).

Unfortunately you end up with IFrob, IFrob2, IFrob3, IFrob4, IFrobEx, IFrobEx2. 
You also introduce a hard boundary that makes passing “native” types across the 
boundary impossible. Everything must fit inside the set of types described by 
COM. For Swift any scheme boils down to “use a lowest-common-denominator and 
give up all of Swift’s advanced type system features”.

Believe me, there are parts of the Simulator stack where I would like to use 
Swift but without ABI stability it just isn’t possible. If there were a 
plausible alternative I’d happily take it. There isn’t.

Russ

> 
> I'm not arguing for its adoption per se - but good ideas are always worth 
> stealing and there was some solid engineering in there.
> 
> Sent from the road
> 
>> On Jan 27, 2017, at 09:19, Tino Heth via swift-evolution 
>>  wrote:
>> 
>> I wouldn't expect that I can mix language and framework versions freely.
> ___
> 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] @NSCopying currently does not affect initializers

2017-01-28 Thread Rod Brown via swift-evolution
I agree that there is an issue here.

While I understand that the initialiser avoids the full setter for direct 
access, I would expect the attribute to mean that the substituted direct access 
still applied the attribute you marked the API with. I would consider the fact 
that it doesn't work as a dangerous gap in the API.

It is also concerning if we consider how this will work with Property 
Behaviours that are planned for Swift in the future. If we made NSCopying a 
property behaviour, the direct access would mean it too would not be invoked at 
initial access so I'm not sure how the best way to get around this is - should 
we do compiler magic to copy in the initialiser, or should we warn if we don't 
detect a call to copy() or copy(with:) in the initialiser?

I think we at least need to do something here. It's a very convoluted piece of 
logic to say the @NSCopying attribute doesn't work in an initialiser and it's 
hardly intuitive despite the fair reasoning.

Rod

> On 29 Jan 2017, at 4:47 pm, Torin Kwok via swift-evolution 
>  wrote:
> 
> Yep, I also admit the design of forbidding calling a setter before full
> class initialization is reasonable and what's really annoying is the
> inconsistency.
> 
> However, making @NSCopying attribute not subjects to the fact that
> setters would not be invoked in initializers perhaps is viable too. In
> the other words, assigning a value to a property whether or not by
> calling a setter has no influence on whether @NSCopying semantic'd work:
> copying should always take place after a property has been declared as
> @NSCopying.
> 
> Jean-Daniel writes:
> 
>>> Le 28 janv. 2017 à 05:34, Torin Kwok via swift-evolution 
>>>  a écrit :
>>> 
>>> Hello guys,
>>> 
>>> Note: This issue has been originally presented inswift-usersmailling list 
>>> .
>>>  And then I post it again here at the suggestion 
>>> 
>>>  of Jordan Rose:
>>> 
>>> It might be reasonable to change this behavior, but it probably deserves a 
>>> bit of discussion on swift-evolution; it's not 100%, for-sure a bug.
>>> --- the original content follows this line ---
>>> 
>>> I encountered a strange behavior when I declared a property with the 
>>> @NSCopying attribute:
>>> 
>>> // `Person` class inherits from `NSObject` class and conforms to 
>>> `NSCopying` protocol
>>> @NSCopying var employee: Person
>>> and then assigned an external instance of Person class protocol to this 
>>> property within the designated init methods:
>>> 
>>> // Designated initializer of `Department` class
>>> init( employee externalEmployee: Person ) {
>>> self.employee = externalEmployee
>>> super.init()
>>> 
>>> // Assertion would fail since Swift do not actually copy the value assigned 
>>> to this property 
>>> // even though `self.employee` has been marked as `@NSCoyping`
>>> // assert( self.employee !== externalEmployee )
>>> }
>>> If I indeed require the deep copying behavior during the init process, 
>>> instead of taking advantage of @NSCopying attribute, I would have to invoke 
>>> the copy() method manually:
>>> 
>>> init( employee externalEmployee: Person ) {
>>> // ...
>>> self.employee = externalEmployee.copy() as! Person  
>>> // ...
>>> }
>>> In fact, what really makes me confusing is that @NSCopying semantic does 
>>> work properly within the other parts of the class definition such as normal 
>>> instance methods, or external scope. For instance, if we're assigning an 
>>> external instance of Person to the self.employee proper of Department 
>>> directly through setter rather than initializer:
>>> 
>>> department.employee = johnAppleseed
>>> then self.employee property and johnAppleseed variable will no longer share 
>>> the same underlying object now. In the other words, @NSCopying attribute 
>>> makes sense.
>>> 
>>> After I looked through a great deal of results given by Google, and 
>>> dicussions on StackOverflow, I finally end up with nothing helpful — the 
>>> vast majority of articles, documentations as well as issues talking about 
>>> this similar topics only focus on the basic concepts and effects of 
>>> @NSCopying itself but do not mentioned this strange behavior at all — 
>>> besides one radar descriping the same problem (rdar://21383959 
>>> ) and a final conclusion mentioned in a guy's Gist 
>>> comment: ... values set during initialization are not cloned ...
>>> 
>>> That is, @NSCopying semantic has no effect in initializers.
>>> 
>>> Then, what I want to figure out is the reason why @NSCopying semantic will 
>>> become effectless implicitly whithin initializers of a class, and the 
>>> special considerations behind this behavior, if any.
>>> 
>>> --- END ---
>>> 
>>> Jordan:
>>> 
>>> Your observation is correct: @NSCopying currently does not affect 
>>> initializers. This is because accessing a property in an initializer always

Re: [swift-evolution] @NSCopying currently does not affect initializers

2017-01-28 Thread Torin Kwok via swift-evolution
Yep, I also admit the design of forbidding calling a setter before full
class initialization is reasonable and what's really annoying is the
inconsistency.

However, making @NSCopying attribute not subjects to the fact that
setters would not be invoked in initializers perhaps is viable too. In
the other words, assigning a value to a property whether or not by
calling a setter has no influence on whether @NSCopying semantic'd work:
copying should always take place after a property has been declared as
@NSCopying.

Jean-Daniel writes:

>> Le 28 janv. 2017 à 05:34, Torin Kwok via swift-evolution 
>>  a écrit :
>> 
>> Hello guys,
>> 
>> Note: This issue has been originally presented inswift-usersmailling list 
>> .
>>  And then I post it again here at the suggestion 
>> 
>>  of Jordan Rose:
>> 
>> It might be reasonable to change this behavior, but it probably deserves a 
>> bit of discussion on swift-evolution; it's not 100%, for-sure a bug.
>> --- the original content follows this line ---
>> 
>> I encountered a strange behavior when I declared a property with the 
>> @NSCopying attribute:
>> 
>> // `Person` class inherits from `NSObject` class and conforms to `NSCopying` 
>> protocol
>> @NSCopying var employee: Person
>> and then assigned an external instance of Person class protocol to this 
>> property within the designated init methods:
>> 
>> // Designated initializer of `Department` class
>> init( employee externalEmployee: Person ) {
>>  self.employee = externalEmployee
>>  super.init()
>> 
>>  // Assertion would fail since Swift do not actually copy the value assigned 
>> to this property 
>>  // even though `self.employee` has been marked as `@NSCoyping`
>>  // assert( self.employee !== externalEmployee )
>>  }
>> If I indeed require the deep copying behavior during the init process, 
>> instead of taking advantage of @NSCopying attribute, I would have to invoke 
>> the copy() method manually:
>> 
>> init( employee externalEmployee: Person ) {
>>  // ...
>>  self.employee = externalEmployee.copy() as! Person  
>>  // ...
>>  }
>> In fact, what really makes me confusing is that @NSCopying semantic does 
>> work properly within the other parts of the class definition such as normal 
>> instance methods, or external scope. For instance, if we're assigning an 
>> external instance of Person to the self.employee proper of Department 
>> directly through setter rather than initializer:
>> 
>> department.employee = johnAppleseed
>> then self.employee property and johnAppleseed variable will no longer share 
>> the same underlying object now. In the other words, @NSCopying attribute 
>> makes sense.
>> 
>> After I looked through a great deal of results given by Google, and 
>> dicussions on StackOverflow, I finally end up with nothing helpful — the 
>> vast majority of articles, documentations as well as issues talking about 
>> this similar topics only focus on the basic concepts and effects of 
>> @NSCopying itself but do not mentioned this strange behavior at all — 
>> besides one radar descriping the same problem (rdar://21383959 
>> ) and a final conclusion mentioned in a guy's Gist comment: 
>> ... values set during initialization are not cloned ...
>> 
>> That is, @NSCopying semantic has no effect in initializers.
>> 
>> Then, what I want to figure out is the reason why @NSCopying semantic will 
>> become effectless implicitly whithin initializers of a class, and the 
>> special considerations behind this behavior, if any.
>> 
>> --- END ---
>> 
>> Jordan:
>> 
>> Your observation is correct: @NSCopying currently does not affect 
>> initializers. This is because accessing a property in an initializer always 
>> does direct access to the storage rather than going through the setter.
>> I have tested the identical logic in Objective-C and the NSCopying semantic 
>> works perfectly within Obj-C's class initializer.
>> 
> This is because Obj-C guarantee that all ivars are zero initialized and does 
> not enforce initializer safety (but forcing initialization of ivars before 
> calling other methods).
>
> Calling a setter (like any other method) before full class initialization is 
> unsafe as the setter may be overridden or simply customized, and may need to 
> access to the class or subclasses ivars.
>
> That said, I’m not sure what is the best way to solve that inconsistency.


-- 
Torin Kwok (郭桐)
OpenPGP/GnuPG: https://keybase.io/kwok
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Checking in; more thoughts on arrays and variadic generics

2017-01-28 Thread Slava Pestov via swift-evolution

> On Jan 27, 2017, at 4:55 PM, Karl Wagner  wrote:
> 
> 
>> On 27 Jan 2017, at 22:25, Slava Pestov > > wrote:
>> 
>> 
>>> On Jan 27, 2017, at 11:44 AM, Karl Wagner via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> So, 2 quick points:
>>> 
>>> 1) I have often wanted a shorthand for expressing long tuples; I definitely 
>>> think that’s something worth bike-shedding, e.g. - (String * 4, Int32 * 4) 
>>> or something
>> 
>> Why not define a struct, or a tuple consisting of two arrays?
> 
> Because I want a fixed-length guarantee; ([String], [Int]) could have any 
> number of Strings or Ints.

Ok, maybe a struct would named fields would be better though.

> It’s just a shorthand for defining long or complex tuples; we currently 
> import C arrays as massive tuples which can be basically impossible to read.

I agree that this is a problem — fixed length arrays should be imported better, 
once we have the right language features.

> 
>> 
>>> 2) Having a special non-growing array type which is called “array” and 
>>> separate from Array is not such a good idea IMO. I would rather allow 
>>> tuples to conform to protocols (see: 
>>> https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#extensions-of-structural-types
>>>  
>>> ).
>>> 
>>> If tuples could conform to protocols, we could say “any tuple of homogenous 
>>> elements is a Collection”. There would be benefits for the standard 
>>> library, too - EmptyCollection would disappear, replaced with the empty 
>>> tuple (),
>> 
>> This sounds too clever.
> 
> Yeah… the cleverness is one of things I like about it. We get to remove these 
> canned conformances and reduce the stdlib surface area while gaining an 
> efficient way to express a fixed-size Collection. It would come with all 
> kinds of supplementary benefits, such as iterating and mapping the elements 
> of a tuple.
> 
>> 
>>> as would CollectionOfOne, to be replaced by a single-element tuple (T).
>> 
>> For what it’s worth, Swift doesn’t have single-element tuples. (T) is just 
>> sugar for the type T itself.
> 
> Would it be unreasonable to separate those, so that (T) is separate from T 
> instead of being a synonym for it? There is some awkwardness with tuples due 
> to legacy designs. Perhaps this would help clean it up a little (or perhaps 
> make it worse, who knows?)
> 
> For source compatibility, we could allow an implicit conversion; in the same 
> way that a T can be implicitly “promoted" to an Optional, it could be 
> implicitly “promoted” to a single-element tuple of T (and vice-versa).

Sure, we *could* re-design tuple types in a way where single element tuples 
make sense. Then we’d have to come up with a source compatibility story for 
Swift 3 vs Swift 4, fix any fallout (compiler crashes) from this change, 
implement migrator support when the stdlib is changed to use the new features, 
etc. But think of it this way — every such “unnecessary” change (and I realize 
this is subjective!) is taking away cycles the team could use to fix crashes, 
improve compiler speed, and improve diagnostics. Not to mention implementing 
the other evolution proposals which arguably increase expressive power in 
important ways we feel we need for ABI stability, such as generic subscripts.

> 
>> 
>>> We would also be able to remove our limited-arity == overloads in favour of 
>>> actual, honest-to-goodness Equatable conformance.
>> 
>> I like this idea though.
>> 
>>> 
>>> - Karl
>>>  
>>> ___
>>> 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] Shouldn't ".withUnsafeBufferPointer" and ".withUnsafeMutableBufferPointer" be parts of protocols?

2017-01-28 Thread Dave Abrahams via swift-evolution

on Fri Jan 27 2017, Zach Waldowski  wrote:

> I like the sound of it so far, but my first major thought is that isn't
> it modeling a "has-a" relationship instead of an "is-a"? The buffer
> methods indicate that the data type *can* be represented as a buffer for
> the duration of the method call, but may not necessarily be before or
> after. Such a semantic distinction would also allow Data and
> DispatchData, as well as other theoretical data structures like a Deque
> (I think?) to participate.

The way to handle Deque is to add this requirement to Collection when
we get the language features to express it:

  protocol Collection {

associatedtype Segments : Collection 
where Segments.Element : Collection,
  Segments.Element.Element == Element
 = EmptyCollection>

var segments: Segments? {get}
...
  }

  extension Collection 
  where Segments == EmptyCollection> {
var segments: Segments? { return nil }
  }

Data structures like Deque would vend a non-nil `var segments`, and
algorithms that can benefit from segmentation would be rewritten to take
advantage of it.  The contiguous storage referenced by a Deque's
segments would be available by virtue of their conformance to
ContiguouslyStored.

>
> Cheers!
>
>   Zachary Waldowski
>
>   z...@waldowski.me
>
> On Fri, Jan 27, 2017, at 06:40 PM, Daryle Walker via swift-evolution wrote:
>> I was perusing the library for array ideas, and noticed that several
>> types had methods in common, but without a grouping protocol.
>> Shouldn’t that be fixed?
>> 
>
>> (Oh, if multiple protocols have an associated-type with the same name,
>> is that a problem? Is it a problem if they resolve differently for
>> each protocol attached to a given type? I’m asking because these
>> protocols reuse Sequence’s Element for their own purpose.)
>> 
>
>> 
>
>> Formal Protocol for Contiguous Storage Visitation
>
>>  * Proposal: SE-
>>  * Authors: Daryle Walker[1]
>>  * Review Manager: TBD
>>  * Status: *Awaiting review*
>> *During the review process, add the following fields as needed:*
>
>>  * Decision Notes: Rationale[2], Additional Commentary[3]
>>  * Bugs: SR-[4], SR-[5]
>>  * Previous Revision: 1[6]
>>  * Previous Proposal: SE-
>> Introduction
>
>> The standard library types Array, ArraySlice, and ContiguousArray have
>> an interface for visiting their elements as a contiguous block of
>> memory (arranging said elements to that configuration first if
>> necessary). These methods are all the same, but not under a common
>> protocol (i.e. seeming to match by "coincidence").
>> This proposal seeks to correct that with two new protocols that these
>> types will implement.
>> Swift-evolution thread: Discussion thread topic for that proposal[7]
>> Motivation
>
>> Just adding these protocols for consistency is relatively minor, but
>> they may be used for other types. Particularly, they would be needed
>> if fixed-sized arrays are added to the language.
>> Proposed solution
>
>> The library array types will follow the
>> MutableContiguousBlockprotocol, which inherits from the
>> ContiguousBlock protocol.
>> extension Array: MutableContiguousBlock { }  extension ArraySlice:
>> MutableContiguousBlock { }  extension ContiguousArray:
>> MutableContiguousBlock { }
>> For example, a repackaging of the library's example code:
>
>> func change(object: inout T) -> T.Element
>> where T.Element: Integer { let sum = object.withUnsafeBufferPointer {
>> (buffer) -> T.Element in var result: T.Element = 0 for i in
>> stride(from: buffer.startIndex, to: buffer.endIndex, by: 2) { result
>> += buffer[i] } return result } object.withUnsafeMutableBufferPointer {
>> buffer in for j in stride(from: buffer.startIndex, to: buffer.endIndex
>> - 1, by: 2) { swap(&buffer[j], &buffer[j + 1]) } } return sum }  var
>> numbers = [1, 2, 3, 4, 5] print(change(object: &numbers))  // 9
>> print(numbers)   // [2, 1, 4, 3, 5]
>> Detailed design
>
>> /** Visitation protocol of the receiver's contiguous storage of
>> immutable elements. */ protocol ContiguousBlock {  /// Inferred alias
>> to the element type to visit associatedtype Element  /** Calls a
>> closure with a pointer to the receiver's contiguous storage. If no
>> such storage exists, it is first created.  Often, the optimizer can
>> eliminate bounds checks within an array algorithm, but when that
>> fails, invoking the same algorithm on the buffer pointer passed into
>> your closure lets you trade safety for speed.  The following example
>> shows how you can iterate over the contents of the buffer pointer:
>> let numbers = [1, 2, 3, 4, 5] let sum =
>> numbers.withUnsafeBufferPointer { buffer -> Int in var result = 0 for
>> i in stride(from: buffer.startIndex, to: buffer.endIndex, by: 2) {
>> result += buffer[i] } return result } // 'sum' == 9  - Parameter body:
>> A closure with an `UnsafeBufferPointer` parameter that points to the
>> contiguous storage for the receiver. If `body` has a return value, it

Re: [swift-evolution] @NSCopying currently does not affect initializers

2017-01-28 Thread Jean-Daniel via swift-evolution

> Le 28 janv. 2017 à 05:34, Torin Kwok via swift-evolution 
>  a écrit :
> 
> Hello guys,
> 
> Note: This issue has been originally presented in swift-users mailling list 
> .
>  And then I post it again here at the suggestion 
> 
>  of Jordan Rose:
> 
> It might be reasonable to change this behavior, but it probably deserves a 
> bit of discussion on swift-evolution; it's not 100%, for-sure a bug.
> --- the original content follows this line ---
> 
> I encountered a strange behavior when I declared a property with the 
> @NSCopying attribute:
> 
> // `Person` class inherits from `NSObject` class and conforms to `NSCopying` 
> protocol
> @NSCopying var employee: Person
> and then assigned an external instance of Person class protocol to this 
> property within the designated init methods:
> 
> // Designated initializer of `Department` class
> init( employee externalEmployee: Person ) {
>  self.employee = externalEmployee
>  super.init()
> 
>  // Assertion would fail since Swift do not actually copy the value assigned 
> to this property 
>  // even though `self.employee` has been marked as `@NSCoyping`
>  // assert( self.employee !== externalEmployee )
>  }
> If I indeed require the deep copying behavior during the init process, 
> instead of taking advantage of @NSCopying attribute, I would have to invoke 
> the copy() method manually:
> 
> init( employee externalEmployee: Person ) {
>  // ...
>  self.employee = externalEmployee.copy() as! Person  
>  // ...
>  }
> In fact, what really makes me confusing is that @NSCopying semantic does work 
> properly within the other parts of the class definition such as normal 
> instance methods, or external scope. For instance, if we're assigning an 
> external instance of Person to the self.employee proper of Department 
> directly through setter rather than initializer:
> 
> department.employee = johnAppleseed
> then self.employee property and johnAppleseed variable will no longer share 
> the same underlying object now. In the other words, @NSCopying attribute 
> makes sense.
> 
> After I looked through a great deal of results given by Google, and 
> dicussions on StackOverflow, I finally end up with nothing helpful — the vast 
> majority of articles, documentations as well as issues talking about this 
> similar topics only focus on the basic concepts and effects of @NSCopying 
> itself but do not mentioned this strange behavior at all — besides one radar 
> descriping the same problem (rdar://21383959 ) and a final 
> conclusion mentioned in a guy's Gist comment: ... values set during 
> initialization are not cloned ...
> 
> That is, @NSCopying semantic has no effect in initializers.
> 
> Then, what I want to figure out is the reason why @NSCopying semantic will 
> become effectless implicitly whithin initializers of a class, and the special 
> considerations behind this behavior, if any.
> 
> --- END ---
> 
> Jordan:
> 
> Your observation is correct: @NSCopying currently does not affect 
> initializers. This is because accessing a property in an initializer always 
> does direct access to the storage rather than going through the setter.
> I have tested the identical logic in Objective-C and the NSCopying semantic 
> works perfectly within Obj-C's class initializer.
> 
This is because Obj-C guarantee that all ivars are zero initialized and does 
not enforce initializer safety (but forcing initialization of ivars before 
calling other methods).

Calling a setter (like any other method) before full class initialization is 
unsafe as the setter may be overridden or simply customized, and may need to 
access to the class or subclasses ivars.

That said, I’m not sure what is the best way to solve that inconsistency.


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