Re: [swift-evolution] Mark protocol methods with their protocol

2016-09-21 Thread Karl via swift-evolution
I would like to make it a requirement if not inside a protocol extension which 
declares a conformance, and actually build the protocol name in to the member 
in an ABI-breaking way. We could make it additive by generating forwarding 
thunks from the old symbols to the new ones, but it would be better if we could 
just solve the overlapping-members problem before then.

That would mean you never get collisions between protocol members. There’s 
loads of amazing stuff we can do with that ability, and ways we can extend it 
to reduce a lot of boilerplate that occurs when you want to have multiple 
representations of the same data (String is just an example).

I don’t really care about the syntax we need to make it liveable. We could 
automatically insert the protocol names for unambiguous members at call-site, 
or something else.

This thread was originally about making the *syntax* a requirement; I agree 
with that, and I would actually take it one (or several) steps further, solving 
other problems along the way.

> On 22 Sep 2016, at 06:46, Russ Bishop  wrote:
> 
> 
>> On Sep 20, 2016, at 4:34 PM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> 
>> on Tue Sep 20 2016, Karl  wrote:
>> 
>>> I think the best way is to prefix the member name with the protocol, e.g:
>>> 
>>> protocol MyProto {
>>>   var aVariable : Int
>>>   func aFunction()
>>> }
>>> class MyClass : MyProto {
>>>   var MyProto.aVariable : Int
>>>   func MyProto.aFunction() { … }
>>> }
>> ...
>>> CC-ing Dave A, to understand better if this fits with the vision of 
>>> protocols
>> 
>> I generally agree with Doug.  The canonical way to indicate “this
>> method/property/type implements a requirement of protocol P” should be
>> to define the entity in an extension that also adds conformance to P.
>> If that's inadequate indication in some way we should find a way to
>> enhance it.  I wouldn't mind the notation above, but only as a fallback,
>> not a reuquirement.
>> 
>> -- 
>> -Dave
>> ___
> 
> Indeed this is exactly how C# handles Interfaces (protocols). The default is 
> the exact same way Swift works - by matching names. If there is a collision 
> you specify Protocol.memberName. Its simple and in the years I was writing C# 
> code it was flexible enough to cover most reasonable scenarios, without 
> adding a bunch of boilerplate.
> 
> Russ
> 

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


Re: [swift-evolution] Mark protocol methods with their protocol

2016-09-21 Thread Russ Bishop via swift-evolution

> On Sep 20, 2016, at 4:34 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Tue Sep 20 2016, Karl  wrote:
> 
>> I think the best way is to prefix the member name with the protocol, e.g:
>> 
>> protocol MyProto {
>>var aVariable : Int
>>func aFunction()
>> }
>> class MyClass : MyProto {
>>var MyProto.aVariable : Int
>>func MyProto.aFunction() { … }
>> }
> ...
>> CC-ing Dave A, to understand better if this fits with the vision of protocols
> 
> I generally agree with Doug.  The canonical way to indicate “this
> method/property/type implements a requirement of protocol P” should be
> to define the entity in an extension that also adds conformance to P.
> If that's inadequate indication in some way we should find a way to
> enhance it.  I wouldn't mind the notation above, but only as a fallback,
> not a reuquirement.
> 
> -- 
> -Dave
> ___

Indeed this is exactly how C# handles Interfaces (protocols). The default is 
the exact same way Swift works - by matching names. If there is a collision you 
specify Protocol.memberName. Its simple and in the years I was writing C# code 
it was flexible enough to cover most reasonable scenarios, without adding a 
bunch of boilerplate.

Russ

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


Re: [swift-evolution] Should Swift apply "statement scope" for ARC

2016-09-21 Thread Joe Groff via swift-evolution

> On Sep 21, 2016, at 4:01 PM, John Holdsworth  wrote:
> 
> My contrived example was a bit flimsy. I’d better unpack the full story. The 
> real
> code I had problems with was based around the following Java instance wrapper:
> 
> open class JNIObject: JNIObjectProtocol {
> 
> var _javaObject: jobject?
> 
> open var javaObject: jobject? {
> get {
> return _javaObject
> }
> set(newValue) {
> if newValue != _javaObject {
> let oldValue = _javaObject
> if newValue != nil {
> _javaObject = JNI.api.NewGlobalRef( JNI.env, newValue )
> }
> else {
> _javaObject = nil
> }
> if oldValue != nil {
> JNI.api.DeleteGlobalRef( JNI.env, oldValue )
> }
> }
> }
> }
> 
> deinit {
> javaObject = nil
> }
> 
> As a result the following transfer of a Java instance always worked:
> 
> init(imageProducer:ImageProducer) {
> let supr = CanvasBase()
> super.init( javaObject: supr.javaObject )
> image = createImage(imageProducer)
> }
> 
> But the following only worked for debug compiles:
> 
> init(imageProducer:ImageProducer) {
> super.init( javaObject: CanvasBase().javaObject )
> image = createImage(imageProducer)
> }
> 
> Felt like a bit of a bear trap is all. Statement scope would avoid problems 
> like this.

True, though statement scope is also a pretty massive barrier that would 
prevent important optimizations that are valid for most classes. You might be 
able to avoid the bear trap by changing the `javaObject` interface into a 
callback-based interface, that ensures the object remains alive while you have 
access to it. Instead of:

protocol JNIObjectProtocol {
  var javaObject: jobject { get }
}

would it work to have something like this?

protocol JNIObjectProtocol {
  func withJavaObject(_ body: (jobject) -> ())
}

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


Re: [swift-evolution] Should Swift apply "statement scope" for ARC

2016-09-21 Thread John Holdsworth via swift-evolution
My contrived example was a bit flimsy. I’d better unpack the full story. The 
real
code I had problems with was based around the following Java instance wrapper:

open class JNIObject: JNIObjectProtocol {

var _javaObject: jobject?

open var javaObject: jobject? {
get {
return _javaObject
}
set(newValue) {
if newValue != _javaObject {
let oldValue = _javaObject
if newValue != nil {
_javaObject = JNI.api.NewGlobalRef( JNI.env, newValue )
}
else {
_javaObject = nil
}
if oldValue != nil {
JNI.api.DeleteGlobalRef( JNI.env, oldValue )
}
}
}
}

deinit {
javaObject = nil
}

As a result the following transfer of a Java instance always worked:

init(imageProducer:ImageProducer) {
let supr = CanvasBase()
super.init( javaObject: supr.javaObject )
image = createImage(imageProducer)
}

But the following only worked for debug compiles:

init(imageProducer:ImageProducer) {
super.init( javaObject: CanvasBase().javaObject )
image = createImage(imageProducer)
}

Felt like a bit of a bear trap is all. Statement scope would avoid problems 
like this.

John


> On 21 Sep 2016, at 23:34, Joe Groff  wrote:
> 
> 
>> On Sep 21, 2016, at 3:14 PM, Xiaodi Wu via swift-evolution 
>>  wrote:
>> 
>> I haven't used it myself, but is this the use case addressed by 
>> `withExtendedLifetime(_:_:)`?
> 
> Yeah, if you want to vend resources managed by an object to consumers outside 
> of that object like this, you need to use withExtendedLifetime to keep the 
> object alive for as long as you're using the resources. A cleaner way to 
> model this might be to put the class or protocol in control of handling the 
> I/O to the file handle, instead of vending the file handle itself, so that 
> the ownership semantics fall out more naturally:
> 
> protocol Storage {
>  func write(bytes: UnsafeRawPointer, count: Int)
> }
> 
> func save(string: String, to: Storage?) {
>if let data = string.data(using: String.Encoding.utf8) {
>data.withUnsafeBytes {
>_ = to?.write(bytes: $0, count: data.count)
>}
>}
> }
> 
> -Joe
> 
>> On Wed, Sep 21, 2016 at 16:54 John Holdsworth via swift-evolution 
>>  wrote:
>> Hi,
>> 
>> For complex statements in C++ any temporary instances created in the course
>> of an expression have their lifetime extended to the completion of the 
>> current
>> statement after which they are all deallocated en masse. This makes certain
>> types of language usage possible and easier to reason with.
>> 
>> I’m bringing this up as I had a problem with some code crashing only when
>> compiled with release configuration and the problem could have been avoided
>> if Swift deferred deallocation to the end of a statement. While Swift’s ARC 
>> policy
>> is consistent in itself this seems to be a particular problem interfacing 
>> between
>> language/reference counting systems. My problem code was a Java-Swift Bridge.
>> 
>> A contrived example:
>> 
>> import Foundation
>> 
>> protocol Storage {
>>var fp: UnsafeMutablePointer { get }
>> }
>> 
>> class FileStorage: Storage {
>> 
>>let fp: UnsafeMutablePointer
>> 
>>init?(path: String, mode: String = "w") {
>>print("Opening")
>>let fp = fopen(path, mode)
>>if fp == nil {
>>return nil
>>}
>>self.fp = fp!
>>}
>> 
>>deinit {
>>print("Closing")
>>fclose(fp)
>>}
>> }
>> 
>> func save(string: String, to: Storage?) {
>>if let data = string.data(using: String.Encoding.utf8) {
>>print("Saving1")
>>if let fp = to?.fp {
>>print("Saving2")
>>data.withUnsafeBytes {
>>_ = fwrite($0, 1, data.count, fp)
>>}
>>print("Saving3")
>>}
>>}
>> }
>> 
>> save(string: "Hello World\n", to: FileStorage(path: "/tmp/a.txt"))
>> 
>> 
>> In debug configuration is prints:
>> Opening
>> Saving1
>> Saving2
>> Saving3
>> Closing
>> 
>> Whereas in release configuration it prints:
>> Opening
>> Saving1
>> Closing > Saving2
>> Saving3
>> 
>> The optimiser is vigorously deallocating objects when they are no longer 
>> referenced regardless
>> of whether an variable referencing it is still in scope (In fairness this 
>> particular problem only occurs
>> for Optional augments of Protocols) but this behaviour seems to be implicit 
>> in the current language
>> spec. The alternative is to retain arguments themselves as I believe they 
>> are in Objective-C ARC.
>> 
>> This would have been avoided if the temporary FileStorage instance has been 
>> considered to have
>> a lifetime up to the end of the statement calling function save() 

Re: [swift-evolution] Should Swift apply "statement scope" for ARC

2016-09-21 Thread Joe Groff via swift-evolution

> On Sep 21, 2016, at 3:14 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> I haven't used it myself, but is this the use case addressed by 
> `withExtendedLifetime(_:_:)`?

Yeah, if you want to vend resources managed by an object to consumers outside 
of that object like this, you need to use withExtendedLifetime to keep the 
object alive for as long as you're using the resources. A cleaner way to model 
this might be to put the class or protocol in control of handling the I/O to 
the file handle, instead of vending the file handle itself, so that the 
ownership semantics fall out more naturally:

protocol Storage {
  func write(bytes: UnsafeRawPointer, count: Int)
}

func save(string: String, to: Storage?) {
if let data = string.data(using: String.Encoding.utf8) {
data.withUnsafeBytes {
_ = to?.write(bytes: $0, count: data.count)
}
}
}

-Joe

> On Wed, Sep 21, 2016 at 16:54 John Holdsworth via swift-evolution 
>  wrote:
> Hi,
> 
> For complex statements in C++ any temporary instances created in the course
> of an expression have their lifetime extended to the completion of the current
> statement after which they are all deallocated en masse. This makes certain
> types of language usage possible and easier to reason with.
> 
> I’m bringing this up as I had a problem with some code crashing only when
> compiled with release configuration and the problem could have been avoided
> if Swift deferred deallocation to the end of a statement. While Swift’s ARC 
> policy
> is consistent in itself this seems to be a particular problem interfacing 
> between
> language/reference counting systems. My problem code was a Java-Swift Bridge.
> 
> A contrived example:
> 
> import Foundation
> 
> protocol Storage {
> var fp: UnsafeMutablePointer { get }
> }
> 
> class FileStorage: Storage {
> 
> let fp: UnsafeMutablePointer
> 
> init?(path: String, mode: String = "w") {
> print("Opening")
> let fp = fopen(path, mode)
> if fp == nil {
> return nil
> }
> self.fp = fp!
> }
> 
> deinit {
> print("Closing")
> fclose(fp)
> }
> }
> 
> func save(string: String, to: Storage?) {
> if let data = string.data(using: String.Encoding.utf8) {
> print("Saving1")
> if let fp = to?.fp {
> print("Saving2")
> data.withUnsafeBytes {
> _ = fwrite($0, 1, data.count, fp)
> }
> print("Saving3")
> }
> }
> }
> 
> save(string: "Hello World\n", to: FileStorage(path: "/tmp/a.txt"))
> 
> 
> In debug configuration is prints:
> Opening
> Saving1
> Saving2
> Saving3
> Closing
> 
> Whereas in release configuration it prints:
> Opening
> Saving1
> Closing  Saving2
> Saving3
> 
> The optimiser is vigorously deallocating objects when they are no longer 
> referenced regardless
> of whether an variable referencing it is still in scope (In fairness this 
> particular problem only occurs
> for Optional augments of Protocols) but this behaviour seems to be implicit 
> in the current language
> spec. The alternative is to retain arguments themselves as I believe they are 
> in Objective-C ARC.
> 
> This would have been avoided if the temporary FileStorage instance has been 
> considered to have
> a lifetime up to the end of the statement calling function save() and hence 
> the duration of the call.
> This needed increase ARC overhead in any way. Just alter the timing of it to 
> be more conservative.
> 
> John
> 
> ___
> 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] Should Swift apply "statement scope" for ARC

2016-09-21 Thread Xiaodi Wu via swift-evolution
I haven't used it myself, but is this the use case addressed by
`withExtendedLifetime(_:_:)`?

On Wed, Sep 21, 2016 at 16:54 John Holdsworth via swift-evolution <
swift-evolution@swift.org> wrote:

> Hi,
>
> For complex statements in C++ any temporary instances created in the course
> of an expression have their lifetime extended to the completion of the
> current
> statement after which they are all deallocated en masse. This makes certain
> types of language usage possible and easier to reason with.
>
> I’m bringing this up as I had a problem with some code crashing only when
> compiled with release configuration and the problem could have been avoided
> if Swift deferred deallocation to the end of a statement. While Swift’s
> ARC policy
> is consistent in itself this seems to be a particular problem interfacing
> between
> language/reference counting systems. My problem code was a Java-Swift
> Bridge.
>
> A contrived example:
>
> import Foundation
>
> protocol Storage {
> var fp: UnsafeMutablePointer { get }
> }
>
> class FileStorage: Storage {
>
> let fp: UnsafeMutablePointer
>
> init?(path: String, mode: String = "w") {
> print("Opening")
> let fp = fopen(path, mode)
> if fp == nil {
> return nil
> }
> self.fp = fp!
> }
>
> deinit {
> print("Closing")
> fclose(fp)
> }
> }
>
> func save(string: String, to: Storage?) {
> if let data = string.data(using: String.Encoding.utf8) {
> print("Saving1")
> if let fp = to?.fp {
> print("Saving2")
> data.withUnsafeBytes {
> _ = fwrite($0, 1, data.count, fp)
> }
> print("Saving3")
> }
> }
> }
>
> save(string: "Hello World\n", to: FileStorage(path: "/tmp/a.txt"))
>
>
> In debug configuration is prints:
> *Opening*
> *Saving1*
> *Saving2*
> *Saving3*
> *Closing*
>
> Whereas in release configuration it prints:
> *Opening*
> *Saving1*
> *Closing  *Saving2*
> *Saving3*
>
> The optimiser is vigorously deallocating objects when they are no longer
> referenced regardless
> of whether an variable referencing it is still in scope (In fairness this
> particular problem only occurs
> for Optional augments of Protocols) but this behaviour seems to be
> implicit in the current language
> spec. The alternative is to retain arguments themselves as I believe they
> are in Objective-C ARC.
>
> This would have been avoided if the temporary FileStorage instance has
> been considered to have
> a lifetime up to the end of the statement calling function save() and
> hence the duration of the call.
> This needed increase ARC overhead in any way. Just alter the timing of it
> to be more conservative.
>
> John
>
> ___
> 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] Should Swift apply "statement scope" for ARC

2016-09-21 Thread John Holdsworth via swift-evolution
Hi,

For complex statements in C++ any temporary instances created in the course
of an expression have their lifetime extended to the completion of the current
statement after which they are all deallocated en masse. This makes certain
types of language usage possible and easier to reason with.

I’m bringing this up as I had a problem with some code crashing only when
compiled with release configuration and the problem could have been avoided
if Swift deferred deallocation to the end of a statement. While Swift’s ARC 
policy
is consistent in itself this seems to be a particular problem interfacing 
between
language/reference counting systems. My problem code was a Java-Swift Bridge.

A contrived example:

import Foundation

protocol Storage {
var fp: UnsafeMutablePointer { get }
}

class FileStorage: Storage {

let fp: UnsafeMutablePointer

init?(path: String, mode: String = "w") {
print("Opening")
let fp = fopen(path, mode)
if fp == nil {
return nil
}
self.fp = fp!
}

deinit {
print("Closing")
fclose(fp)
}
}

func save(string: String, to: Storage?) {
if let data = string.data(using: String.Encoding.utf8) {
print("Saving1")
if let fp = to?.fp {
print("Saving2")
data.withUnsafeBytes {
_ = fwrite($0, 1, data.count, fp)
}
print("Saving3")
}
}
}

save(string: "Hello World\n", to: FileStorage(path: "/tmp/a.txt"))


In debug configuration is prints:
Opening
Saving1
Saving2
Saving3
Closing

Whereas in release configuration it prints:
Opening
Saving1
Closing ___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pre-Review] Permit where clauses to constrain associated types

2016-09-21 Thread T.J. Usiyan via swift-evolution
I… like this syntax but I have to admit that I am confused about
```protocol IntSequence : Sequence where Iterator.Element == Int {
...
}
```
I think that this example needs a better subtype/subprotocol to motivate
the feature. This particular type seems more like a constrained typealias
example to me. An example that I think might work is

```protocol FloatingPointSignal : Sequence where Iterator.Element == Double
{
var sampleRate: Double
...
}
```
because there is behavior/state to add in the subprotocol.



On Wed, Sep 21, 2016 at 2:50 PM, David Hart via swift-evolution <
swift-evolution@swift.org> wrote:

> Hello mailing list,
>
> Since the following proposal was discussed before the release of Swift 3
> and then delayed, I’m opening it up again for a short pre-review before to
> get some additional feedback before it can be merged.
>
> Web link: https://github.com/hartbit/swift-evolution/blob/
> 4107087d82eacc35538f5af0d97ffb80dfa4f998/proposals/-
> associated-types-constraints.md
>
> Permit where clauses to constrain associated types
>
>- Proposal: SE-
>
> 
>- Authors: David Hart , Jacob Bandes-Storch
>, Doug Gregor
>
>- Review Manager: TBD
>- Status: Awaiting review
>
>
> 
> Introduction
>
> This proposal seeks to introduce a where clause to associated type
> declarations and improvements to protocol constraints to bring associated
> types the same expressive power as generic type parameters.
>
> This proposal was discussed twice on the Swift Evolution list in the
> following threads:
>
>- [Completing Generics] Arbitrary requirements in protocols
>
> 
>- [Proposal] More Powerful Constraints for Associated Types
>   - Week #1
>   
> 
>   - Week #2
>   
> 
>   - Week #3
>   
> 
>
>
> 
> Motivation
>
> Currently, associated type declarations can only express simple
> inheritance constraints and not the more sophisticated constraints
> available to generic types with the where clause. Some designs, including
> many in the Standard Library, require more powerful constraints for
> associated types to be truly elegant. For example, the SequenceType protocol
> could be declared as follows if the current proposal was accepted:
>
> protocol Sequence {
> associatedtype Iterator : IteratorProtocol
> associatedtype SubSequence : Sequence where SubSequence.Iterator.Element 
> == Iterator.Element
> ...
> }
>
>
> Detailed
> Design
>
> First of all, this proposal modifies the grammar for a protocol's
> associated types to the following:
>
> *protocol-associated-type-declaration* → *attributesopt*
> *access-level-modifieropt* associatedtype *typealias-name* ­
> *type-inheritance-clause­opt* *typealias-assignment­opt*
> *requirement-clauseopt*
>
> The new requirement-clause is then used by the compiler to validate the
> associated types of conforming types.
>
> Secondly, the proposal also allows protocols to use the associated types
> of their conforming protocols in their declaration where clause as below:
>
> protocol IntSequence : Sequence where Iterator.Element == Int {
> ...
> }
>
> Name lookup semantics in the protocol declaration where clause only looks
> at associated types in the parent protocols. For example, the following
> code would cause an error:
>
> protocol SomeSequence : Sequence where Counter : SomeProtocol { // error: Use 
> of undefined associated type 'Counter'
> associatedtype Counter
> }
>
> But instead should be written on the associated type itself:
>
> protocol IntSequence : Sequence {
> associatedtype Counter : SomeProtocol
> }
>
>
> Effect
> on ABI Stability
>
> As mentioned previously, there are a number of places in the standard
> library where this feature would be adopted (such as the
> SubSequence.Iterator.Element == 

[swift-evolution] [Pre-Review] Permit where clauses to constrain associated types

2016-09-21 Thread David Hart via swift-evolution
Hello mailing list,

Since the following proposal was discussed before the release of Swift 3 and 
then delayed, I’m opening it up again for a short pre-review before to get some 
additional feedback before it can be merged.

Web link: 
https://github.com/hartbit/swift-evolution/blob/4107087d82eacc35538f5af0d97ffb80dfa4f998/proposals/-associated-types-constraints.md

Permit where clauses to constrain associated types

Proposal: SE- 

Authors: David Hart , Jacob Bandes-Storch 
, Doug Gregor 
Review Manager: TBD
Status: Awaiting review
 
Introduction

This proposal seeks to introduce a where clause to associated type declarations 
and improvements to protocol constraints to bring associated types the same 
expressive power as generic type parameters.

This proposal was discussed twice on the Swift Evolution list in the following 
threads:

[Completing Generics] Arbitrary requirements in protocols 

[Proposal] More Powerful Constraints for Associated Types
Week #1 

Week #2 

Week #3 

 
Motivation

Currently, associated type declarations can only express simple inheritance 
constraints and not the more sophisticated constraints available to generic 
types with the where clause. Some designs, including many in the Standard 
Library, require more powerful constraints for associated types to be truly 
elegant. For example, the SequenceType protocol could be declared as follows if 
the current proposal was accepted:

protocol Sequence {
associatedtype Iterator : IteratorProtocol
associatedtype SubSequence : Sequence where SubSequence.Iterator.Element == 
Iterator.Element
...
}
 
Detailed
 Design

First of all, this proposal modifies the grammar for a protocol's associated 
types to the following:

protocol-associated-type-declaration → attributesopt access-level-modifieropt 
associatedtype typealias-name ­type-inheritance-clause­opt 
typealias-assignment­opt requirement-clauseopt

The new requirement-clause is then used by the compiler to validate the 
associated types of conforming types.

Secondly, the proposal also allows protocols to use the associated types of 
their conforming protocols in their declaration where clause as below:

protocol IntSequence : Sequence where Iterator.Element == Int {
...
}
Name lookup semantics in the protocol declaration where clause only looks at 
associated types in the parent protocols. For example, the following code would 
cause an error:

protocol SomeSequence : Sequence where Counter : SomeProtocol { // error: Use 
of undefined associated type 'Counter'
associatedtype Counter
}
But instead should be written on the associated type itself:

protocol IntSequence : Sequence {
associatedtype Counter : SomeProtocol
}
 
Effect
 on ABI Stability

As mentioned previously, there are a number of places in the standard library 
where this feature would be adopted (such as the SubSequence.Iterator.Element 
== Iterator.Element example), each of which will change the mangling of any 
generic function/type that makes use of them.

 
Alternatives

Douglas Gregor argues that the proposed syntax is redundant when adding new 
constraints to an associated type declared in a parent protocol and proposes 
another syntax: 

protocol Collection : Sequence {
where SubSequence : Collection
}
But as Douglas notes himself, that syntax is ambiguous since we adopted the 
generic where clause at the end of declarations of the following proposal: 
SE-0081: Move where clause to end of declaration 
.
 For those reasons, it might be wiser not to introduce the shorthand syntax.

 

Re: [swift-evolution] Bls: Range that goes both ways

2016-09-21 Thread Jeremy Pereira via swift-evolution

> On 21 Sep 2016, at 11:44, Mr Bee via swift-evolution 
>  wrote:
> 
> 
> But after I thought about it again, I think half-opened range doesn't really 
> make any senses. The ..< operator (and my proposed ..> operator) should be 
> removed. Or we have to accept the consequences that we also need the other 
> accompanying operators. The … operator with optional `step` attribute that is 
> able to go both ways is more important that half-opened range operator. 
> 

This came up before on the list from whence I get the link

https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html

which justifies both why numbering starts at 0 and why the ..< operator is the 
most useful one. Th tl;dr version is that in a..< b you can find out how many 
integers are in the range with a - b and easily specify an empty range. With a 
… b you have to do a - b + 1 which is ugly and it is also problematic if you 
want to specify an empty range.

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


Re: [swift-evolution] Testing access level, final, and static

2016-09-21 Thread Dave Abrahams via swift-evolution

on Wed Sep 21 2016, Benjamin Spratling  wrote:

> Howdy,
> As I understand it, In Swift 3, a lack of encapsulation is testable,
> but specific keywords to protect a designed encapsulation can’t be
> introspected, and thus encapsulation is fragile, i.e. not protectable
> by unit tests.
>
> For instance, we can write unit-tests that determine if a member's
> access level is at least a given level.  (by writing a test which
> accesses it at that level.)  However, we cannot test that it is less
> than, or exactly at a specific level.  

You can certainly write tests that only succeed when compilation fails.
Another option would be to use SourceKit to get a programmatic
representation of the code and check that.

HTH,

-- 
-Dave

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


Re: [swift-evolution] Mark protocol methods with their protocol

2016-09-21 Thread Vladimir.S via swift-evolution

On 21.09.2016 2:34, Dave Abrahams via swift-evolution wrote:


on Tue Sep 20 2016, Karl  wrote:


I think the best way is to prefix the member name with the protocol, e.g:

protocol MyProto {
var aVariable : Int
func aFunction()
}
class MyClass : MyProto {
var MyProto.aVariable : Int
func MyProto.aFunction() { … }
}

...

CC-ing Dave A, to understand better if this fits with the vision of protocols


I generally agree with Doug.  The canonical way to indicate “this
method/property/type implements a requirement of protocol P” should be
to define the entity in an extension that also adds conformance to P.


Could you clarify, how do you see a solution in case extension can't have 
stored properties? So, if protocol has such requirement(i.e. we want to 
implement the protocol requirement as stored property) we can't move it to 
extension.

Do you expect we'll have stored props in extension in near future?

Also, what about protocol extensions? What do you suggest to mark default 
implementation method here to express intention and to separate default 
implementation (that depends on protocol definition and so, IMO compiler 
should help us if protocol definition changed) from just helper methods in 
protocol extension? Like here:


protocol A {
func foov()
}

protocol B : A {
}

extension A {
func foov() {}
}

extension B {
// I was expecting this is a default implementation of foov() for B
// but in reality this is a helper method
// who knows when this error will be detected
func foow() {}
}


If that's inadequate indication in some way we should find a way to
enhance it.  I wouldn't mind the notation above, but only as a fallback,
not a reuquirement.



Could you share your opinion (and probably some common opinion of the core 
team) regarding `implement`(or `override`) keyword requirement for 
methods/props in type declared exactly to implement protocol's requirements?


Don't you feel that if Swift will not *require* this, we'll have fragile 
code base as, even if *I* can use linter for this, 3rd party source code 
that will be in my project probably will not use the "safe" method of 
protocol conformance?

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


Re: [swift-evolution] [swift-users] [swift-user]Unexpected behavior of protocol extension.

2016-09-21 Thread Vladimir.S via swift-evolution

On 21.09.2016 9:30, Goffredo Marocchi via swift-evolution wrote:

If the reference to the instance of the class is cast to the protocol type,
I want other object to be aware of my API contract not the specific class
instance, then the protocol default method gets called and that is several
shades of not appropriate for me.


Could you provide some example? I was not able to reproduce such 
behavior(and was not expected to be able):
(Probably, you want to mention helper methods in protocol extension that 
was not defined *in protocol itself*, then yes. But AFAIK not for the 
*default implementation* of protocol requirement i.e. the method/prop that 
*is* declared in "main" protocol definition)


protocol A {
func foo()
}

extension A {
func foo() { print("A") }
}

class C : A {
func foo() { print("C") }
}


let a : A = C()
a.foo() // "C"


func f(a: A) {
a.foo()
}
f(a: a) // "C"


func g(a: T) where T : A {
a.foo()
}
g(a: C()) // "C"


func h(a: T) where T.Iterator.Element : A {
for e in a {
e.foo()
}
}
h(a: [C()]) // "C"


func i(a: T) where T.Iterator.Element == A {
for e in a {
e.foo()
}
}
i(a: [a]) // "C"

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


[swift-evolution] Testing access level, final, and static

2016-09-21 Thread Benjamin Spratling via swift-evolution
Howdy,
As I understand it, In Swift 3, a lack of encapsulation is testable, but 
specific keywords to protect a designed encapsulation can’t be introspected, 
and thus encapsulation is fragile, i.e. not protectable by unit tests.

For instance, we can write unit-tests that determine if a member's access level 
is at least a given level.  (by writing a test which accesses it at that 
level.)  However, we cannot test that it is less than, or exactly at a specific 
level.  A member of a large team could escalate an access level during 
development for a new feature, while the developer who wrote the original 
access level (and knows why it is not ok) is on vacation, then another 
developer unaware of the history could begin using it in an unexpected way, 
introducing bugs.  (I wish I invented this example.  Unfortunately, I witnessed 
it a few months after the fact.)  More interesting for Swift 4, a compiled 
module vendor could accidentally publish an API which could be used to violate 
encapsulation in an unexpected way in which the customer is not aware.  Let’s 
not pretend that hasn’t happened either.  Rumor sites thrive on it.

Similarly, I can test that a member is not “final", but I cannot write a test 
to ensure that it is “final”.

The same goes for “class” vs. “static”.  I can test that a class method is 
“class”, but I cannot compile a test that it is “static”, not “class”.

Finally, I can test that a property is a “var”, and has a setter, but I cannot 
compile a test that it is a “let”.

Being able to perform these tests seems as desirable to me as having these 
language features in the first place.  (I do, in principle, want a unit test 
for all the code I write, right?)  I’m certain that all of this information is 
available to the compiler, and that most of it is in the .swiftmodule and 
.swiftdoc files.  Perhaps the sil is the right data for such an analysis.  I 
simply want to raise the desire for such a feature as the team works on 
stabilizing the ABI.

I’m also curious what the community thinks whether testing these would work 
best by declaring explicit functions or references for each one in the test 
module, like AssertTrue(accessLevel(SomeClass.doSomething(_:)) == .private), or 
possibly in some kind of “DebugIntrospection” module not available "on device". 
 Another option is to add a “AssertCantCompile” method which would verify that 
there is at least one compiler failure in some section of conjectural code.  
That could test for anything we don’t think to enumerate. But it becomes 
unwieldy from a syntactic point of view, and if the conjectural code is in a 
string, then it ends up on the wrong side of the build.

-Ben Spratling

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


Re: [swift-evolution] Range that goes both ways

2016-09-21 Thread Charlie Monroe via swift-evolution
Hi,

AFAIK, these all would be very much sugar for:

1) (1 ..< 5).reversed()
2) The same as above: (1 ... 5).reversed() does exactly what you want.
3) Kind of makes sense to me to include >..,  though to be thorough, you'd need 
to add >.< as well - that's a weird looking operator...
4) There's a global function for this: stride(from: 1, to: 10, by: 2)

Charlie


> On Sep 21, 2016, at 9:49 AM, Mr Bee via swift-evolution 
>  wrote:
> 
> Hi,
> 
> I'm a Swift newbie so forgive me if my question sounds a bit silly, or 
> perhaps had been asked previously. My question is, why Swift doesn't have 
> built-in operator for backward or decremented range? Especially to be used in 
> for-in loop.
> 
> Swift only has ... (closed range) and ..< (half-opened range) that both go 
> forward (incremented). To use backward (decremented) range, we have to use 
> several techniques (stride, sequence, etc). Of course those techniques work 
> well. But I don't think they're very swifty, so to say.
> 
> So, is it possible to propose a new operator and a modification to existing 
> operator regarding range? Would such proposal be considered and implemented 
> after Swift 3? If it is, here's my pre-proposal about it.
> 
> 1. Add new ..> operator that goes backward (decremented) as companion to ..< 
> operator that goes forward (incremented).
> 
> Example:
>   for i in 1 ..< 5 { print(i) }
> will prints: 1 2 3 4
>   for i in 5 ..> 1 { print(i) }
> will prints: 5 4 3 2
> 
> 2. Modify the ... operator to be able to go both ways. If the left operand is 
> greater than the right, it goes backward (decremented). While if the left 
> operand is less than the right, it goes forward (incremented).
> 
> Example:
>   for i in 1 ... 5 { print(i) }
> will prints: 1 2 3 4 5
>   for i in 5 ... 1 { print(i) }
> will prints: 5 4 3 2 1
> 
> 3. Add new pair of operator to accompany the ..> and ..< (half opened range 
> on the right side) pair operator. It's >.. and <.. operators which are half 
> opened range on the left side. As you might guess, the >.. is the opposite of 
> ..> operator and the <.. is the opposite of the ..< operator.
> 
> Example:
>   for i in 1 <.. 5 { print(i) }
> will prints: 2 3 4 5
>   for i in 5 >.. 1 { print(i) }
> will prints: 4 3 2 1
> 
> 4. I would like to go even further by introducing a new attribute into for-in 
> loop syntax. It's `step` keyword which is used to define the interval of the 
> loop (like BASIC). Of course this additional attribute only works if the 
> range is countable or indexable. If not, the compiler should complain.
> 
> Example:
>   for i in 1 ... 10 step 2 { print(i) }
> will prints: 1 3 5 7 9
>   for i in 10 ... 0 step 2 { print(i) }
> will prints: 10 8 6 4 2 0
>   for i in 1 ..< 9 step 3 { print(i) }
> will prints: 1 3 6 
>   // note: 9 is omitted since it's on the opened side.
>   for i in 9 >.. 1 step 2 { print(i) }
> will prints: 7 5 3 1
>   // note: 9 is omitted since it's on the opened side.
> 
> I hope you get the idea. I think such a rich for-in loop syntax would make 
> Swift smarter, more robust, and easier to be learned and understood. They're 
> also required since the flexibiliy of c-style for-loop is no longer available 
> from Swift 3 and on. Decremented or backward range is sometimes needed in 
> some algorithms. Making it built into the language would be better, instead 
> of using non-language solutions. This proposal also doesn't break old codes 
> since it doesn't change the old behavior.
> 
> If such proposal is possible to be implemented —or at least considered— in 
> the next version of Swift, I'll do the work of the formal proposal on GitHub. 
> If it's not, well, I don't want to spend my time doing something that will be 
> ignored.
> 
> Thank you.
> 
> Regards, 
> 
> –Mr Bee
> 
> PS. I apologize if my English isn't well enough. I hope you all understand 
> what I meant. :)
> 
> ___
> 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] Range that goes both ways

2016-09-21 Thread Mr Bee via swift-evolution
Hi,
I'm a Swift newbie so forgive me if my question sounds a bit silly, or perhaps 
had been asked previously. My question is, why Swift doesn't have built-in 
operator for backward or decremented range? Especially to be used in for-in 
loop.
Swift only has ... (closed range) and ..< (half-opened range) that both go 
forward (incremented). To use backward (decremented) range, we have to use 
several techniques (stride, sequence, etc). Of course those techniques work 
well. But I don't think they're very swifty, so to say.
So, is it possible to propose a new operator and a modification to existing 
operator regarding range? Would such proposal be considered and implemented 
after Swift 3? If it is, here's my pre-proposal about it.
1. Add new ..> operator that goes backward (decremented) as companion to ..< 
operator that goes forward (incremented).
Example:  for i in 1 ..< 5 { print(i) }will prints: 1 2 3 4  for i in 5 ..> 1 { 
print(i) }will prints: 5 4 3 2
2. Modify the ... operator to be able to go both ways. If the left operand is 
greater than the right, it goes backward (decremented). While if the left 
operand is less than the right, it goes forward (incremented).
Example:  for i in 1 ... 5 { print(i) }will prints: 1 2 3 4 5  for i in 5 ... 1 
{ print(i) }will prints: 5 4 3 2 1
3. Add new pair of operator to accompany the ..> and ..< (half opened range on 
the right side) pair operator. It's >.. and <.. operators which are half opened 
range on the left side. As you might guess, the >.. is the opposite of ..> 
operator and the <.. is the opposite of the ..< operator.
Example:  for i in 1 <.. 5 { print(i) }will prints: 2 3 4 5  for i in 5 >.. 1 { 
print(i) }will prints: 4 3 2 1
4. I would like to go even further by introducing a new attribute into for-in 
loop syntax. It's `step` keyword which is used to define the interval of the 
loop (like BASIC). Of course this additional attribute only works if the range 
is countable or indexable. If not, the compiler should complain.
Example:  for i in 1 ... 10 step 2 { print(i) }will prints: 1 3 5 7 9  for i in 
10 ... 0 step 2 { print(i) }will prints: 10 8 6 4 2 0  for i in 1 ..< 9 step 3 
{ print(i) }will prints: 1 3 6   // note: 9 is omitted since it's on the opened 
side.  for i in 9 >.. 1 step 2 { print(i) }will prints: 7 5 3 1  // note: 9 is 
omitted since it's on the opened side.
I hope you get the idea. I think such a rich for-in loop syntax would make 
Swift smarter, more robust, and easier to be learned and understood. They're 
also required since the flexibiliy of c-style for-loop is no longer available 
from Swift 3 and on. Decremented or backward range is sometimes needed in some 
algorithms. Making it built into the language would be better, instead of using 
non-language solutions. This proposal also doesn't break old codes since it 
doesn't change the old behavior.
If such proposal is possible to be implemented —or at least considered— in the 
next version of Swift, I'll do the work of the formal proposal on GitHub. If 
it's not, well, I don't want to spend my time doing something that will be 
ignored.
Thank you.
Regards, 
–Mr Bee
PS. I apologize if my English isn't well enough. I hope you all understand what 
I meant. :)
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-users] [swift-user]Unexpected behavior of protocol extension.

2016-09-21 Thread Goffredo Marocchi via swift-evolution

Sent from my iPhone

> On 21 Sep 2016, at 01:41, Zhao Xin  wrote:
> 
> > I am not sure why protocol extension need to differ so much and present 
> > dispatch rules that are potentially very confusing. 
> 
> I think that both the Java and Swift designers want to get the benefits of 
> multiple inherences, in the meaning time, they don't want to support multiple 
> objects inherence. 
> 
> For Java only, as Java allows implicit override, the `@override` is optional. 
> Related bugs are hard to find if you don't use  `@override`.
> 
> For me, the current rule is simple. 
> 1. If there is a `override`, it is "class dynamic binding". If there is no 
> `override`, it is not. The dynamic type of `self` is irrelevant.
> 2. The method in 'protocol extension` is default, which means fail safe. It 
> is not a method of a class until the class implements it.
> 

Classic dynamic binding has its charms yes ;).

To be on point, once you adopt the protocol, and thus the extensions that may 
also have been declared and the default methods, and you decide to override or 
happen to override the default implementation it is still not enough to make 
sure you will call your implementation in your own code. If the reference to 
the instance of the class is cast to the protocol type, I want other object to 
be aware of my API contract not the specific class instance, then the protocol 
default method gets called and that is several shades of not appropriate for me.

https://nomothetis.svbtle.com/the-ghost-of-swift-bugs-future (with subclassing 
this can get more complicated)

Reasoning:
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/001922.html

... hence why turning protocol dispatching into dynamic dispatching, unless the 
user says otherwise (@Kevin: sometimes it makes the language easier to use 
without sacrificing speed if we renounce a tad of purity and accept a dedicated 
keyword as compiler hint... a simple @static or something would suffice).
Updating a version of a binary framework could be covered in extra perils you 
do not need.

> Zhaoxin
> 
>> On Wed, Sep 21, 2016 at 4:10 AM, Goffredo Marocchi  wrote:
>> This would make for hilarious debugging session if you have the misfortune 
>> of using a third party binary framework that gets updated and provide 
>> default implementations for some methods in the protocol extensions.
>> 
>> When Java 8 also decided to blur the lines between classes (implementations) 
>> and interfaces (equivalent of protocols on this side of the fence more or 
>> less... anyways they represent behaviours/API contracts), they also provided 
>> a very simple rule to determine on the code would behave at runtime.
>>> Extending Interfaces That Contain Default Methods
>>> 
>>> When you extend an interface that contains a default method, you can do the 
>>> following:
>>> 
>>> Not mention the default method at all, which lets your extended interface 
>>> inherit the default method.
>>> Redeclare the default method, which makes it abstract.
>>> Redefine the default method, which overrides it.
>> 
>> https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
>> 
>> I am not sure why protocol extension need to differ so much and present 
>> dispatch rules that are potentially very confusing. 
>> 
>> Casting at runtime should *never* change what implementation of a method 
>> gets called. 
>> For a safe by default language the fact that this can occur is quite 
>> puzzling and worrying. I am not sure the cost of implementing the current 
>> static/dynamic dispatch rules for default methods in protocol extensions is 
>> worth it to say it bluntly, but please enlighten me if I am missing an 
>> obvious huge pink elephant in the room here.
>> 
>> Sent from my iPhone
>> 
>>> On 20 Sep 2016, at 16:18, Nevin Brackett-Rozinsky via swift-evolution 
>>>  wrote:
>>> 
>>> I think there is a deeper issue that may be worth exploring here.
>>> 
>>> Notably, when one class presents a member function, its subclasses ought to 
>>> use “override” when they reimplement that method themselves, regardless of 
>>> where the superclass’s version comes from.
>>> 
>>> In the original post, the class “A” expresses (by conforming to protocol 
>>> “Foo”) that it has a member function “bar()”, and “B” is a subclass of “A” 
>>> which wants its own definition of “bar()”.
>>> 
>>> It seems to me that “B” should not care whether “A” rolled its own 
>>> implementation of “bar()” or used the default implementation provided by 
>>> “Foo”.
>>> 
>>> From the perspective of “B”, its superclass “A” promises to have a member 
>>> function “bar()”, so “B” should need to use the `override` keyword just 
>>> like it would when overriding any other method.
>>> 
>>> To illustrate this more clearly, suppose that “Foo” and “A: Foo” are 
>>> defined in a 3rd-party library, while “B: A” is written in a client module.
>>> 
>>> If the library changes